[gs-code-review] Propsed patch to libjpeg to workaround comp id [686980]

Raph Levien raph.levien at artifex.com
Fri Jun 18 09:17:16 PDT 2004


Test file 64_agony_lay.pdf for bug 686980 contains DCT streams with
invalid component id's. For example, obj 108 0 has an SOF marker with
id's [1 2 3 1], and an SOS marker to match. The JPEG spec states quite
clearly that the component identifiers be distinct (see descruption
of C_i in B.2.2).

The following code checks that the component id is unique, and chooses
a reasonable fake if so. The patch should have no effect whatsoever
for valid DCT streams.

This is a patch to libjpeg 6b. We might need to investigate how to get
this patch distributed to the appropriate parties, as there hasn't
been a new release of libjpeg in years.

Raph

*** /tmp/jpeg-6b/jdmarker.c	1998-02-21 12:24:50.000000000 -0800
--- jpeg/jdmarker.c	2004-06-18 09:05:55.000000000 -0700
***************
*** 279,284 ****
    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
         ci++, compptr++) {
      compptr->component_index = ci;
!     INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
      INPUT_BYTE(cinfo, c, return FALSE);
      compptr->h_samp_factor = (c >> 4) & 15;
--- 279,303 ----
    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
         ci++, compptr++) {
+     int component_id;
+     int j;
      compptr->component_index = ci;
!     INPUT_BYTE(cinfo, component_id, return FALSE);
!     for (j = 0; j < ci; j++) {
!       /* Check to see whether component id has already been seen
! 	 (in violation of the spec, but unfortunately seen in some
! 	 files). If so, create "fake" component id equal to the
! 	 max id seen so far + 1. */
!       if (cinfo->comp_info[j].component_id == component_id) {
! 	int max_id = cinfo->comp_info[0].component_id;
! 	int k;
! 	for (k = 1; k < ci; k++) {
! 	  int k_id = cinfo->comp_info[k].component_id;
! 	  if (k_id > max_id) max_id = k_id;
! 	}
! 	component_id = max_id + 1;
! 	break;
!       }
!     }
!     compptr->component_id = component_id;
      INPUT_BYTE(cinfo, c, return FALSE);
      compptr->h_samp_factor = (c >> 4) & 15;
***************
*** 324,330 ****
  
    for (i = 0; i < n; i++) {
      INPUT_BYTE(cinfo, cc, return FALSE);
      INPUT_BYTE(cinfo, c, return FALSE);
!     
      for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
  	 ci++, compptr++) {
--- 343,365 ----
  
    for (i = 0; i < n; i++) {
+     int j;
      INPUT_BYTE(cinfo, cc, return FALSE);
      INPUT_BYTE(cinfo, c, return FALSE);
! 
!     /* Detect the case where component id's are not unique, and, if so,
!        create a fake component id using the same logic as in get_sof. */
!     for (j = 0; j < i; j++) {
!       if (cc == cinfo->cur_comp_info[j]->component_id) {
! 	int k;
! 	int max_id = cinfo->cur_comp_info[0]->component_id;
! 	for (k = 1; k < i; k++) {
! 	  int k_id = cinfo->cur_comp_info[k]->component_id;
! 	  if (k_id > max_id) max_id = k_id;
! 	}
! 	cc = max_id + 1;
! 	break;
!       }
!     }
! 
      for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
  	 ci++, compptr++) {



More information about the gs-code-review mailing list