#define TINYJPEG_FLAGS_MJPEG_TABLE (1<<1)
/* Format accepted in outout */
-enum tinyjpeg_fmt {
- TINYJPEG_FMT_GREY = 1,
- TINYJPEG_FMT_BGR24,
- TINYJPEG_FMT_RGB24,
- TINYJPEG_FMT_YUV420P,
-};
+struct tinyjpeg_colorspace;
+typedef const struct tinyjpeg_colorspace *tinyjpeg_colorspace_t;
+
+extern const tinyjpeg_colorspace_t TINYJPEG_FMT_GREY, TINYJPEG_FMT_BGR24,
+ TINYJPEG_FMT_RGB24, TINYJPEG_FMT_YUV420P, TINYJPEG_FMT_BGRA32,
+ TINYJPEG_FMT_RGBA32;
struct jdec_private *tinyjpeg_init(void);
void tinyjpeg_free(struct jdec_private *priv);
int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size);
-int tinyjpeg_decode(struct jdec_private *priv, int pixel_format);
+int tinyjpeg_decode(struct jdec_private *priv, tinyjpeg_colorspace_t pixel_format);
const char *tinyjpeg_get_errorstring(struct jdec_private *priv);
void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height);
int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **components);
libpng/pngrtran.o libpng/pngwtran.o libpng/pngmem.o \
libpng/pngerror.o libpng/pngpread.o \
\
- jpeg/tinyjpeg.o jpeg/jidctflt.o \
+ jpeg/tinyjpeg.o jpeg/jidctflt.o jpeg/decode1.o jpeg/decode3.o \
+ jpeg/rgb24.o jpeg/bgr24.o jpeg/yuv420p.o jpeg/grey.o \
\
sys/x86_init_fpu.o math/pow.o math/strtod.o
--- /dev/null
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/*******************************************************************************
+ *
+ * Colorspace conversion routine
+ *
+ *
+ * Note:
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ * R = Y + 1.40200 * Cr
+ * G = Y - 0.34414 * Cb - 0.71414 * Cr
+ * B = Y + 1.77200 * Cb
+ *
+ ******************************************************************************/
+static unsigned char clamp(int i)
+{
+ if (i<0)
+ return 0;
+ else if (i>255)
+ return 255;
+ else
+ return i;
+}
+
+/**
+ * YCrCb -> BGR24 (1x1)
+ * .---.
+ * | 1 |
+ * `---'
+ */
+static void YCrCB_to_BGR24_1x1(struct jdec_private *priv)
+{
+ const unsigned char *Y, *Cb, *Cr;
+ unsigned char *p;
+ int i,j;
+ int offset_to_next_row;
+
+#define SCALEBITS 10
+#define ONE_HALF (1UL << (SCALEBITS-1))
+#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+ p = priv->plane[0];
+ Y = priv->Y;
+ Cb = priv->Cb;
+ Cr = priv->Cr;
+ offset_to_next_row = priv->width*3 - 8*3;
+ for (i=0; i<8; i++) {
+
+ for (j=0;j<8;j++) {
+
+ int y, cb, cr;
+ int add_r, add_g, add_b;
+ int r, g , b;
+
+ y = (*Y++) << SCALEBITS;
+ cb = *Cb++ - 128;
+ cr = *Cr++ - 128;
+ add_r = FIX(1.40200) * cr + ONE_HALF;
+ add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+ add_b = FIX(1.77200) * cb + ONE_HALF;
+
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+
+ }
+
+ p += offset_to_next_row;
+ }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+
+/*
+ * YCrCb -> BGR24 (2x1)
+ * .-------.
+ * | 1 | 2 |
+ * `-------'
+ */
+static void YCrCB_to_BGR24_2x1(struct jdec_private *priv)
+{
+ const unsigned char *Y, *Cb, *Cr;
+ unsigned char *p;
+ int i,j;
+ int offset_to_next_row;
+
+#define SCALEBITS 10
+#define ONE_HALF (1UL << (SCALEBITS-1))
+#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+ p = priv->plane[0];
+ Y = priv->Y;
+ Cb = priv->Cb;
+ Cr = priv->Cr;
+ offset_to_next_row = priv->width*3 - 16*3;
+ for (i=0; i<8; i++) {
+
+ for (j=0; j<8; j++) {
+
+ int y, cb, cr;
+ int add_r, add_g, add_b;
+ int r, g , b;
+
+ cb = *Cb++ - 128;
+ cr = *Cr++ - 128;
+ add_r = FIX(1.40200) * cr + ONE_HALF;
+ add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+ add_b = FIX(1.77200) * cb + ONE_HALF;
+
+ y = (*Y++) << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+
+ y = (*Y++) << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+
+ }
+
+ p += offset_to_next_row;
+ }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+/*
+ * YCrCb -> BGR24 (1x2)
+ * .---.
+ * | 1 |
+ * |---|
+ * | 2 |
+ * `---'
+ */
+static void YCrCB_to_BGR24_1x2(struct jdec_private *priv)
+{
+ const unsigned char *Y, *Cb, *Cr;
+ unsigned char *p, *p2;
+ int i,j;
+ int offset_to_next_row;
+
+#define SCALEBITS 10
+#define ONE_HALF (1UL << (SCALEBITS-1))
+#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+ p = priv->plane[0];
+ p2 = priv->plane[0] + priv->width*3;
+ Y = priv->Y;
+ Cb = priv->Cb;
+ Cr = priv->Cr;
+ offset_to_next_row = 2*priv->width*3 - 8*3;
+ for (i=0; i<8; i++) {
+
+ for (j=0; j<8; j++) {
+
+ int y, cb, cr;
+ int add_r, add_g, add_b;
+ int r, g , b;
+
+ cb = *Cb++ - 128;
+ cr = *Cr++ - 128;
+ add_r = FIX(1.40200) * cr + ONE_HALF;
+ add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+ add_b = FIX(1.77200) * cb + ONE_HALF;
+
+ y = (*Y++) << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+
+ y = (Y[8-1]) << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+
+ }
+ Y += 8;
+ p += offset_to_next_row;
+ p2 += offset_to_next_row;
+ }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+
+/*
+ * YCrCb -> BGR24 (2x2)
+ * .-------.
+ * | 1 | 2 |
+ * |---+---|
+ * | 3 | 4 |
+ * `-------'
+ */
+static void YCrCB_to_BGR24_2x2(struct jdec_private *priv)
+{
+ const unsigned char *Y, *Cb, *Cr;
+ unsigned char *p, *p2;
+ int i,j;
+ int offset_to_next_row;
+
+#define SCALEBITS 10
+#define ONE_HALF (1UL << (SCALEBITS-1))
+#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+ p = priv->plane[0];
+ p2 = priv->plane[0] + priv->width*3;
+ Y = priv->Y;
+ Cb = priv->Cb;
+ Cr = priv->Cr;
+ offset_to_next_row = (priv->width*3*2) - 16*3;
+ for (i=0; i<8; i++) {
+
+ for (j=0;j<8;j++) {
+
+ int y, cb, cr;
+ int add_r, add_g, add_b;
+ int r, g , b;
+
+ cb = *Cb++ - 128;
+ cr = *Cr++ - 128;
+ add_r = FIX(1.40200) * cr + ONE_HALF;
+ add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+ add_b = FIX(1.77200) * cb + ONE_HALF;
+
+ y = (*Y++) << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+
+ y = (*Y++) << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+
+ y = (Y[16-2]) << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+
+ y = (Y[16-1]) << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ }
+ Y += 16;
+ p += offset_to_next_row;
+ p2 += offset_to_next_row;
+ }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+static int initialize_bgr24(struct jdec_private *priv,
+ unsigned int *bytes_per_blocklines,
+ unsigned int *bytes_per_mcu)
+{
+ if (priv->components[0] == NULL)
+ priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3);
+ bytes_per_blocklines[0] = priv->width * 3;
+ bytes_per_mcu[0] = 3*8;
+
+ return !priv->components[0];
+}
+
+static const struct tinyjpeg_colorspace format_bgr24 =
+ {
+ {
+ YCrCB_to_BGR24_1x1,
+ YCrCB_to_BGR24_1x2,
+ YCrCB_to_BGR24_2x1,
+ YCrCB_to_BGR24_2x2,
+ },
+ tinyjpeg_decode_mcu_3comp_table,
+ initialize_bgr24
+ };
+
+const tinyjpeg_colorspace_t TINYJPEG_FMT_BGR24 = &format_bgr24;
--- /dev/null
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/*
+ * Decode a 1x1 directly in 1 color
+ */
+static void decode_MCU_1x1_1plane(struct jdec_private *priv)
+{
+ // Y
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y, 8);
+
+ // Cb
+ tinyjpeg_process_Huffman_data_unit(priv, cCb);
+ IDCT(&priv->component_infos[cCb], priv->Cb, 8);
+
+ // Cr
+ tinyjpeg_process_Huffman_data_unit(priv, cCr);
+ IDCT(&priv->component_infos[cCr], priv->Cr, 8);
+}
+
+
+/*
+ * Decode a 2x1
+ * .-------.
+ * | 1 | 2 |
+ * `-------'
+ */
+static void decode_MCU_2x1_1plane(struct jdec_private *priv)
+{
+ // Y
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y, 16);
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y+8, 16);
+
+ // Cb
+ tinyjpeg_process_Huffman_data_unit(priv, cCb);
+
+ // Cr
+ tinyjpeg_process_Huffman_data_unit(priv, cCr);
+}
+
+
+/*
+ * Decode a 2x2 directly in GREY format (8bits)
+ * .-------.
+ * | 1 | 2 |
+ * |---+---|
+ * | 3 | 4 |
+ * `-------'
+ */
+static void decode_MCU_2x2_1plane(struct jdec_private *priv)
+{
+ // Y
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y, 16);
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y+8, 16);
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y+64*2, 16);
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16);
+
+ // Cb
+ tinyjpeg_process_Huffman_data_unit(priv, cCb);
+
+ // Cr
+ tinyjpeg_process_Huffman_data_unit(priv, cCr);
+}
+
+/*
+ * Decode a 1x2 mcu
+ * .---.
+ * | 1 |
+ * |---|
+ * | 2 |
+ * `---'
+ */
+static void decode_MCU_1x2_1plane(struct jdec_private *priv)
+{
+ // Y
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y, 8);
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y+64, 8);
+
+ // Cb
+ tinyjpeg_process_Huffman_data_unit(priv, cCb);
+
+ // Cr
+ tinyjpeg_process_Huffman_data_unit(priv, cCr);
+}
+
+const decode_MCU_fct tinyjpeg_decode_mcu_1comp_table[4] = {
+ decode_MCU_1x1_1plane,
+ decode_MCU_1x2_1plane,
+ decode_MCU_2x1_1plane,
+ decode_MCU_2x2_1plane,
+};
--- /dev/null
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/*
+ * Decode all the 3 components for 1x1
+ */
+static void decode_MCU_1x1_3planes(struct jdec_private *priv)
+{
+ // Y
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y, 8);
+
+ // Cb
+ tinyjpeg_process_Huffman_data_unit(priv, cCb);
+ IDCT(&priv->component_infos[cCb], priv->Cb, 8);
+
+ // Cr
+ tinyjpeg_process_Huffman_data_unit(priv, cCr);
+ IDCT(&priv->component_infos[cCr], priv->Cr, 8);
+}
+
+/*
+ * Decode a 2x1
+ * .-------.
+ * | 1 | 2 |
+ * `-------'
+ */
+static void decode_MCU_2x1_3planes(struct jdec_private *priv)
+{
+ // Y
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y, 16);
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y+8, 16);
+
+ // Cb
+ tinyjpeg_process_Huffman_data_unit(priv, cCb);
+ IDCT(&priv->component_infos[cCb], priv->Cb, 8);
+
+ // Cr
+ tinyjpeg_process_Huffman_data_unit(priv, cCr);
+ IDCT(&priv->component_infos[cCr], priv->Cr, 8);
+}
+
+/*
+ * Decode a 2x2
+ * .-------.
+ * | 1 | 2 |
+ * |---+---|
+ * | 3 | 4 |
+ * `-------'
+ */
+static void decode_MCU_2x2_3planes(struct jdec_private *priv)
+{
+ // Y
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y, 16);
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y+8, 16);
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y+64*2, 16);
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16);
+
+ // Cb
+ tinyjpeg_process_Huffman_data_unit(priv, cCb);
+ IDCT(&priv->component_infos[cCb], priv->Cb, 8);
+
+ // Cr
+ tinyjpeg_process_Huffman_data_unit(priv, cCr);
+ IDCT(&priv->component_infos[cCr], priv->Cr, 8);
+}
+
+/*
+ * Decode a 1x2 mcu
+ * .---.
+ * | 1 |
+ * |---|
+ * | 2 |
+ * `---'
+ */
+static void decode_MCU_1x2_3planes(struct jdec_private *priv)
+{
+ // Y
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y, 8);
+ tinyjpeg_process_Huffman_data_unit(priv, cY);
+ IDCT(&priv->component_infos[cY], priv->Y+64, 8);
+
+ // Cb
+ tinyjpeg_process_Huffman_data_unit(priv, cCb);
+ IDCT(&priv->component_infos[cCb], priv->Cb, 8);
+
+ // Cr
+ tinyjpeg_process_Huffman_data_unit(priv, cCr);
+ IDCT(&priv->component_infos[cCr], priv->Cr, 8);
+}
+
+const decode_MCU_fct tinyjpeg_decode_mcu_3comp_table[4] = {
+ decode_MCU_1x1_3planes,
+ decode_MCU_1x2_3planes,
+ decode_MCU_2x1_3planes,
+ decode_MCU_2x2_3planes,
+};
--- /dev/null
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/**
+ * YCrCb -> Grey (1x1)
+ * .---.
+ * | 1 |
+ * `---'
+ */
+static void YCrCB_to_Grey_1x1(struct jdec_private *priv)
+{
+ const unsigned char *y;
+ unsigned char *p;
+ unsigned int i;
+ int offset_to_next_row;
+
+ p = priv->plane[0];
+ y = priv->Y;
+ offset_to_next_row = priv->width;
+
+ for (i=0; i<8; i++) {
+ memcpy(p, y, 8);
+ y+=8;
+ p += offset_to_next_row;
+ }
+}
+
+/**
+ * YCrCb -> Grey (2x1)
+ * .-------.
+ * | 1 | 2 |
+ * `-------'
+ */
+static void YCrCB_to_Grey_2x1(struct jdec_private *priv)
+{
+ const unsigned char *y;
+ unsigned char *p;
+ unsigned int i;
+
+ p = priv->plane[0];
+ y = priv->Y;
+
+ for (i=0; i<8; i++) {
+ memcpy(p, y, 16);
+ y += 16;
+ p += priv->width;
+ }
+}
+
+
+/**
+ * YCrCb -> Grey (1x2)
+ * .---.
+ * | 1 |
+ * |---|
+ * | 2 |
+ * `---'
+ */
+static void YCrCB_to_Grey_1x2(struct jdec_private *priv)
+{
+ const unsigned char *y;
+ unsigned char *p;
+ unsigned int i;
+
+ p = priv->plane[0];
+ y = priv->Y;
+
+ for (i=0; i<16; i++) {
+ memcpy(p, y, 8);
+ y += 8;
+ p += priv->width;
+ }
+}
+
+/**
+ * YCrCb -> Grey (2x2)
+ * .-------.
+ * | 1 | 2 |
+ * |---+---|
+ * | 3 | 4 |
+ * `-------'
+ */
+static void YCrCB_to_Grey_2x2(struct jdec_private *priv)
+{
+ const unsigned char *y;
+ unsigned char *p;
+ unsigned int i;
+
+ p = priv->plane[0];
+ y = priv->Y;
+
+ for (i=0; i<16; i++) {
+ memcpy(p, y, 16);
+ y += 16;
+ p += priv->width;
+ }
+}
+
+static int initialize_grey(struct jdec_private *priv,
+ unsigned int *bytes_per_blocklines,
+ unsigned int *bytes_per_mcu)
+{
+ if (priv->components[0] == NULL)
+ priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3);
+ bytes_per_blocklines[0] = priv->width * 3;
+ bytes_per_mcu[0] = 3*8;
+
+ return !priv->components[0];
+}
+
+static const struct tinyjpeg_colorspace format_grey =
+ {
+ {
+ YCrCB_to_Grey_1x1,
+ YCrCB_to_Grey_1x2,
+ YCrCB_to_Grey_2x1,
+ YCrCB_to_Grey_2x2,
+ },
+ tinyjpeg_decode_mcu_1comp_table,
+ initialize_grey
+ };
+
+const tinyjpeg_colorspace_t TINYJPEG_FMT_GREY = &format_grey;
--- /dev/null
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/*******************************************************************************
+ *
+ * Colorspace conversion routine
+ *
+ *
+ * Note:
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ * R = Y + 1.40200 * Cr
+ * G = Y - 0.34414 * Cb - 0.71414 * Cr
+ * B = Y + 1.77200 * Cb
+ *
+ ******************************************************************************/
+static unsigned char clamp(int i)
+{
+ if (i<0)
+ return 0;
+ else if (i>255)
+ return 255;
+ else
+ return i;
+}
+
+/**
+ * YCrCb -> RGB24 (1x1)
+ * .---.
+ * | 1 |
+ * `---'
+ */
+static void YCrCB_to_RGB24_1x1(struct jdec_private *priv)
+{
+ const unsigned char *Y, *Cb, *Cr;
+ unsigned char *p;
+ int i,j;
+ int offset_to_next_row;
+
+#define SCALEBITS 10
+#define ONE_HALF (1UL << (SCALEBITS-1))
+#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+ p = priv->plane[0];
+ Y = priv->Y;
+ Cb = priv->Cb;
+ Cr = priv->Cr;
+ offset_to_next_row = priv->width*3 - 8*3;
+ for (i=0; i<8; i++) {
+
+ for (j=0;j<8;j++) {
+
+ int y, cb, cr;
+ int add_r, add_g, add_b;
+ int r, g , b;
+
+ y = (*Y++) << SCALEBITS;
+ cb = *Cb++ - 128;
+ cr = *Cr++ - 128;
+ add_r = FIX(1.40200) * cr + ONE_HALF;
+ add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+ add_b = FIX(1.77200) * cb + ONE_HALF;
+
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+
+ }
+
+ p += offset_to_next_row;
+ }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+/**
+ * YCrCb -> RGB24 (2x1)
+ * .-------.
+ * | 1 | 2 |
+ * `-------'
+ */
+static void YCrCB_to_RGB24_2x1(struct jdec_private *priv)
+{
+ const unsigned char *Y, *Cb, *Cr;
+ unsigned char *p;
+ int i,j;
+ int offset_to_next_row;
+
+#define SCALEBITS 10
+#define ONE_HALF (1UL << (SCALEBITS-1))
+#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+ p = priv->plane[0];
+ Y = priv->Y;
+ Cb = priv->Cb;
+ Cr = priv->Cr;
+ offset_to_next_row = priv->width*3 - 16*3;
+ for (i=0; i<8; i++) {
+
+ for (j=0; j<8; j++) {
+
+ int y, cb, cr;
+ int add_r, add_g, add_b;
+ int r, g , b;
+
+ y = (*Y++) << SCALEBITS;
+ cb = *Cb++ - 128;
+ cr = *Cr++ - 128;
+ add_r = FIX(1.40200) * cr + ONE_HALF;
+ add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+ add_b = FIX(1.77200) * cb + ONE_HALF;
+
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+
+ y = (*Y++) << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+
+ }
+
+ p += offset_to_next_row;
+ }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+
+/**
+ * YCrCb -> RGB24 (1x2)
+ * .---.
+ * | 1 |
+ * |---|
+ * | 2 |
+ * `---'
+ */
+static void YCrCB_to_RGB24_1x2(struct jdec_private *priv)
+{
+ const unsigned char *Y, *Cb, *Cr;
+ unsigned char *p, *p2;
+ int i,j;
+ int offset_to_next_row;
+
+#define SCALEBITS 10
+#define ONE_HALF (1UL << (SCALEBITS-1))
+#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+ p = priv->plane[0];
+ p2 = priv->plane[0] + priv->width*3;
+ Y = priv->Y;
+ Cb = priv->Cb;
+ Cr = priv->Cr;
+ offset_to_next_row = 2*priv->width*3 - 8*3;
+ for (i=0; i<8; i++) {
+
+ for (j=0; j<8; j++) {
+
+ int y, cb, cr;
+ int add_r, add_g, add_b;
+ int r, g , b;
+
+ cb = *Cb++ - 128;
+ cr = *Cr++ - 128;
+ add_r = FIX(1.40200) * cr + ONE_HALF;
+ add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+ add_b = FIX(1.77200) * cb + ONE_HALF;
+
+ y = (*Y++) << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+
+ y = (Y[8-1]) << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+
+ }
+ Y += 8;
+ p += offset_to_next_row;
+ p2 += offset_to_next_row;
+ }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+/**
+ * YCrCb -> RGB24 (2x2)
+ * .-------.
+ * | 1 | 2 |
+ * |---+---|
+ * | 3 | 4 |
+ * `-------'
+ */
+static void YCrCB_to_RGB24_2x2(struct jdec_private *priv)
+{
+ const unsigned char *Y, *Cb, *Cr;
+ unsigned char *p, *p2;
+ int i,j;
+ int offset_to_next_row;
+
+#define SCALEBITS 10
+#define ONE_HALF (1UL << (SCALEBITS-1))
+#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
+
+ p = priv->plane[0];
+ p2 = priv->plane[0] + priv->width*3;
+ Y = priv->Y;
+ Cb = priv->Cb;
+ Cr = priv->Cr;
+ offset_to_next_row = (priv->width*3*2) - 16*3;
+ for (i=0; i<8; i++) {
+
+ for (j=0;j<8;j++) {
+
+ int y, cb, cr;
+ int add_r, add_g, add_b;
+ int r, g , b;
+
+ cb = *Cb++ - 128;
+ cr = *Cr++ - 128;
+ add_r = FIX(1.40200) * cr + ONE_HALF;
+ add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
+ add_b = FIX(1.77200) * cb + ONE_HALF;
+
+ y = (*Y++) << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+
+ y = (*Y++) << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+
+ y = (Y[16-2]) << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+
+ y = (Y[16-1]) << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ }
+ Y += 16;
+ p += offset_to_next_row;
+ p2 += offset_to_next_row;
+ }
+
+#undef SCALEBITS
+#undef ONE_HALF
+#undef FIX
+
+}
+
+static int initialize_rgb24(struct jdec_private *priv,
+ unsigned int *bytes_per_blocklines,
+ unsigned int *bytes_per_mcu)
+{
+ if (priv->components[0] == NULL)
+ priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3);
+ bytes_per_blocklines[0] = priv->width * 3;
+ bytes_per_mcu[0] = 3*8;
+
+ return !priv->components[0];
+}
+
+static const struct tinyjpeg_colorspace format_rgb24 =
+ {
+ {
+ YCrCB_to_RGB24_1x1,
+ YCrCB_to_RGB24_1x2,
+ YCrCB_to_RGB24_2x1,
+ YCrCB_to_RGB24_2x2,
+ },
+ tinyjpeg_decode_mcu_3comp_table,
+ initialize_rgb24
+ };
+
+const tinyjpeg_colorspace_t TINYJPEG_FMT_RGB24 = &format_rgb24;
};
+struct tinyjpeg_colorspace {
+ convert_colorspace_fct convert_colorspace[4];
+ const decode_MCU_fct *decode_mcu_table;
+ int (*initialize)(struct jdec_private *, unsigned int *, unsigned int *);
+};
+
#define IDCT jpeg_idct_float
void jpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride);
+void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component);
+
+extern const decode_MCU_fct tinyjpeg_decode_mcu_3comp_table[4];
+extern const decode_MCU_fct tinyjpeg_decode_mcu_1comp_table[4];
+
+enum std_markers {
+ DQT = 0xDB, /* Define Quantization Table */
+ SOF = 0xC0, /* Start of Frame (size information) */
+ DHT = 0xC4, /* Huffman Table */
+ SOI = 0xD8, /* Start of Image */
+ SOS = 0xDA, /* Start of Scan */
+ EOI = 0xD9, /* End of Image */
+ APP0 = 0xE0,
+};
+
+#define cY 1
+#define cCb 2
+#define cCr 3
+
+#define BLACK_Y 0
+#define BLACK_U 127
+#define BLACK_V 127
+
+#define SANITY_CHECK 1
+
+#if DEBUG
+#define error(fmt, args...) do { \
+ snprintf(error_string, sizeof(error_string), fmt, ## args); \
+ return -1; \
+} while(0)
+
+#define trace(fmt, args...) do { \
+ fprintf(stderr, fmt, ## args); \
+ fflush(stderr); \
+} while(0)
+#else
+#define error(fmt, args...) do { return -1; } while(0)
+#define trace(fmt, args...) do { } while (0)
+#endif
+
+#if 0
+static char *print_bits(unsigned int value, char *bitstr)
+{
+ int i, j;
+ i=31;
+ while (i>0)
+ {
+ if (value & (1UL<<i))
+ break;
+ i--;
+ }
+ j=0;
+ while (i>=0)
+ {
+ bitstr[j++] = (value & (1UL<<i))?'1':'0';
+ i--;
+ }
+ bitstr[j] = 0;
+ return bitstr;
+}
+
+static void print_next_16bytes(int offset, const unsigned char *stream)
+{
+ 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",
+ offset,
+ stream[0], stream[1], stream[2], stream[3],
+ stream[4], stream[5], stream[6], stream[7],
+ stream[8], stream[9], stream[10], stream[11],
+ stream[12], stream[13], stream[14], stream[15]);
+}
+
+#endif
+
#endif
#include "tinyjpeg.h"
#include "tinyjpeg-internal.h"
-enum std_markers {
- DQT = 0xDB, /* Define Quantization Table */
- SOF = 0xC0, /* Start of Frame (size information) */
- DHT = 0xC4, /* Huffman Table */
- SOI = 0xD8, /* Start of Image */
- SOS = 0xDA, /* Start of Scan */
- EOI = 0xD9, /* End of Image */
- APP0 = 0xE0,
-};
-
-#define cY 1
-#define cCb 2
-#define cCr 3
-
-#define BLACK_Y 0
-#define BLACK_U 127
-#define BLACK_V 127
-
-#define SANITY_CHECK 1
-
-#if DEBUG
-#define error(fmt, args...) do { \
- snprintf(error_string, sizeof(error_string), fmt, ## args); \
- return -1; \
-} while(0)
-
-#define trace(fmt, args...) do { \
- fprintf(stderr, fmt, ## args); \
- fflush(stderr); \
-} while(0)
-#else
-#define error(fmt, args...) do { return -1; } while(0)
-#define trace(fmt, args...) do { } while (0)
-#endif
-
-#if 0
-static char *print_bits(unsigned int value, char *bitstr)
-{
- int i, j;
- i=31;
- while (i>0)
- {
- if (value & (1UL<<i))
- break;
- i--;
- }
- j=0;
- while (i>=0)
- {
- bitstr[j++] = (value & (1UL<<i))?'1':'0';
- i--;
- }
- bitstr[j] = 0;
- return bitstr;
-}
-
-static void print_next_16bytes(int offset, const unsigned char *stream)
-{
- 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",
- offset,
- stream[0], stream[1], stream[2], stream[3],
- stream[4], stream[5], stream[6], stream[7],
- stream[8], stream[9], stream[10], stream[11],
- stream[12], stream[13], stream[14], stream[15]);
-}
-
-#endif
-
/* Global variable to return the last error found while deconding */
static char error_string[256];
* The table coefficients is already dezigzaged at the end of the operation.
*
*/
-static void process_Huffman_data_unit(struct jdec_private *priv, int component)
+void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component)
{
unsigned char j;
int huff_code;
*
******************************************************************************/
-static unsigned char clamp(int i)
-{
- if (i<0)
- return 0;
- else if (i>255)
- return 255;
- else
- return i;
-}
-
-
-/**
- * YCrCb -> YUV420P (1x1)
- * .---.
- * | 1 |
- * `---'
- */
-static void YCrCB_to_YUV420P_1x1(struct jdec_private *priv)
-{
- const unsigned char *s, *y;
- unsigned char *p;
- int i,j;
-
- p = priv->plane[0];
- y = priv->Y;
- for (i=0; i<8; i++)
- {
- memcpy(p, y, 8);
- p+=priv->width;
- y+=8;
- }
-
- p = priv->plane[1];
- s = priv->Cb;
- for (i=0; i<8; i+=2)
- {
- for (j=0; j<8; j+=2, s+=2)
- *p++ = *s;
- s += 8; /* Skip one line */
- p += priv->width/2 - 4;
- }
-
- p = priv->plane[2];
- s = priv->Cr;
- for (i=0; i<8; i+=2)
- {
- for (j=0; j<8; j+=2, s+=2)
- *p++ = *s;
- s += 8; /* Skip one line */
- p += priv->width/2 - 4;
- }
-}
-
-/**
- * YCrCb -> YUV420P (2x1)
- * .-------.
- * | 1 | 2 |
- * `-------'
- */
-static void YCrCB_to_YUV420P_2x1(struct jdec_private *priv)
-{
- unsigned char *p;
- const unsigned char *s, *y1;
- int i,j;
-
- p = priv->plane[0];
- y1 = priv->Y;
- for (i=0; i<8; i++)
- {
- memcpy(p, y1, 16);
- p += priv->width;
- y1 += 16;
- }
-
- p = priv->plane[1];
- s = priv->Cb;
- for (i=0; i<8; i+=2)
- {
- for (j=0; j<8; j+=1, s+=1)
- *p++ = *s;
- s += 8; /* Skip one line */
- p += priv->width/2 - 8;
- }
-
- p = priv->plane[2];
- s = priv->Cr;
- for (i=0; i<8; i+=2)
- {
- for (j=0; j<8; j+=1, s+=1)
- *p++ = *s;
- s += 8; /* Skip one line */
- p += priv->width/2 - 8;
- }
-}
-
-
-/**
- * YCrCb -> YUV420P (1x2)
- * .---.
- * | 1 |
- * |---|
- * | 2 |
- * `---'
- */
-static void YCrCB_to_YUV420P_1x2(struct jdec_private *priv)
-{
- const unsigned char *s, *y;
- unsigned char *p;
- int i,j;
-
- p = priv->plane[0];
- y = priv->Y;
- for (i=0; i<16; i++)
- {
- memcpy(p, y, 8);
- p+=priv->width;
- y+=8;
- }
-
- p = priv->plane[1];
- s = priv->Cb;
- for (i=0; i<8; i++)
- {
- for (j=0; j<8; j+=2, s+=2)
- *p++ = *s;
- p += priv->width/2 - 4;
- }
-
- p = priv->plane[2];
- s = priv->Cr;
- for (i=0; i<8; i++)
- {
- for (j=0; j<8; j+=2, s+=2)
- *p++ = *s;
- p += priv->width/2 - 4;
- }
-}
-
-/**
- * YCrCb -> YUV420P (2x2)
- * .-------.
- * | 1 | 2 |
- * |---+---|
- * | 3 | 4 |
- * `-------'
- */
-static void YCrCB_to_YUV420P_2x2(struct jdec_private *priv)
-{
- unsigned char *p;
- const unsigned char *s, *y1;
- int i;
-
- p = priv->plane[0];
- y1 = priv->Y;
- for (i=0; i<16; i++)
- {
- memcpy(p, y1, 16);
- p += priv->width;
- y1 += 16;
- }
-
- p = priv->plane[1];
- s = priv->Cb;
- for (i=0; i<8; i++)
- {
- memcpy(p, s, 8);
- s += 8;
- p += priv->width/2;
- }
-
- p = priv->plane[2];
- s = priv->Cr;
- for (i=0; i<8; i++)
- {
- memcpy(p, s, 8);
- s += 8;
- p += priv->width/2;
- }
-}
-
-/**
- * YCrCb -> RGB24 (1x1)
- * .---.
- * | 1 |
- * `---'
- */
-static void YCrCB_to_RGB24_1x1(struct jdec_private *priv)
-{
- const unsigned char *Y, *Cb, *Cr;
- unsigned char *p;
- int i,j;
- int offset_to_next_row;
-
-#define SCALEBITS 10
-#define ONE_HALF (1UL << (SCALEBITS-1))
-#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
-
- p = priv->plane[0];
- Y = priv->Y;
- Cb = priv->Cb;
- Cr = priv->Cr;
- offset_to_next_row = priv->width*3 - 8*3;
- for (i=0; i<8; i++) {
-
- for (j=0;j<8;j++) {
-
- int y, cb, cr;
- int add_r, add_g, add_b;
- int r, g , b;
-
- y = (*Y++) << SCALEBITS;
- cb = *Cb++ - 128;
- cr = *Cr++ - 128;
- add_r = FIX(1.40200) * cr + ONE_HALF;
- add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
- add_b = FIX(1.77200) * cb + ONE_HALF;
-
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
-
- }
-
- p += offset_to_next_row;
- }
-
-#undef SCALEBITS
-#undef ONE_HALF
-#undef FIX
-
-}
-
-/**
- * YCrCb -> BGR24 (1x1)
- * .---.
- * | 1 |
- * `---'
- */
-static void YCrCB_to_BGR24_1x1(struct jdec_private *priv)
-{
- const unsigned char *Y, *Cb, *Cr;
- unsigned char *p;
- int i,j;
- int offset_to_next_row;
-
-#define SCALEBITS 10
-#define ONE_HALF (1UL << (SCALEBITS-1))
-#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
-
- p = priv->plane[0];
- Y = priv->Y;
- Cb = priv->Cb;
- Cr = priv->Cr;
- offset_to_next_row = priv->width*3 - 8*3;
- for (i=0; i<8; i++) {
-
- for (j=0;j<8;j++) {
-
- int y, cb, cr;
- int add_r, add_g, add_b;
- int r, g , b;
-
- y = (*Y++) << SCALEBITS;
- cb = *Cb++ - 128;
- cr = *Cr++ - 128;
- add_r = FIX(1.40200) * cr + ONE_HALF;
- add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
- add_b = FIX(1.77200) * cb + ONE_HALF;
-
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
-
- }
-
- p += offset_to_next_row;
- }
-
-#undef SCALEBITS
-#undef ONE_HALF
-#undef FIX
-
-}
-
-
-/**
- * YCrCb -> RGB24 (2x1)
- * .-------.
- * | 1 | 2 |
- * `-------'
- */
-static void YCrCB_to_RGB24_2x1(struct jdec_private *priv)
-{
- const unsigned char *Y, *Cb, *Cr;
- unsigned char *p;
- int i,j;
- int offset_to_next_row;
-
-#define SCALEBITS 10
-#define ONE_HALF (1UL << (SCALEBITS-1))
-#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
-
- p = priv->plane[0];
- Y = priv->Y;
- Cb = priv->Cb;
- Cr = priv->Cr;
- offset_to_next_row = priv->width*3 - 16*3;
- for (i=0; i<8; i++) {
-
- for (j=0; j<8; j++) {
-
- int y, cb, cr;
- int add_r, add_g, add_b;
- int r, g , b;
-
- y = (*Y++) << SCALEBITS;
- cb = *Cb++ - 128;
- cr = *Cr++ - 128;
- add_r = FIX(1.40200) * cr + ONE_HALF;
- add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
- add_b = FIX(1.77200) * cb + ONE_HALF;
-
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
-
- y = (*Y++) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
-
- }
-
- p += offset_to_next_row;
- }
-
-#undef SCALEBITS
-#undef ONE_HALF
-#undef FIX
-
-}
-
-/*
- * YCrCb -> BGR24 (2x1)
- * .-------.
- * | 1 | 2 |
- * `-------'
- */
-static void YCrCB_to_BGR24_2x1(struct jdec_private *priv)
-{
- const unsigned char *Y, *Cb, *Cr;
- unsigned char *p;
- int i,j;
- int offset_to_next_row;
-
-#define SCALEBITS 10
-#define ONE_HALF (1UL << (SCALEBITS-1))
-#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
-
- p = priv->plane[0];
- Y = priv->Y;
- Cb = priv->Cb;
- Cr = priv->Cr;
- offset_to_next_row = priv->width*3 - 16*3;
- for (i=0; i<8; i++) {
-
- for (j=0; j<8; j++) {
-
- int y, cb, cr;
- int add_r, add_g, add_b;
- int r, g , b;
-
- cb = *Cb++ - 128;
- cr = *Cr++ - 128;
- add_r = FIX(1.40200) * cr + ONE_HALF;
- add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
- add_b = FIX(1.77200) * cb + ONE_HALF;
-
- y = (*Y++) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
-
- y = (*Y++) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
-
- }
-
- p += offset_to_next_row;
- }
-
-#undef SCALEBITS
-#undef ONE_HALF
-#undef FIX
-
-}
-
-/**
- * YCrCb -> RGB24 (1x2)
- * .---.
- * | 1 |
- * |---|
- * | 2 |
- * `---'
- */
-static void YCrCB_to_RGB24_1x2(struct jdec_private *priv)
-{
- const unsigned char *Y, *Cb, *Cr;
- unsigned char *p, *p2;
- int i,j;
- int offset_to_next_row;
-
-#define SCALEBITS 10
-#define ONE_HALF (1UL << (SCALEBITS-1))
-#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
-
- p = priv->plane[0];
- p2 = priv->plane[0] + priv->width*3;
- Y = priv->Y;
- Cb = priv->Cb;
- Cr = priv->Cr;
- offset_to_next_row = 2*priv->width*3 - 8*3;
- for (i=0; i<8; i++) {
-
- for (j=0; j<8; j++) {
-
- int y, cb, cr;
- int add_r, add_g, add_b;
- int r, g , b;
-
- cb = *Cb++ - 128;
- cr = *Cr++ - 128;
- add_r = FIX(1.40200) * cr + ONE_HALF;
- add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
- add_b = FIX(1.77200) * cb + ONE_HALF;
-
- y = (*Y++) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
-
- y = (Y[8-1]) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
-
- }
- Y += 8;
- p += offset_to_next_row;
- p2 += offset_to_next_row;
- }
-
-#undef SCALEBITS
-#undef ONE_HALF
-#undef FIX
-
-}
-
-/*
- * YCrCb -> BGR24 (1x2)
- * .---.
- * | 1 |
- * |---|
- * | 2 |
- * `---'
- */
-static void YCrCB_to_BGR24_1x2(struct jdec_private *priv)
-{
- const unsigned char *Y, *Cb, *Cr;
- unsigned char *p, *p2;
- int i,j;
- int offset_to_next_row;
-
-#define SCALEBITS 10
-#define ONE_HALF (1UL << (SCALEBITS-1))
-#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
-
- p = priv->plane[0];
- p2 = priv->plane[0] + priv->width*3;
- Y = priv->Y;
- Cb = priv->Cb;
- Cr = priv->Cr;
- offset_to_next_row = 2*priv->width*3 - 8*3;
- for (i=0; i<8; i++) {
-
- for (j=0; j<8; j++) {
-
- int y, cb, cr;
- int add_r, add_g, add_b;
- int r, g , b;
-
- cb = *Cb++ - 128;
- cr = *Cr++ - 128;
- add_r = FIX(1.40200) * cr + ONE_HALF;
- add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
- add_b = FIX(1.77200) * cb + ONE_HALF;
-
- y = (*Y++) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
-
- y = (Y[8-1]) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
-
- }
- Y += 8;
- p += offset_to_next_row;
- p2 += offset_to_next_row;
- }
-
-#undef SCALEBITS
-#undef ONE_HALF
-#undef FIX
-
-}
-
-
-/**
- * YCrCb -> RGB24 (2x2)
- * .-------.
- * | 1 | 2 |
- * |---+---|
- * | 3 | 4 |
- * `-------'
- */
-static void YCrCB_to_RGB24_2x2(struct jdec_private *priv)
-{
- const unsigned char *Y, *Cb, *Cr;
- unsigned char *p, *p2;
- int i,j;
- int offset_to_next_row;
-
-#define SCALEBITS 10
-#define ONE_HALF (1UL << (SCALEBITS-1))
-#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
-
- p = priv->plane[0];
- p2 = priv->plane[0] + priv->width*3;
- Y = priv->Y;
- Cb = priv->Cb;
- Cr = priv->Cr;
- offset_to_next_row = (priv->width*3*2) - 16*3;
- for (i=0; i<8; i++) {
-
- for (j=0;j<8;j++) {
-
- int y, cb, cr;
- int add_r, add_g, add_b;
- int r, g , b;
-
- cb = *Cb++ - 128;
- cr = *Cr++ - 128;
- add_r = FIX(1.40200) * cr + ONE_HALF;
- add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
- add_b = FIX(1.77200) * cb + ONE_HALF;
-
- y = (*Y++) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
-
- y = (*Y++) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
-
- y = (Y[16-2]) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
-
- y = (Y[16-1]) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
- }
- Y += 16;
- p += offset_to_next_row;
- p2 += offset_to_next_row;
- }
-
-#undef SCALEBITS
-#undef ONE_HALF
-#undef FIX
-
-}
-
-
-/*
- * YCrCb -> BGR24 (2x2)
- * .-------.
- * | 1 | 2 |
- * |---+---|
- * | 3 | 4 |
- * `-------'
- */
-static void YCrCB_to_BGR24_2x2(struct jdec_private *priv)
-{
- const unsigned char *Y, *Cb, *Cr;
- unsigned char *p, *p2;
- int i,j;
- int offset_to_next_row;
-
-#define SCALEBITS 10
-#define ONE_HALF (1UL << (SCALEBITS-1))
-#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5))
-
- p = priv->plane[0];
- p2 = priv->plane[0] + priv->width*3;
- Y = priv->Y;
- Cb = priv->Cb;
- Cr = priv->Cr;
- offset_to_next_row = (priv->width*3*2) - 16*3;
- for (i=0; i<8; i++) {
-
- for (j=0;j<8;j++) {
-
- int y, cb, cr;
- int add_r, add_g, add_b;
- int r, g , b;
-
- cb = *Cb++ - 128;
- cr = *Cr++ - 128;
- add_r = FIX(1.40200) * cr + ONE_HALF;
- add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
- add_b = FIX(1.77200) * cb + ONE_HALF;
-
- y = (*Y++) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
-
- y = (*Y++) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
-
- y = (Y[16-2]) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
-
- y = (Y[16-1]) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
- }
- Y += 16;
- p += offset_to_next_row;
- p2 += offset_to_next_row;
- }
-
-#undef SCALEBITS
-#undef ONE_HALF
-#undef FIX
-
-}
-
-
-
-/**
- * YCrCb -> Grey (1x1)
- * .---.
- * | 1 |
- * `---'
- */
-static void YCrCB_to_Grey_1x1(struct jdec_private *priv)
-{
- const unsigned char *y;
- unsigned char *p;
- unsigned int i;
- int offset_to_next_row;
-
- p = priv->plane[0];
- y = priv->Y;
- offset_to_next_row = priv->width;
-
- for (i=0; i<8; i++) {
- memcpy(p, y, 8);
- y+=8;
- p += offset_to_next_row;
- }
-}
-
-/**
- * YCrCb -> Grey (2x1)
- * .-------.
- * | 1 | 2 |
- * `-------'
- */
-static void YCrCB_to_Grey_2x1(struct jdec_private *priv)
-{
- const unsigned char *y;
- unsigned char *p;
- unsigned int i;
-
- p = priv->plane[0];
- y = priv->Y;
-
- for (i=0; i<8; i++) {
- memcpy(p, y, 16);
- y += 16;
- p += priv->width;
- }
-}
-
-
-/**
- * YCrCb -> Grey (1x2)
- * .---.
- * | 1 |
- * |---|
- * | 2 |
- * `---'
- */
-static void YCrCB_to_Grey_1x2(struct jdec_private *priv)
-{
- const unsigned char *y;
- unsigned char *p;
- unsigned int i;
-
- p = priv->plane[0];
- y = priv->Y;
-
- for (i=0; i<16; i++) {
- memcpy(p, y, 8);
- y += 8;
- p += priv->width;
- }
-}
-
-/**
- * YCrCb -> Grey (2x2)
- * .-------.
- * | 1 | 2 |
- * |---+---|
- * | 3 | 4 |
- * `-------'
- */
-static void YCrCB_to_Grey_2x2(struct jdec_private *priv)
-{
- const unsigned char *y;
- unsigned char *p;
- unsigned int i;
-
- p = priv->plane[0];
- y = priv->Y;
-
- for (i=0; i<16; i++) {
- memcpy(p, y, 16);
- y += 16;
- p += priv->width;
- }
-}
-
-
-/*
- * Decode all the 3 components for 1x1
- */
-static void decode_MCU_1x1_3planes(struct jdec_private *priv)
-{
- // Y
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y, 8);
-
- // Cb
- process_Huffman_data_unit(priv, cCb);
- IDCT(&priv->component_infos[cCb], priv->Cb, 8);
-
- // Cr
- process_Huffman_data_unit(priv, cCr);
- IDCT(&priv->component_infos[cCr], priv->Cr, 8);
-}
-
-/*
- * Decode a 1x1 directly in 1 color
- */
-static void decode_MCU_1x1_1plane(struct jdec_private *priv)
-{
- // Y
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y, 8);
-
- // Cb
- process_Huffman_data_unit(priv, cCb);
- IDCT(&priv->component_infos[cCb], priv->Cb, 8);
-
- // Cr
- process_Huffman_data_unit(priv, cCr);
- IDCT(&priv->component_infos[cCr], priv->Cr, 8);
-}
-
-
-/*
- * Decode a 2x1
- * .-------.
- * | 1 | 2 |
- * `-------'
- */
-static void decode_MCU_2x1_3planes(struct jdec_private *priv)
-{
- // Y
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y, 16);
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y+8, 16);
-
- // Cb
- process_Huffman_data_unit(priv, cCb);
- IDCT(&priv->component_infos[cCb], priv->Cb, 8);
-
- // Cr
- process_Huffman_data_unit(priv, cCr);
- IDCT(&priv->component_infos[cCr], priv->Cr, 8);
-}
-
-/*
- * Decode a 2x1
- * .-------.
- * | 1 | 2 |
- * `-------'
- */
-static void decode_MCU_2x1_1plane(struct jdec_private *priv)
-{
- // Y
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y, 16);
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y+8, 16);
-
- // Cb
- process_Huffman_data_unit(priv, cCb);
-
- // Cr
- process_Huffman_data_unit(priv, cCr);
-}
-
-
-/*
- * Decode a 2x2
- * .-------.
- * | 1 | 2 |
- * |---+---|
- * | 3 | 4 |
- * `-------'
- */
-static void decode_MCU_2x2_3planes(struct jdec_private *priv)
-{
- // Y
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y, 16);
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y+8, 16);
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y+64*2, 16);
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16);
-
- // Cb
- process_Huffman_data_unit(priv, cCb);
- IDCT(&priv->component_infos[cCb], priv->Cb, 8);
-
- // Cr
- process_Huffman_data_unit(priv, cCr);
- IDCT(&priv->component_infos[cCr], priv->Cr, 8);
-}
-
-/*
- * Decode a 2x2 directly in GREY format (8bits)
- * .-------.
- * | 1 | 2 |
- * |---+---|
- * | 3 | 4 |
- * `-------'
- */
-static void decode_MCU_2x2_1plane(struct jdec_private *priv)
-{
- // Y
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y, 16);
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y+8, 16);
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y+64*2, 16);
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16);
-
- // Cb
- process_Huffman_data_unit(priv, cCb);
-
- // Cr
- process_Huffman_data_unit(priv, cCr);
-}
-
-/*
- * Decode a 1x2 mcu
- * .---.
- * | 1 |
- * |---|
- * | 2 |
- * `---'
- */
-static void decode_MCU_1x2_3planes(struct jdec_private *priv)
-{
- // Y
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y, 8);
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y+64, 8);
-
- // Cb
- process_Huffman_data_unit(priv, cCb);
- IDCT(&priv->component_infos[cCb], priv->Cb, 8);
-
- // Cr
- process_Huffman_data_unit(priv, cCr);
- IDCT(&priv->component_infos[cCr], priv->Cr, 8);
-}
-
-/*
- * Decode a 1x2 mcu
- * .---.
- * | 1 |
- * |---|
- * | 2 |
- * `---'
- */
-static void decode_MCU_1x2_1plane(struct jdec_private *priv)
-{
- // Y
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y, 8);
- process_Huffman_data_unit(priv, cY);
- IDCT(&priv->component_infos[cY], priv->Y+64, 8);
-
- // Cb
- process_Huffman_data_unit(priv, cCb);
-
- // Cr
- process_Huffman_data_unit(priv, cCr);
-}
-
static void print_SOF(const unsigned char *stream)
{
int width, height, nr_components, precision;
return ret;
}
-static const decode_MCU_fct decode_mcu_3comp_table[4] = {
- decode_MCU_1x1_3planes,
- decode_MCU_1x2_3planes,
- decode_MCU_2x1_3planes,
- decode_MCU_2x2_3planes,
-};
-
-static const decode_MCU_fct decode_mcu_1comp_table[4] = {
- decode_MCU_1x1_1plane,
- decode_MCU_1x2_1plane,
- decode_MCU_2x1_1plane,
- decode_MCU_2x2_1plane,
-};
-
-static const convert_colorspace_fct convert_colorspace_yuv420p[4] = {
- YCrCB_to_YUV420P_1x1,
- YCrCB_to_YUV420P_1x2,
- YCrCB_to_YUV420P_2x1,
- YCrCB_to_YUV420P_2x2,
-};
-
-static const convert_colorspace_fct convert_colorspace_rgb24[4] = {
- YCrCB_to_RGB24_1x1,
- YCrCB_to_RGB24_1x2,
- YCrCB_to_RGB24_2x1,
- YCrCB_to_RGB24_2x2,
-};
-
-static const convert_colorspace_fct convert_colorspace_bgr24[4] = {
- YCrCB_to_BGR24_1x1,
- YCrCB_to_BGR24_1x2,
- YCrCB_to_BGR24_2x1,
- YCrCB_to_BGR24_2x2,
-};
-
-static const convert_colorspace_fct convert_colorspace_grey[4] = {
- YCrCB_to_Grey_1x1,
- YCrCB_to_Grey_1x2,
- YCrCB_to_Grey_2x1,
- YCrCB_to_Grey_2x2,
-};
-
/**
* Decode and convert the jpeg image into @pixfmt@ image
*
* Note: components will be automaticaly allocated if no memory is attached.
*/
-int tinyjpeg_decode(struct jdec_private *priv, int pixfmt)
+int tinyjpeg_decode(struct jdec_private *priv,
+ const struct tinyjpeg_colorspace *pixfmt)
{
unsigned int x, y, xstride_by_mcu, ystride_by_mcu;
unsigned int bytes_per_blocklines[3], bytes_per_mcu[3];
decode_MCU_fct decode_MCU;
const decode_MCU_fct *decode_mcu_table;
- const convert_colorspace_fct *colorspace_array_conv;
convert_colorspace_fct convert_to_pixfmt;
/* To keep gcc happy initialize some array */
bytes_per_blocklines[1] = 0;
bytes_per_blocklines[2] = 0;
- decode_mcu_table = decode_mcu_3comp_table;
- switch (pixfmt) {
- case TINYJPEG_FMT_YUV420P:
- colorspace_array_conv = convert_colorspace_yuv420p;
- if (priv->components[0] == NULL)
- priv->components[0] = (uint8_t *)malloc(priv->width * priv->height);
- if (priv->components[1] == NULL)
- priv->components[1] = (uint8_t *)malloc(priv->width * priv->height/4);
- if (priv->components[2] == NULL)
- priv->components[2] = (uint8_t *)malloc(priv->width * priv->height/4);
- bytes_per_blocklines[0] = priv->width;
- bytes_per_blocklines[1] = priv->width/4;
- bytes_per_blocklines[2] = priv->width/4;
- bytes_per_mcu[0] = 8;
- bytes_per_mcu[1] = 4;
- bytes_per_mcu[2] = 4;
- break;
-
- case TINYJPEG_FMT_RGB24:
- colorspace_array_conv = convert_colorspace_rgb24;
- if (priv->components[0] == NULL)
- priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3);
- bytes_per_blocklines[0] = priv->width * 3;
- bytes_per_mcu[0] = 3*8;
- break;
-
- case TINYJPEG_FMT_BGR24:
- colorspace_array_conv = convert_colorspace_bgr24;
- if (priv->components[0] == NULL)
- priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3);
- bytes_per_blocklines[0] = priv->width * 3;
- bytes_per_mcu[0] = 3*8;
- break;
-
- case TINYJPEG_FMT_GREY:
- decode_mcu_table = decode_mcu_1comp_table;
- colorspace_array_conv = convert_colorspace_grey;
- if (priv->components[0] == NULL)
- priv->components[0] = (uint8_t *)malloc(priv->width * priv->height);
- bytes_per_blocklines[0] = priv->width;
- bytes_per_mcu[0] = 8;
- break;
-
- default:
- trace("Bad pixel format\n");
- return -1;
- }
+ decode_mcu_table = pixfmt->decode_mcu_table;
+
+ /* Fix: check return value */
+ pixfmt->initialize(priv, bytes_per_blocklines, bytes_per_mcu);
xstride_by_mcu = ystride_by_mcu = 8;
if ((priv->component_infos[cY].Hfactor | priv->component_infos[cY].Vfactor) == 1) {
decode_MCU = decode_mcu_table[0];
- convert_to_pixfmt = colorspace_array_conv[0];
+ convert_to_pixfmt = pixfmt->convert_colorspace[0];
trace("Use decode 1x1 sampling\n");
} else if (priv->component_infos[cY].Hfactor == 1) {
decode_MCU = decode_mcu_table[1];
- convert_to_pixfmt = colorspace_array_conv[1];
+ convert_to_pixfmt = pixfmt->convert_colorspace[1];
ystride_by_mcu = 16;
trace("Use decode 1x2 sampling (not supported)\n");
} else if (priv->component_infos[cY].Vfactor == 2) {
decode_MCU = decode_mcu_table[3];
- convert_to_pixfmt = colorspace_array_conv[3];
+ convert_to_pixfmt = pixfmt->convert_colorspace[3];
xstride_by_mcu = 16;
ystride_by_mcu = 16;
trace("Use decode 2x2 sampling\n");
} else {
decode_MCU = decode_mcu_table[2];
- convert_to_pixfmt = colorspace_array_conv[2];
+ convert_to_pixfmt = pixfmt->convert_colorspace[2];
xstride_by_mcu = 16;
trace("Use decode 2x1 sampling\n");
}
priv->flags = flags;
return oldflags;
}
-
--- /dev/null
+/*
+ * Small jpeg decoder library
+ *
+ * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the author nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * yuv420p.c
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "tinyjpeg.h"
+#include "tinyjpeg-internal.h"
+
+/**
+ * YCrCb -> YUV420P (1x1)
+ * .---.
+ * | 1 |
+ * `---'
+ */
+static void YCrCB_to_YUV420P_1x1(struct jdec_private *priv)
+{
+ const unsigned char *s, *y;
+ unsigned char *p;
+ int i,j;
+
+ p = priv->plane[0];
+ y = priv->Y;
+ for (i=0; i<8; i++)
+ {
+ memcpy(p, y, 8);
+ p+=priv->width;
+ y+=8;
+ }
+
+ p = priv->plane[1];
+ s = priv->Cb;
+ for (i=0; i<8; i+=2)
+ {
+ for (j=0; j<8; j+=2, s+=2)
+ *p++ = *s;
+ s += 8; /* Skip one line */
+ p += priv->width/2 - 4;
+ }
+
+ p = priv->plane[2];
+ s = priv->Cr;
+ for (i=0; i<8; i+=2)
+ {
+ for (j=0; j<8; j+=2, s+=2)
+ *p++ = *s;
+ s += 8; /* Skip one line */
+ p += priv->width/2 - 4;
+ }
+}
+
+/**
+ * YCrCb -> YUV420P (2x1)
+ * .-------.
+ * | 1 | 2 |
+ * `-------'
+ */
+static void YCrCB_to_YUV420P_2x1(struct jdec_private *priv)
+{
+ unsigned char *p;
+ const unsigned char *s, *y1;
+ int i,j;
+
+ p = priv->plane[0];
+ y1 = priv->Y;
+ for (i=0; i<8; i++)
+ {
+ memcpy(p, y1, 16);
+ p += priv->width;
+ y1 += 16;
+ }
+
+ p = priv->plane[1];
+ s = priv->Cb;
+ for (i=0; i<8; i+=2)
+ {
+ for (j=0; j<8; j+=1, s+=1)
+ *p++ = *s;
+ s += 8; /* Skip one line */
+ p += priv->width/2 - 8;
+ }
+
+ p = priv->plane[2];
+ s = priv->Cr;
+ for (i=0; i<8; i+=2)
+ {
+ for (j=0; j<8; j+=1, s+=1)
+ *p++ = *s;
+ s += 8; /* Skip one line */
+ p += priv->width/2 - 8;
+ }
+}
+
+
+/**
+ * YCrCb -> YUV420P (1x2)
+ * .---.
+ * | 1 |
+ * |---|
+ * | 2 |
+ * `---'
+ */
+static void YCrCB_to_YUV420P_1x2(struct jdec_private *priv)
+{
+ const unsigned char *s, *y;
+ unsigned char *p;
+ int i,j;
+
+ p = priv->plane[0];
+ y = priv->Y;
+ for (i=0; i<16; i++)
+ {
+ memcpy(p, y, 8);
+ p+=priv->width;
+ y+=8;
+ }
+
+ p = priv->plane[1];
+ s = priv->Cb;
+ for (i=0; i<8; i++)
+ {
+ for (j=0; j<8; j+=2, s+=2)
+ *p++ = *s;
+ p += priv->width/2 - 4;
+ }
+
+ p = priv->plane[2];
+ s = priv->Cr;
+ for (i=0; i<8; i++)
+ {
+ for (j=0; j<8; j+=2, s+=2)
+ *p++ = *s;
+ p += priv->width/2 - 4;
+ }
+}
+
+/**
+ * YCrCb -> YUV420P (2x2)
+ * .-------.
+ * | 1 | 2 |
+ * |---+---|
+ * | 3 | 4 |
+ * `-------'
+ */
+static void YCrCB_to_YUV420P_2x2(struct jdec_private *priv)
+{
+ unsigned char *p;
+ const unsigned char *s, *y1;
+ int i;
+
+ p = priv->plane[0];
+ y1 = priv->Y;
+ for (i=0; i<16; i++)
+ {
+ memcpy(p, y1, 16);
+ p += priv->width;
+ y1 += 16;
+ }
+
+ p = priv->plane[1];
+ s = priv->Cb;
+ for (i=0; i<8; i++)
+ {
+ memcpy(p, s, 8);
+ s += 8;
+ p += priv->width/2;
+ }
+
+ p = priv->plane[2];
+ s = priv->Cr;
+ for (i=0; i<8; i++)
+ {
+ memcpy(p, s, 8);
+ s += 8;
+ p += priv->width/2;
+ }
+}
+
+static int initialize_yuv420p(struct jdec_private *priv,
+ unsigned int *bytes_per_blocklines,
+ unsigned int *bytes_per_mcu)
+{
+ if (priv->components[0] == NULL)
+ priv->components[0] = (uint8_t *)malloc(priv->width * priv->height);
+ if (priv->components[1] == NULL)
+ priv->components[1] = (uint8_t *)malloc(priv->width * priv->height/4);
+ if (priv->components[2] == NULL)
+ priv->components[2] = (uint8_t *)malloc(priv->width * priv->height/4);
+ bytes_per_blocklines[0] = priv->width;
+ bytes_per_blocklines[1] = priv->width/4;
+ bytes_per_blocklines[2] = priv->width/4;
+ bytes_per_mcu[0] = 8;
+ bytes_per_mcu[1] = 4;
+ bytes_per_mcu[2] = 4;
+
+ /* Return nonzero on failure */
+ return !priv->components[0] || !priv->components[1] || !priv->components[2];
+}
+
+static const struct tinyjpeg_colorspace format_yuv420p =
+ {
+ {
+ YCrCB_to_YUV420P_1x1,
+ YCrCB_to_YUV420P_1x2,
+ YCrCB_to_YUV420P_2x1,
+ YCrCB_to_YUV420P_2x2,
+ },
+ tinyjpeg_decode_mcu_3comp_table,
+ initialize_yuv420p
+ };
+
+const tinyjpeg_colorspace_t TINYJPEG_FMT_YUV420P = &format_yuv420p;