libjpeg는 말그대로 jpeg을 위한 라이브러리이다.

이 녀석으로 할 수 있는 것은,
일정 사이즈로 resize(리사이즈) 혹은 scale/scaling(스케일링) 하는 것과
jpg를 bmp로 변환하는 것이다. djpeg를 보면 다른 bmp 포맷으로도 변환이 가능하지만,
윈도우 기반의 Bitmap으로만 할줄을 알아서..(헤더만 차이가 있을려나..)

아무튼 자세한 내용은 libjpeg에 들어있는 libjpeg.doc 을 참조 하면 되지만
한가지 애매한 부분이 있어 추가를 한다.

jpeg_read_header(&cinfo, TRUE);

이부분은 말그대로 jpeg 파일의 크기등의 각종 정보를 불러온다.
그리고 그 정보를 바탕으로 scaling을 준비한다. 그리고 나서

jpeg_start_decompress(&cinfo);

위의 함수를 호출하여(정확하게는 매크로) jpeg 을 bitmap으로 변환한다.
아래는 변환 부분의 소스코드이며,

cinfo.scale_num = 1;
cinfo.scale_denom = 8;

부분의 값으로 인해서 1/8 크기로 축소되어 변형된다.
(이로인해 preview 시에 상당히 빠르게 볼 수 있다. 그리고 jpeg6b 버전의 최대값이 1/8 이다)
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	FILE * infile;
	unsigned char *data_ori = NULL;
	unsigned char *data = NULL;
	int		calc_width;

	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_decompress(&cinfo);
		jpeg_stdio_src(&cinfo, infile);
		jpeg_read_header(&cinfo, TRUE);
			cinfo.scale_num = 1;
			cinfo.scale_denom = 8;
		jpeg_start_decompress(&cinfo);
			calc_width = (cinfo.output_width * cinfo.jpeg_color_space + 3) / 4 * 4;
			data = data_ori = malloc(calc_width * cinfo.output_height);
			if(data == NULL)
			{
				jpeg_finish_decompress(&cinfo);
				jpeg_destroy_compress(&cinfo);

				fclose(infile);
				return FALSE;
			}

		while (cinfo.output_scanline < cinfo.output_height)
		{
			jpeg_read_scanlines(&cinfo, &data, 1);
			data += calc_width;
		}

		jpeg_finish_decompress(&cinfo);
	jpeg_destroy_compress(&cinfo);

fclose(infile); free(data_ori);

calc_width = (cinfo.output_width * cinfo.jpeg_color_space + 3) / 4 * 4;

이 부분은 bitmap특성상 4byte align이 되어야 하므로, 4바이트 단위로 끊어주는 계산을 해준다.
아래의 data += calc_width; 에서 사용된다.
Posted by 구차니

