image/decoders/iccjpeg.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * iccprofile.c
     7  *
     8  * This file provides code to read and write International Color Consortium
     9  * (ICC) device profiles embedded in JFIF JPEG image files.  The ICC has
    10  * defined a standard format for including such data in JPEG "APP2" markers.
    11  * The code given here does not know anything about the internal structure
    12  * of the ICC profile data; it just knows how to put the profile data into
    13  * a JPEG file being written, or get it back out when reading.
    14  *
    15  * This code depends on new features added to the IJG JPEG library as of
    16  * IJG release 6b; it will not compile or work with older IJG versions.
    17  *
    18  * NOTE: this code would need surgery to work on 16-bit-int machines
    19  * with ICC profiles exceeding 64K bytes in size.  If you need to do that,
    20  * change all the "unsigned int" variables to "INT32".  You'll also need
    21  * to find a malloc() replacement that can allocate more than 64K.
    22  */
    24 #include "iccjpeg.h"
    25 #include <stdlib.h>			/* define malloc() */
    28 /*
    29  * Since an ICC profile can be larger than the maximum size of a JPEG marker
    30  * (64K), we need provisions to split it into multiple markers.  The format
    31  * defined by the ICC specifies one or more APP2 markers containing the
    32  * following data:
    33  *	Identifying string	ASCII "ICC_PROFILE\0"  (12 bytes)
    34  *	Marker sequence number	1 for first APP2, 2 for next, etc (1 byte)
    35  *	Number of markers	Total number of APP2's used (1 byte)
    36  *      Profile data		(remainder of APP2 data)
    37  * Decoders should use the marker sequence numbers to reassemble the profile,
    38  * rather than assuming that the APP2 markers appear in the correct sequence.
    39  */
    41 #define ICC_MARKER  (JPEG_APP0 + 2)	/* JPEG marker code for ICC */
    42 #define ICC_OVERHEAD_LEN  14		/* size of non-profile data in APP2 */
    43 #define MAX_BYTES_IN_MARKER  65533	/* maximum data len of a JPEG marker */
    44 #define MAX_DATA_BYTES_IN_MARKER  (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN)
    46 /*
    47  * Prepare for reading an ICC profile
    48  */
    50 void
    51 setup_read_icc_profile (j_decompress_ptr cinfo)
    52 {
    53   /* Tell the library to keep any APP2 data it may find */
    54   jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF);
    55 }
    58 /*
    59  * Handy subroutine to test whether a saved marker is an ICC profile marker.
    60  */
    62 static boolean
    63 marker_is_icc (jpeg_saved_marker_ptr marker)
    64 {
    65   return
    66     marker->marker == ICC_MARKER &&
    67     marker->data_length >= ICC_OVERHEAD_LEN &&
    68     /* verify the identifying string */
    69     GETJOCTET(marker->data[0]) == 0x49 &&
    70     GETJOCTET(marker->data[1]) == 0x43 &&
    71     GETJOCTET(marker->data[2]) == 0x43 &&
    72     GETJOCTET(marker->data[3]) == 0x5F &&
    73     GETJOCTET(marker->data[4]) == 0x50 &&
    74     GETJOCTET(marker->data[5]) == 0x52 &&
    75     GETJOCTET(marker->data[6]) == 0x4F &&
    76     GETJOCTET(marker->data[7]) == 0x46 &&
    77     GETJOCTET(marker->data[8]) == 0x49 &&
    78     GETJOCTET(marker->data[9]) == 0x4C &&
    79     GETJOCTET(marker->data[10]) == 0x45 &&
    80     GETJOCTET(marker->data[11]) == 0x0;
    81 }
    84 /*
    85  * See if there was an ICC profile in the JPEG file being read;
    86  * if so, reassemble and return the profile data.
    87  *
    88  * TRUE is returned if an ICC profile was found, FALSE if not.
    89  * If TRUE is returned, *icc_data_ptr is set to point to the
    90  * returned data, and *icc_data_len is set to its length.
    91  *
    92  * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc()
    93  * and must be freed by the caller with free() when the caller no longer
    94  * needs it.  (Alternatively, we could write this routine to use the
    95  * IJG library's memory allocator, so that the data would be freed implicitly
    96  * at jpeg_finish_decompress() time.  But it seems likely that many apps
    97  * will prefer to have the data stick around after decompression finishes.)
    98  *
    99  * NOTE: if the file contains invalid ICC APP2 markers, we just silently
   100  * return FALSE.  You might want to issue an error message instead.
   101  */
   103 boolean
   104 read_icc_profile (j_decompress_ptr cinfo,
   105 		  JOCTET **icc_data_ptr,
   106 		  unsigned int *icc_data_len)
   107 {
   108   jpeg_saved_marker_ptr marker;
   109   int num_markers = 0;
   110   int seq_no;
   111   JOCTET *icc_data;
   112   unsigned int total_length;
   113 #define MAX_SEQ_NO  255		/* sufficient since marker numbers are bytes */
   114   char marker_present[MAX_SEQ_NO+1];	  /* 1 if marker found */
   115   unsigned int data_length[MAX_SEQ_NO+1]; /* size of profile data in marker */
   116   unsigned int data_offset[MAX_SEQ_NO+1]; /* offset for data in marker */
   118   *icc_data_ptr = NULL;		/* avoid confusion if FALSE return */
   119   *icc_data_len = 0;
   121   /* This first pass over the saved markers discovers whether there are
   122    * any ICC markers and verifies the consistency of the marker numbering.
   123    */
   125   for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++)
   126     marker_present[seq_no] = 0;
   128   for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
   129     if (marker_is_icc(marker)) {
   130       if (num_markers == 0)
   131 	num_markers = GETJOCTET(marker->data[13]);
   132       else if (num_markers != GETJOCTET(marker->data[13]))
   133 	return FALSE;		/* inconsistent num_markers fields */
   134       seq_no = GETJOCTET(marker->data[12]);
   135       if (seq_no <= 0 || seq_no > num_markers)
   136 	return FALSE;		/* bogus sequence number */
   137       if (marker_present[seq_no])
   138 	return FALSE;		/* duplicate sequence numbers */
   139       marker_present[seq_no] = 1;
   140       data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN;
   141     }
   142   }
   144   if (num_markers == 0)
   145     return FALSE;
   147   /* Check for missing markers, count total space needed,
   148    * compute offset of each marker's part of the data.
   149    */
   151   total_length = 0;
   152   for (seq_no = 1; seq_no <= num_markers; seq_no++) {
   153     if (marker_present[seq_no] == 0)
   154       return FALSE;		/* missing sequence number */
   155     data_offset[seq_no] = total_length;
   156     total_length += data_length[seq_no];
   157   }
   159   if (total_length <= 0)
   160     return FALSE;		/* found only empty markers? */
   162   /* Allocate space for assembled data */
   163   icc_data = (JOCTET *) malloc(total_length * sizeof(JOCTET));
   164   if (icc_data == NULL)
   165     return FALSE;		/* oops, out of memory */
   167   /* and fill it in */
   168   for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
   169     if (marker_is_icc(marker)) {
   170       JOCTET FAR *src_ptr;
   171       JOCTET *dst_ptr;
   172       unsigned int length;
   173       seq_no = GETJOCTET(marker->data[12]);
   174       dst_ptr = icc_data + data_offset[seq_no];
   175       src_ptr = marker->data + ICC_OVERHEAD_LEN;
   176       length = data_length[seq_no];
   177       while (length--) {
   178 	*dst_ptr++ = *src_ptr++;
   179       }
   180     }
   181   }
   183   *icc_data_ptr = icc_data;
   184   *icc_data_len = total_length;
   186   return TRUE;
   187 }

mercurial