Home | History | Annotate | Download | only in jpeg
      1 /*
      2  * Small jpeg decoder library (Internal header)
      3  *
      4  * Copyright (c) 2006, Luc Saillard <luc (at) saillard.org>
      5  * All rights reserved.
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions are met:
      8  *
      9  * - Redistributions of source code must retain the above copyright notice,
     10  *  this list of conditions and the following disclaimer.
     11  *
     12  * - Redistributions in binary form must reproduce the above copyright notice,
     13  *  this list of conditions and the following disclaimer in the documentation
     14  *  and/or other materials provided with the distribution.
     15  *
     16  * - Neither the name of the author nor the names of its contributors may be
     17  *  used to endorse or promote products derived from this software without
     18  *  specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  * POSSIBILITY OF SUCH DAMAGE.
     31  *
     32  */
     33 
     34 
     35 #ifndef __TINYJPEG_INTERNAL_H_
     36 #define __TINYJPEG_INTERNAL_H_
     37 
     38 #include <setjmp.h>
     39 
     40 #define SANITY_CHECK 1
     41 
     42 struct jdec_private;
     43 
     44 #define HUFFMAN_BITS_SIZE  256
     45 #define HUFFMAN_HASH_NBITS 9
     46 #define HUFFMAN_HASH_SIZE  (1UL<<HUFFMAN_HASH_NBITS)
     47 #define HUFFMAN_HASH_MASK  (HUFFMAN_HASH_SIZE-1)
     48 
     49 #define HUFFMAN_TABLES	   4
     50 #define COMPONENTS	   3
     51 #define JPEG_MAX_WIDTH	   4096
     52 #define JPEG_MAX_HEIGHT	   4096
     53 
     54 struct huffman_table
     55 {
     56   /* Fast look up table, using HUFFMAN_HASH_NBITS bits we can have directly the symbol,
     57    * if the symbol is <0, then we need to look into the tree table */
     58   short int lookup[HUFFMAN_HASH_SIZE];
     59   /* code size: give the number of bits of a symbol is encoded */
     60   unsigned char code_size[HUFFMAN_HASH_SIZE];
     61   /* some place to store value that is not encoded in the lookup table
     62    * FIXME: Calculate if 256 value is enough to store all values
     63    */
     64   uint16_t slowtable[16-HUFFMAN_HASH_NBITS][256];
     65 };
     66 
     67 struct component
     68 {
     69   unsigned int Hfactor;
     70   unsigned int Vfactor;
     71   float *Q_table;		/* Pointer to the quantisation table to use */
     72   struct huffman_table *AC_table;
     73   struct huffman_table *DC_table;
     74   short int previous_DC;	/* Previous DC coefficient */
     75   short int DCT[64];		/* DCT coef */
     76 #if SANITY_CHECK
     77   unsigned int cid;
     78 #endif
     79 };
     80 
     81 
     82 typedef void (*decode_MCU_fct) (struct jdec_private *priv);
     83 typedef void (*convert_colorspace_fct) (struct jdec_private *priv, int, int);
     84 
     85 struct jdec_private
     86 {
     87   /* Public variables */
     88   uint8_t *components[COMPONENTS];
     89   unsigned int bytes_per_row[COMPONENTS];
     90   unsigned int width, height;	/* Size of the image */
     91   unsigned int flags;
     92 
     93   /* Private variables */
     94   const unsigned char *stream_begin, *stream_end;
     95   unsigned int stream_length;
     96 
     97   const unsigned char *stream;	/* Pointer to the current stream */
     98   unsigned int reservoir, nbits_in_reservoir;
     99 
    100   struct component component_infos[COMPONENTS];
    101   float Q_tables[COMPONENTS][64];		/* quantization tables */
    102   struct huffman_table HTDC[HUFFMAN_TABLES];	/* DC huffman tables   */
    103   struct huffman_table HTAC[HUFFMAN_TABLES];	/* AC huffman tables   */
    104   int default_huffman_table_initialized;
    105   int restart_interval;
    106   int restarts_to_go;				/* MCUs left in this restart interval */
    107   int last_rst_marker_seen;			/* Rst marker is incremented each time */
    108 
    109   /* Temp space used after the IDCT to store each components */
    110   uint8_t Y[64*4], Cr[64], Cb[64];
    111 
    112   jmp_buf jump_state;
    113   /* Internal Pointer use for colorspace conversion, do not modify it !!! */
    114   uint8_t *plane[COMPONENTS];
    115 
    116 };
    117 
    118 #define IDCT tinyjpeg_idct_float
    119 void tinyjpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride);
    120 
    121 struct tinyjpeg_colorspace {
    122   convert_colorspace_fct convert_colorspace[4];
    123   const decode_MCU_fct *decode_mcu_table;
    124   int (*initialize)(struct jdec_private *, unsigned int *, unsigned int *);
    125 };
    126 
    127 void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component);
    128 
    129 extern const decode_MCU_fct tinyjpeg_decode_mcu_3comp_table[4];
    130 extern const decode_MCU_fct tinyjpeg_decode_mcu_1comp_table[4];
    131 
    132 enum std_markers {
    133    DQT  = 0xDB, /* Define Quantization Table */
    134    SOF  = 0xC0, /* Start of Frame (size information) */
    135    DHT  = 0xC4, /* Huffman Table */
    136    SOI  = 0xD8, /* Start of Image */
    137    SOS  = 0xDA, /* Start of Scan */
    138    RST  = 0xD0, /* Reset Marker d0 -> .. */
    139    RST7 = 0xD7, /* Reset Marker .. -> d7 */
    140    EOI  = 0xD9, /* End of Image */
    141    DRI  = 0xDD, /* Define Restart Interval */
    142    APP0 = 0xE0,
    143 };
    144 
    145 #define cY	0
    146 #define cCb	1
    147 #define cCr	2
    148 
    149 #define BLACK_Y 0
    150 #define BLACK_U 127
    151 #define BLACK_V 127
    152 
    153 #define SANITY_CHECK 1
    154 
    155 #if JPEG_DEBUG
    156 #define error(fmt, args...) do { \
    157    snprintf(error_string, sizeof(error_string), fmt, ## args); \
    158    return -1; \
    159 } while(0)
    160 
    161 #define trace(fmt, args...) do { \
    162    fprintf(stderr, fmt, ## args); \
    163    fflush(stderr); \
    164 } while(0)
    165 #else
    166 #define error(fmt, args...) do { return -1; } while(0)
    167 #define trace(fmt, args...) do { } while (0)
    168 #endif
    169 
    170 #ifndef __likely
    171 # define __likely(x) (!!(x))
    172 #endif
    173 #ifndef __unlikely
    174 # define __unlikely(x) (!!(x))
    175 #endif
    176 
    177 #define min(x, y) ((x) < (y) ? (x) : (y))
    178 #define max(x, y) ((x) > (y) ? (x) : (y))
    179 
    180 #if 0
    181 static char *print_bits(unsigned int value, char *bitstr)
    182 {
    183   int i, j;
    184   i=31;
    185   while (i>0)
    186    {
    187      if (value & (1UL<<i))
    188        break;
    189      i--;
    190    }
    191   j=0;
    192   while (i>=0)
    193    {
    194      bitstr[j++] = (value & (1UL<<i))?'1':'0';
    195      i--;
    196    }
    197   bitstr[j] = 0;
    198   return bitstr;
    199 }
    200 
    201 static void print_next_16bytes(int offset, const unsigned char *stream)
    202 {
    203   trace("%4.4x: %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
    204 	offset,
    205 	stream[0], stream[1], stream[2], stream[3],
    206 	stream[4], stream[5], stream[6], stream[7],
    207 	stream[8], stream[9], stream[10], stream[11],
    208 	stream[12], stream[13], stream[14], stream[15]);
    209 }
    210 
    211 #endif
    212 
    213 #endif
    214