< prev index next >

modules/javafx.graphics/src/main/native-iio/libjpeg7/jcmarker.c

Print this page

        

@@ -1,9 +1,10 @@
 /*
  * jcmarker.c
  *
  * Copyright (C) 1991-1998, Thomas G. Lane.
+ * Modified 2003-2013 by Guido Vollbeding.
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
  * This file contains routines to write JPEG datastream markers.
  */

@@ -70,10 +71,11 @@
   M_APP13 = 0xed,
   M_APP14 = 0xee,
   M_APP15 = 0xef,
 
   M_JPG0  = 0xf0,
+  M_JPG8  = 0xf8,
   M_JPG13 = 0xfd,
   M_COM   = 0xfe,
 
   M_TEM   = 0x01,
 

@@ -151,25 +153,26 @@
 
   if (qtbl == NULL)
     ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);
 
   prec = 0;
-  for (i = 0; i < DCTSIZE2; i++) {
-    if (qtbl->quantval[i] > 255)
+  for (i = 0; i <= cinfo->lim_Se; i++) {
+    if (qtbl->quantval[cinfo->natural_order[i]] > 255)
       prec = 1;
   }
 
   if (! qtbl->sent_table) {
     emit_marker(cinfo, M_DQT);
 
-    emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
+    emit_2bytes(cinfo,
+      prec ? cinfo->lim_Se * 2 + 2 + 1 + 2 : cinfo->lim_Se + 1 + 1 + 2);
 
     emit_byte(cinfo, index + (prec<<4));
 
-    for (i = 0; i < DCTSIZE2; i++) {
+    for (i = 0; i <= cinfo->lim_Se; i++) {
       /* The table entries must be emitted in zigzag order. */
-      unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
+      unsigned int qval = qtbl->quantval[cinfo->natural_order[i]];
       if (prec)
         emit_byte(cinfo, (int) (qval >> 8));
       emit_byte(cinfo, (int) (qval & 0xFF));
     }
 

@@ -233,18 +236,23 @@
   for (i = 0; i < NUM_ARITH_TBLS; i++)
     dc_in_use[i] = ac_in_use[i] = 0;
 
   for (i = 0; i < cinfo->comps_in_scan; i++) {
     compptr = cinfo->cur_comp_info[i];
+    /* DC needs no table for refinement scan */
+    if (cinfo->Ss == 0 && cinfo->Ah == 0)
     dc_in_use[compptr->dc_tbl_no] = 1;
+    /* AC needs no table when not present */
+    if (cinfo->Se)
     ac_in_use[compptr->ac_tbl_no] = 1;
   }
 
   length = 0;
   for (i = 0; i < NUM_ARITH_TBLS; i++)
     length += dc_in_use[i] + ac_in_use[i];
 
+  if (length) {
   emit_marker(cinfo, M_DAC);
 
   emit_2bytes(cinfo, length*2 + 2);
 
   for (i = 0; i < NUM_ARITH_TBLS; i++) {

@@ -255,10 +263,11 @@
     if (ac_in_use[i]) {
       emit_byte(cinfo, i + 0x10);
       emit_byte(cinfo, cinfo->arith_ac_K[i]);
     }
   }
+  }
 #endif /* C_ARITH_CODING_SUPPORTED */
 }
 
 
 LOCAL(void)

@@ -272,10 +281,41 @@
   emit_2bytes(cinfo, (int) cinfo->restart_interval);
 }
 
 
 LOCAL(void)
+emit_lse_ict (j_compress_ptr cinfo)
+/* Emit an LSE inverse color transform specification marker */
+{
+  /* Support only 1 transform */
+  if (cinfo->color_transform != JCT_SUBTRACT_GREEN ||
+      cinfo->num_components < 3)
+    ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+
+  emit_marker(cinfo, M_JPG8);
+  
+  emit_2bytes(cinfo, 24);       /* fixed length */
+
+  emit_byte(cinfo, 0x0D);       /* ID inverse transform specification */
+  emit_2bytes(cinfo, MAXJSAMPLE);       /* MAXTRANS */
+  emit_byte(cinfo, 3);          /* Nt=3 */
+  emit_byte(cinfo, cinfo->comp_info[1].component_id);
+  emit_byte(cinfo, cinfo->comp_info[0].component_id);
+  emit_byte(cinfo, cinfo->comp_info[2].component_id);
+  emit_byte(cinfo, 0x80);       /* F1: CENTER1=1, NORM1=0 */
+  emit_2bytes(cinfo, 0);        /* A(1,1)=0 */
+  emit_2bytes(cinfo, 0);        /* A(1,2)=0 */
+  emit_byte(cinfo, 0);          /* F2: CENTER2=0, NORM2=0 */
+  emit_2bytes(cinfo, 1);        /* A(2,1)=1 */
+  emit_2bytes(cinfo, 0);        /* A(2,2)=0 */
+  emit_byte(cinfo, 0);          /* F3: CENTER3=0, NORM3=0 */
+  emit_2bytes(cinfo, 1);        /* A(3,1)=1 */
+  emit_2bytes(cinfo, 0);        /* A(3,2)=0 */
+}
+
+
+LOCAL(void)
 emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
 /* Emit a SOF marker */
 {
   int ci;
   jpeg_component_info *compptr;

@@ -318,36 +358,46 @@
   emit_byte(cinfo, cinfo->comps_in_scan);
 
   for (i = 0; i < cinfo->comps_in_scan; i++) {
     compptr = cinfo->cur_comp_info[i];
     emit_byte(cinfo, compptr->component_id);
-    td = compptr->dc_tbl_no;
-    ta = compptr->ac_tbl_no;
-    if (cinfo->progressive_mode) {
-      /* Progressive mode: only DC or only AC tables are used in one scan;
-       * furthermore, Huffman coding of DC refinement uses no table at all.
-       * We emit 0 for unused field(s); this is recommended by the P&M text
+
+    /* We emit 0 for unused field(s); this is recommended by the P&M text
        * but does not seem to be specified in the standard.
        */
-      if (cinfo->Ss == 0) {
-        ta = 0;                 /* DC scan */
-        if (cinfo->Ah != 0 && !cinfo->arith_code)
-          td = 0;               /* no DC table either */
-      } else {
-        td = 0;                 /* AC scan */
-      }
-    }
+
+    /* DC needs no table for refinement scan */
+    td = cinfo->Ss == 0 && cinfo->Ah == 0 ? compptr->dc_tbl_no : 0;
+    /* AC needs no table when not present */
+    ta = cinfo->Se ? compptr->ac_tbl_no : 0;
+
     emit_byte(cinfo, (td << 4) + ta);
   }
 
   emit_byte(cinfo, cinfo->Ss);
   emit_byte(cinfo, cinfo->Se);
   emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al);
 }
 
 
 LOCAL(void)
