--- leptonlib-1.51.orig/src/jpegio.c 2007-10-25 06:41:16.000000000 +0400 +++ leptonlib-1.51/src/jpegio.c 2007-11-18 16:47:44.000000000 +0300 @@ -56,6 +56,7 @@ static void jpeg_error_do_not_exit(j_common_ptr cinfo); static jmp_buf jpeg_jmpbuf; +static int jpeg_comment_callback(j_decompress_ptr cinfo); /*---------------------------------------------------------------------* @@ -148,6 +149,7 @@ PIXCMAP *cmap; struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; +unsigned char *comment = NULL; PROCNAME("pixReadStreamJpeg"); @@ -177,6 +179,9 @@ jerr.error_exit = jpeg_error_do_not_exit; /* catch error; do not exit! */ jpeg_create_decompress(&cinfo); + + cinfo.client_data = &comment; + jpeg_set_marker_processor(&cinfo, JPEG_COM, jpeg_comment_callback); jpeg_stdio_src(&cinfo, fp); jpeg_read_header(&cinfo, TRUE); cinfo.scale_denom = reduction; @@ -186,22 +191,36 @@ /* Allocate the image and a row buffer */ spp = cinfo.out_color_components; - if (spp != 1 && spp != 3) + if (spp != 1 && spp != 3) { + if (comment) free(comment); return (PIX *)ERROR_PTR("spp must be 1 or 3", procName, NULL); + } w = cinfo.output_width; h = cinfo.output_height; if ((spp == 3) && (cmflag == 0)) /* get full color pix */ { - if ((rowbuffer = (JSAMPROW)CALLOC(sizeof(JSAMPLE), spp * w)) == NULL) + if ((rowbuffer = (JSAMPROW)CALLOC(sizeof(JSAMPLE), spp * w)) == NULL) { + if (comment) free(comment); return (PIX *)ERROR_PTR("rowbuffer not made", procName, NULL); - if ((pix = pixCreate(w, h, 32)) == NULL) + } + if ((pix = pixCreate(w, h, 32)) == NULL) { + if (comment) free(comment); return (PIX *)ERROR_PTR("pix not made", procName, NULL); + } } else { /* 8 bpp gray or colormapped */ - if ((rowbuffer = (JSAMPROW)CALLOC(sizeof(JSAMPLE), w)) == NULL) + if ((rowbuffer = (JSAMPROW)CALLOC(sizeof(JSAMPLE), w)) == NULL) { + if (comment) free(comment); return (PIX *)ERROR_PTR("rowbuffer not made", procName, NULL); - if ((pix = pixCreate(w, h, 8)) == NULL) + } + if ((pix = pixCreate(w, h, 8)) == NULL) { + if (comment) free(comment); return (PIX *)ERROR_PTR("pix not made", procName, NULL); + } + } + + if (comment) { + pix->text = (char *)comment; } if (spp == 1) /* Grayscale or colormapped */ @@ -512,3 +531,46 @@ longjmp(jpeg_jmpbuf, 0); return; } + +/* this function was borrowed from libjpeg */ +static unsigned int jpeg_getc (j_decompress_ptr cinfo) +{ + struct jpeg_source_mgr * datasrc = cinfo->src; + + if (datasrc->bytes_in_buffer == 0) { + if (! (*datasrc->fill_input_buffer) (cinfo)) { + return 0; + } + } + datasrc->bytes_in_buffer--; + return GETJOCTET(*datasrc->next_input_byte++); +} + + +static int jpeg_comment_callback(j_decompress_ptr cinfo) +{ + unsigned int c; + l_int32 length, i; + unsigned char **comment = (unsigned char **)cinfo->client_data; + + length = jpeg_getc(cinfo) << 8; + length += jpeg_getc(cinfo); + length -= 2; + + if (length <= 0) { + return 1; + } + + *comment = malloc(length + 1); + if (!(*comment)) { + return 0; + } + + for (i = 0; i < length; i++) { + c = jpeg_getc(cinfo); + (*comment)[i] = c; + } + (*comment)[length] = 0; + + return 1; +}