댓글을 달아 주세요

  1. 비밀댓글입니다

    2009.09.02 04:21 [ ADDR : EDIT/ DEL : REPLY ]
    • 쓰는것에 대한 예제는 cjpeg 입니다(compress - jpeg)
      jpeg를 읽어서 변환하는건 transjpeg 였나 그렇구요 bmp나 다른 포맷으로 빼내는건 djpeg(decompress - jpeg) 랍니다.

      음.. 저도 jpeg로 저장을 해보려다가 GG 쳐서 말이죠 ㅋ

      2009.09.02 09:29 신고 [ ADDR : EDIT/ DEL ]
  2. 비밀댓글입니다

    2009.09.02 06:13 [ ADDR : EDIT/ DEL : REPLY ]
    • 아마 CxImage가 C++ Class 기반이 되면서 조금 더 느려진게 아닐까라고 추측을 해봅니다. 음.. 저도 6b로 했었는데 금세 7이 나왔나보네요? ^^;

      2009.09.02 09:30 신고 [ ADDR : EDIT/ DEL ]
    • 아.. 반대로 이해했군요 -ㅁ-
      음.. CxImage가 더 빠르다면 자체적으로 코드옵티마이즈 했거나.. 컴파일러가 더 좋은걸려나요? ㅋ

      2009.09.02 09:44 신고 [ ADDR : EDIT/ DEL ]
    • 음.. 그리고 코드가 많이 다르지 않다면,
      아마 결과물과 입력물의 압축율 기본값 차이라던가,
      scaling의 차이일수도 있고, 여러가지 차이가 있어서 딱히 단정짓기는 힘들어서 말이죠 ^^;

      그리고 6b에서는 output scale factor가 1/2 1/4 1/8 로 제한이 되어 있었던거 같고, 1/8이 가장 빠른 decompressing을 나타낸다고 되어 있었어요

      2009.09.02 12:03 신고 [ ADDR : EDIT/ DEL ]
    • 물론, 옵션의 차이일 수도 있습니다.
      하지만, 아무리 그래도 아무런 손도 대지 않고, 기본 옵션 설정 및 똑같은 압축률만 지정했는데 더 밀린다는 건 좀 우습네요.

      고맙습니다. 덕분에 재미있는 공부 했습니다.

      이거 하나 포스팅할까 했다가, 어디부터 써야 할 지 막막해서 포기. OTL

      2009.09.02 13:14 신고 [ ADDR : EDIT/ DEL ]
    • 음.. 아무튼 Visual sutio project 만드는 건 조금 더 공부를 해봐야겠어요 ㅠ.ㅠ

      2009.09.02 13:21 신고 [ ADDR : EDIT/ DEL ]
  3. 죽 확인해보니 transjpeg는 재압축을 하는 것이 아니라 그냥 압축된 스트림을 통째로 다시 쓰는 놈이더군요. OTL.
    이제 사용법을 거의 알았습니다.

    VC6, VS2009 외의 다른 VS에선 잘 안되는 것 같습니다. 결국 VC6으로만 작업... ㅠ.ㅠ

    2009.09.02 20:15 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 전 cjpeg djpeg transjpeg 거의 다 포기하고
      자체적으로 만들었답니다 ㅠ.ㅠ dog노가다 ㅠ.ㅠ

      그냥 example.c 가 만세입니다 ㅋㅋ

      2009.09.03 09:27 신고 [ ADDR : EDIT/ DEL ]
    • example.c 만세 올인!

      2009.09.03 21:48 신고 [ ADDR : EDIT/ DEL ]
  4. Saver

    좋은글 잘 보았습니다. 혹시나 질문이 있는데 raw -> jpeg 시에 scale_num, scale_denom이 아무리해도

    안먹히는 것 같은데 혹시 아시는것 있으신가요? 설명서엔 8/N (N=1-16)이라고 되어있는데 어떤 값을 넣어도 반응이 없네요.

    2010.11.14 01:15 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • jpeg->bmp로만 해봐서 raw->jpeg는 아직 못해봤답니다.
      언제 한번 시간내서 해보고 다시 글을 쓰도록 하겠습니다 ^^

      2010.11.14 10:35 신고 [ ADDR : EDIT/ DEL ]
  5. Saver

    아. compress시에 setDefault 다음에 커스텀 파라미터를 줘야 하는 거였네요; [설명서를 다시 한번 잘 읽어보니..]

    그런데 버그가 있는것 같습니다. scale시에 확장은 잘 되는데 축소시에는 무슨 수치를 넣든 가로 세로 1/2씩 밖에 줄지 않네요 -.-; cjpeg 예제를 실행해도 마찬가지인걸 보면 아예 버그인듯..?

    2010.11.14 14:41 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 그래도 libjpeg은 설명서가 잘 되서 좋은거 같아요 ^^;
      jpeg decoding만 해봐서.. OTL 인코딩은 아직 못했봤다니까요 ㅠ.ㅠ

      2010.11.14 15:14 신고 [ ADDR : EDIT/ DEL ]
  6. 하얀언덕

    안녕하세요 구차니님~~~
    항상 자료 검색하다보면 어느샌가 여기로 이어지내요 ㅋㅋㅋ
    여러가지 찾아 보다가...
    질문 좀 드리려구용 ^^
    libjpeg 쓰면서...
    scale 할때
    cinfo.scale_num = 1;
    cinfo.scale_denom = 8;

    이용하는 것 말고...

    임의의 크기 width, height 2개 입력 받아서 크기를 정하는건 없나요..ㅠ ㅠ
    원래 크기가 600x500 이라하면
    width = 200
    height = 200
    요래요래 바꾸어서 출력할 수 있는지요...
    아... 검색스킬의 환계로 인하여..ㅠ ㅠ
    이렇게 질문을 드립니다용~

    2011.11.22 17:29 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • http://stackoverflow.com/questions/7488048/libjpeg-output-scaling

      검색을 해보니 자체적으로 scaling을 해야 한다고 하네요. bmp로 decoding후 줄여서 다시 encoding 해야할듯 싶어요

      2011.11.22 19:10 신고 [ ADDR : EDIT/ DEL ]