libjpeg에서 이미지를 읽어들이는 부분의 코드(example.c)는 아래와 같다.
/* Here we use the library's state variable cinfo.output_scanline as the
* loop counter, so that we don't have to keep track ourselves.
*/
while (cinfo.output_scanline < cinfo.output_height) {
/* jpeg_read_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could ask for
* more than one scanline at a time if that's more convenient.
*/
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
/* Assume put_scanline_someplace wants a pointer and sample count. */
put_scanline_someplace(buffer[0], row_stride);
}
주석 부분을 제거하면 아래와 같은데…
while (cinfo.output_scanline < cinfo.output_height) {
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
put_scanline_someplace(buffer[0], row_stride);
}
행 단위로 읽고 저장하는 것 외엔 아무 내용이 없다.
문제가 하나 있는데, 읽다가 오류가 발생하는 경우 제대로 읽은 부분까지만 처리하는 게 쉽지 않다는 점이다.
가벼운 오류는 그냥 지나가는 게 기본 동작방식인데, 사실은 파일이 잘린 경우에도 그냥 지나가버린다.
찾아보니 jpeg_read_scanlines()에서 오류가 발생하면 cinfo.err에 상황이 기록된다.
이 점을 이용해서 아래와 같이 수정하면 오류를 인지하고 후속처리를 할 수 있다.
while (cinfo.output_scanline < cinfo.output_height) {
if ((jpeg_read_scanlines(&cinfo, buffer, 1) != 1) || (cinfo.err->num_warnings)) {
// 오류 발생시 여기서 처리
break;
}
put_scanline_someplace(buffer[0], row_stride);
}
덧. 당연한 얘기지만, libjpeg-turbo, mozjpeg 에서도 동일하게 적용됨