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 에서도 동일하게 적용됨



+ Recent posts