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; 에서 사용된다.