libjpeg.lib 오류 해결

그동안 jpeg 관련 프로그램들을 만들면서 libjpeg.lib 계열 라이브러리를 사용했다.
그런데, 망가진 jpeg 파일을 읽으면 언제나 오류가 발생하며 프로그램이 종료되었다[각주:1].

예외처리를 해도 오류를 뿜어내는 원인을에 대해, 1년 넘게 해결책을 찾다가 실패했는데, 최근 우연히 원인을 발견했다.

예외처리 코드에 오류가 있다고 생각했는데, 전혀 아닌, 엉뚱한 곳에 원인이 있었던 것이다.
바로, 오류 발생시 오류 문구를 출력하는 fprintf()에서 오류를 발생시키는 것이었다.

libjpeg 계열은 오류가 발생하면 상황을 output_message() 함수를 통해 출력하는데, 그 쪽에 미묘한 문제가 있었다.

jerror.c의 해당부분 코드는 아래와 같다.

METHODDEF(void)
output_message (j_common_ptr cinfo)
{
  char buffer[JMSG_LENGTH_MAX];

  /* Create the message */
  (*cinfo->err->format_message) (cinfo, buffer);

#ifdef USE_WINDOWS_MESSAGEBOX
  /* Display it in a message dialog box */
  MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
         MB_OK | MB_ICONERROR);
#else
  /* Send it to stderr, adding a newline */
  fprintf(stderr, "%s\n", buffer);
#endif
}

오류발생시 USE_WINDOWS_MESSAGEBOX가 정의되어 있으면 메시지 박스, 아니면 표준출력으로 오류를 출력하는 코드다.
그런데, 문제는 윈도우 모드에서 stderr가 제대로 정의되지 않을 수 있다는 것이다[각주:2].
그동안 종종 발생하던 원인이 바로 이 부분이었다. 해당 어플이 오류를 발생시킨다.

즉, 메시지를 보고 싶지 않으면 위의 코드에서 하일라이팅 해놓은 부분을 주석처리하면 안전하다.

  1. 본 블로그에서 그동안 공개했던 모든 프로그램은 깨진 jpeg 파일을 만나면 어김없이 기절해버렸다. OTL [본문으로]
  2. 이렇게 적었지만, 여전히 이해가 안 가기는 한다. 창모드에서 표준출력은 그냥 씹어먹는 거 아니었남? 우걱우걱 [본문으로]