Home | History | Annotate | Download | only in jpeg
      1 /*
      2  * Small jpeg decoder library
      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 #include <stdio.h>
     35 #include <stdlib.h>
     36 #include <string.h>
     37 #include <stdint.h>
     38 
     39 #include "tinyjpeg.h"
     40 #include "tinyjpeg-internal.h"
     41 
     42 /*******************************************************************************
     43  *
     44  * Colorspace conversion routine
     45  *
     46  *
     47  * Note:
     48  * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
     49  * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
     50  * The conversion equations to be implemented are therefore
     51  *      R = Y                + 1.40200 * Cr
     52  *      G = Y - 0.34414 * Cb - 0.71414 * Cr
     53  *      B = Y + 1.77200 * Cb
     54  *
     55  ******************************************************************************/
     56 static unsigned char clamp(int i)
     57 {
     58   if (i<0)
     59     return 0;
     60   else if (i>255)
     61     return 255;
     62   else
     63     return i;
     64 }
     65 
     66 /**
     67  *  YCrCb -> RGB24 (1x1)
     68  *  .---.
     69  *  | 1 |
     70  *  `---'
     71  */
     72 static void YCrCB_to_RGB24_1x1(struct jdec_private *priv, int sx, int sy)
     73 {
     74   const unsigned char *Y, *Cb, *Cr;
     75   unsigned char *p;
     76   int i,j;
     77   int offset_to_next_row;
     78 
     79 #define SCALEBITS       10
     80 #define ONE_HALF        (1UL << (SCALEBITS-1))
     81 #define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
     82 
     83   p = priv->plane[0];
     84   Y = priv->Y;
     85   Cb = priv->Cb;
     86   Cr = priv->Cr;
     87   offset_to_next_row = priv->bytes_per_row[0] - 8*3;
     88   for (i = sy; i > 0; i--) {
     89     for (j = sx; j > 0; j++) {
     90        int y, cb, cr;
     91        int add_r, add_g, add_b;
     92        int r, g , b;
     93 
     94        y  = Y[0] << SCALEBITS;
     95        cb = *Cb++ - 128;
     96        cr = *Cr++ - 128;
     97        add_r = FIX(1.40200) * cr + ONE_HALF;
     98        add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
     99        add_b = FIX(1.77200) * cb + ONE_HALF;
    100 
    101        r = (y + add_r) >> SCALEBITS;
    102        *p++ = clamp(r);
    103        g = (y + add_g) >> SCALEBITS;
    104        *p++ = clamp(g);
    105        b = (y + add_b) >> SCALEBITS;
    106        *p++ = clamp(b);
    107 
    108        Y++;
    109     }
    110 
    111     p += offset_to_next_row;
    112   }
    113 
    114 #undef SCALEBITS
    115 #undef ONE_HALF
    116 #undef FIX
    117 
    118 }
    119 
    120 /**
    121  *  YCrCb -> RGB24 (2x1)
    122  *  .-------.
    123  *  | 1 | 2 |
    124  *  `-------'
    125  */
    126 static void YCrCB_to_RGB24_2x1(struct jdec_private *priv, int sx, int sy)
    127 {
    128   const unsigned char *Y, *Cb, *Cr;
    129   unsigned char *p;
    130   int i,j;
    131   int offset_to_next_row;
    132 
    133 #define SCALEBITS       10
    134 #define ONE_HALF        (1UL << (SCALEBITS-1))
    135 #define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
    136 
    137   p = priv->plane[0];
    138   Y = priv->Y;
    139   Cb = priv->Cb;
    140   Cr = priv->Cr;
    141   offset_to_next_row = priv->bytes_per_row[0] - 16*3;
    142   for (i = sy; i > 0; i--) {
    143 
    144     for (j = sx; j > 0; j -= 2) {
    145 
    146        int y, cb, cr;
    147        int add_r, add_g, add_b;
    148        int r, g , b;
    149 
    150        y  = Y[0] << SCALEBITS;
    151        cb = *Cb++ - 128;
    152        cr = *Cr++ - 128;
    153        add_r = FIX(1.40200) * cr + ONE_HALF;
    154        add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
    155        add_b = FIX(1.77200) * cb + ONE_HALF;
    156 
    157        r = (y + add_r) >> SCALEBITS;
    158        *p++ = clamp(r);
    159        g = (y + add_g) >> SCALEBITS;
    160        *p++ = clamp(g);
    161        b = (y + add_b) >> SCALEBITS;
    162        *p++ = clamp(b);
    163 
    164        if (j > 1) {
    165 	   y  = Y[1] << SCALEBITS;
    166 	   r = (y + add_r) >> SCALEBITS;
    167 	   *p++ = clamp(r);
    168 	   g = (y + add_g) >> SCALEBITS;
    169 	   *p++ = clamp(g);
    170 	   b = (y + add_b) >> SCALEBITS;
    171 	   *p++ = clamp(b);
    172        }
    173 
    174        Y += 2;
    175     }
    176 
    177     p += offset_to_next_row;
    178   }
    179 
    180 #undef SCALEBITS
    181 #undef ONE_HALF
    182 #undef FIX
    183 
    184 }
    185 
    186 
    187 /**
    188  *  YCrCb -> RGB24 (1x2)
    189  *  .---.
    190  *  | 1 |
    191  *  |---|
    192  *  | 2 |
    193  *  `---'
    194  */
    195 static void YCrCB_to_RGB24_1x2(struct jdec_private *priv, int sx, int sy)
    196 {
    197   const unsigned char *Y, *Cb, *Cr;
    198   unsigned char *p, *p2;
    199   int i,j;
    200   int offset_to_next_row;
    201 
    202 #define SCALEBITS       10
    203 #define ONE_HALF        (1UL << (SCALEBITS-1))
    204 #define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
    205 
    206   p = priv->plane[0];
    207   p2 = priv->plane[0] + priv->bytes_per_row[0];
    208   Y = priv->Y;
    209   Cb = priv->Cb;
    210   Cr = priv->Cr;
    211   offset_to_next_row = 2*priv->bytes_per_row[0] - 8*3;
    212   for (i = sy; i > 0; i -= 2) {
    213     for (j = sx; j > 0; j--) {
    214 
    215        int y, cb, cr;
    216        int add_r, add_g, add_b;
    217        int r, g , b;
    218 
    219        cb = *Cb++ - 128;
    220        cr = *Cr++ - 128;
    221        add_r = FIX(1.40200) * cr + ONE_HALF;
    222        add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
    223        add_b = FIX(1.77200) * cb + ONE_HALF;
    224 
    225        y  = Y[0] << SCALEBITS;
    226        r = (y + add_r) >> SCALEBITS;
    227        *p++ = clamp(r);
    228        g = (y + add_g) >> SCALEBITS;
    229        *p++ = clamp(g);
    230        b = (y + add_b) >> SCALEBITS;
    231        *p++ = clamp(b);
    232 
    233        if (i > 1) {
    234 	   y  = Y[8] << SCALEBITS;
    235 	   r = (y + add_r) >> SCALEBITS;
    236 	   *p2++ = clamp(r);
    237 	   g = (y + add_g) >> SCALEBITS;
    238 	   *p2++ = clamp(g);
    239 	   b = (y + add_b) >> SCALEBITS;
    240 	   *p2++ = clamp(b);
    241        }
    242 
    243        Y++;
    244     }
    245     Y += 8;
    246     p += offset_to_next_row;
    247     p2 += offset_to_next_row;
    248   }
    249 
    250 #undef SCALEBITS
    251 #undef ONE_HALF
    252 #undef FIX
    253 
    254 }
    255 
    256 /**
    257  *  YCrCb -> RGB24 (2x2)
    258  *  .-------.
    259  *  | 1 | 2 |
    260  *  |---+---|
    261  *  | 3 | 4 |
    262  *  `-------'
    263  */
    264 static void YCrCB_to_RGB24_2x2(struct jdec_private *priv, int sx, int sy)
    265 {
    266   const unsigned char *Y, *Cb, *Cr;
    267   unsigned char *p, *p2;
    268   int i,j;
    269   int offset_to_next_row;
    270 
    271 #define SCALEBITS       10
    272 #define ONE_HALF        (1UL << (SCALEBITS-1))
    273 #define FIX(x)          ((int)((x) * (1UL<<SCALEBITS) + 0.5))
    274 
    275   p = priv->plane[0];
    276   p2 = priv->plane[0] + priv->bytes_per_row[0];
    277   Y = priv->Y;
    278   Cb = priv->Cb;
    279   Cr = priv->Cr;
    280   offset_to_next_row = 2*priv->bytes_per_row[0] - 16*3;
    281   for (i = sy; i > 0; i -= 2) {
    282     for (j = sx; j > 0; j -= 2) {
    283 
    284        int y, cb, cr;
    285        int add_r, add_g, add_b;
    286        int r, g , b;
    287 
    288        cb = *Cb++ - 128;
    289        cr = *Cr++ - 128;
    290        add_r = FIX(1.40200) * cr + ONE_HALF;
    291        add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
    292        add_b = FIX(1.77200) * cb + ONE_HALF;
    293 
    294        y  = Y[0] << SCALEBITS;
    295        r = (y + add_r) >> SCALEBITS;
    296        *p++ = clamp(r);
    297        g = (y + add_g) >> SCALEBITS;
    298        *p++ = clamp(g);
    299        b = (y + add_b) >> SCALEBITS;
    300        *p++ = clamp(b);
    301 
    302        if (j > 1) {
    303 	   y  = Y[1] << SCALEBITS;
    304 	   r = (y + add_r) >> SCALEBITS;
    305 	   *p++ = clamp(r);
    306 	   g = (y + add_g) >> SCALEBITS;
    307 	   *p++ = clamp(g);
    308 	   b = (y + add_b) >> SCALEBITS;
    309 	   *p++ = clamp(b);
    310        }
    311 
    312        if (i > 1) {
    313 	   y  = Y[16+0] << SCALEBITS;
    314 	   r = (y + add_r) >> SCALEBITS;
    315 	   *p2++ = clamp(r);
    316 	   g = (y + add_g) >> SCALEBITS;
    317 	   *p2++ = clamp(g);
    318 	   b = (y + add_b) >> SCALEBITS;
    319 	   *p2++ = clamp(b);
    320 
    321 	   if (j > 1) {
    322 	       y  = Y[16+1] << SCALEBITS;
    323 	       r = (y + add_r) >> SCALEBITS;
    324 	       *p2++ = clamp(r);
    325 	       g = (y + add_g) >> SCALEBITS;
    326 	       *p2++ = clamp(g);
    327 	       b = (y + add_b) >> SCALEBITS;
    328 	       *p2++ = clamp(b);
    329 	   }
    330        }
    331 
    332        Y += 2;
    333     }
    334     Y  += 16;
    335     p  += offset_to_next_row;
    336     p2 += offset_to_next_row;
    337   }
    338 
    339 #undef SCALEBITS
    340 #undef ONE_HALF
    341 #undef FIX
    342 
    343 }
    344 
    345 static int initialize_rgb24(struct jdec_private *priv,
    346 			    unsigned int *bytes_per_blocklines,
    347 			    unsigned int *bytes_per_mcu)
    348 {
    349   if (!priv->bytes_per_row[0])
    350     priv->bytes_per_row[0] = priv->width * 3;
    351   if (priv->components[0] == NULL)
    352     priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
    353 
    354   bytes_per_blocklines[0] = priv->bytes_per_row[0] << 3;
    355   bytes_per_mcu[0] = 3*8;
    356 
    357   return !priv->components[0];
    358 }
    359 
    360 static const struct tinyjpeg_colorspace format_rgb24 =
    361   {
    362     {
    363       YCrCB_to_RGB24_1x1,
    364       YCrCB_to_RGB24_1x2,
    365       YCrCB_to_RGB24_2x1,
    366       YCrCB_to_RGB24_2x2,
    367     },
    368     tinyjpeg_decode_mcu_3comp_table,
    369     initialize_rgb24
    370   };
    371 
    372 const tinyjpeg_colorspace_t TINYJPEG_FMT_RGB24 = &format_rgb24;
    373