+emit_pseudo_sos (j_compress_ptr cinfo)
+/* Emit a pseudo SOS marker */
+{
+  emit_marker(cinfo, M_SOS);
+  
+  emit_2bytes(cinfo, 2 + 1 + 3); /* length */
+  
+  emit_byte(cinfo, 0); /* Ns */
+
+  emit_byte(cinfo, 0); /* Ss */
+  emit_byte(cinfo, cinfo->block_size * cinfo->block_size - 1); /* Se */
+  emit_byte(cinfo, 0); /* Ah/Al */
+}
+
+
+LOCAL(void)
 emit_jfif_app0 (j_compress_ptr cinfo)
 /* Emit a JFIF-compliant APP0 marker */
 {
   /*
    * Length of APP0 block       (2 bytes)

@@ -456,12 +506,12 @@
 
 /*
  * Write datastream header.
  * This consists of an SOI and optional APPn markers.
  * We recommend use of the JFIF marker, but not the Adobe marker,
- * when using YCbCr or grayscale data.  The JFIF marker should NOT
- * be used for any other JPEG colorspace.  The Adobe marker is helpful
+ * when using YCbCr or grayscale data.  The JFIF marker is also used
+ * for other standard JPEG colorspaces.  The Adobe marker is helpful
  * to distinguish RGB, CMYK, and YCCK colorspaces.
  * Note that an application can write additional header markers after
  * jpeg_start_compress returns.
  */
 

@@ -482,11 +532,12 @@
 }
 
 
 /*
  * Write frame header.
- * This consists of DQT and SOFn markers.
+ * This consists of DQT and SOFn markers,
+ * a conditional LSE marker and a conditional pseudo SOS marker.
  * Note that we do not emit the SOF until we have emitted the DQT(s).
  * This avoids compatibility problems with incorrect implementations that
  * try to error-check the quant table numbers as soon as they see the SOF.
  */
 

@@ -509,11 +560,11 @@
 
   /* Check for a non-baseline specification.
    * Note we assume that Huffman table numbers won't be changed later.
    */
   if (cinfo->arith_code || cinfo->progressive_mode ||
-      cinfo->data_precision != 8) {
+      cinfo->data_precision != 8 || cinfo->block_size != DCTSIZE) {
     is_baseline = FALSE;
   } else {
     is_baseline = TRUE;
     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
          ci++, compptr++) {

@@ -539,10 +590,18 @@
     else if (is_baseline)
       emit_sof(cinfo, M_SOF0);  /* SOF code for baseline implementation */
     else
       emit_sof(cinfo, M_SOF1);  /* SOF code for non-baseline Huffman file */
   }
+
+  /* Check to emit LSE inverse color transform specification marker */
+  if (cinfo->color_transform)
+    emit_lse_ict(cinfo);
+
+  /* Check to emit pseudo SOS marker */
+  if (cinfo->progressive_mode && cinfo->block_size != DCTSIZE)
+    emit_pseudo_sos(cinfo);
 }
 
 
 /*
  * Write scan header.

@@ -567,24 +626,17 @@
     /* Emit Huffman tables.
      * Note that emit_dht() suppresses any duplicate tables.
      */
     for (i = 0; i < cinfo->comps_in_scan; i++) {
       compptr = cinfo->cur_comp_info[i];
-      if (cinfo->progressive_mode) {
-        /* Progressive mode: only DC or only AC tables are used in one scan */
-        if (cinfo->Ss == 0) {
-          if (cinfo->Ah == 0)   /* DC needs no table for refinement scan */
+      /* DC needs no table for refinement scan */
+      if (cinfo->Ss == 0 && cinfo->Ah == 0)
             emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
-        } else {
+      /* AC needs no table when not present */
+      if (cinfo->Se)
           emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
         }
-      } else {
-        /* Sequential mode: need both DC and AC tables */
-        emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
-        emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
-      }
-    }
   }
 
   /* Emit DRI if required --- note that DRI value could change for each scan.
    * We avoid wasting space with unnecessary DRIs, however.
    */

@@ -651,11 +703,11 @@
 
   /* Create the subobject */
   marker = (my_marker_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
                                 SIZEOF(my_marker_writer));
-  cinfo->marker = (struct jpeg_marker_writer *) marker;
+  cinfo->marker = &marker->pub;
   /* Initialize method pointers */
   marker->pub.write_file_header = write_file_header;
   marker->pub.write_frame_header = write_frame_header;
   marker->pub.write_scan_header = write_scan_header;
   marker->pub.write_file_trailer = write_file_trailer;
< prev index next >