summaryrefslogtreecommitdiff
path: root/com32/lib
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-08-05 08:42:59 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-08-05 08:42:59 -0700
commit74da4eee9a9c7c34a986e4a559627acd12b49a9b (patch)
tree4b21743d9ba061c2f9719f66ecd735fefd70c5de /com32/lib
parent8e01231be41fd889bcb71604dbda511688ed0f38 (diff)
downloadsyslinux-74da4eee9a9c7c34a986e4a559627acd12b49a9b.tar.gz
tinyjpeg: update to revision 20070609
Update tinyjpeg to upstream version 20070609. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'com32/lib')
-rw-r--r--com32/lib/jpeg/jidctflt.c22
-rw-r--r--com32/lib/jpeg/tinyjpeg-internal.h33
-rw-r--r--com32/lib/jpeg/tinyjpeg.c183
-rw-r--r--com32/lib/jpeg/yuv420p.c35
4 files changed, 210 insertions, 63 deletions
diff --git a/com32/lib/jpeg/jidctflt.c b/com32/lib/jpeg/jidctflt.c
index e5e66edc..6f0df772 100644
--- a/com32/lib/jpeg/jidctflt.c
+++ b/com32/lib/jpeg/jidctflt.c
@@ -80,7 +80,7 @@
#define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval))
-#if defined(__GNUC__) && defined(__i686__) || defined(__x86_64__)
+#if 1 && defined(__GNUC__) && (defined(__i686__) || defined(__x86_64__))
static inline unsigned char descale_and_clamp(int x, int shift)
{
@@ -92,7 +92,7 @@ static inline unsigned char descale_and_clamp(int x, int shift)
"\tcmpl %4,%1\n"
"\tcmovg %4,%1\n"
: "=r"(x)
- : "0"(x), "i"(shift), "i"(1UL<<(shift-1)), "r" (0xff), "r" (0)
+ : "0"(x), "Ir"(shift), "ir"(1UL<<(shift-1)), "r" (0xff), "r" (0)
);
return x;
}
@@ -120,7 +120,7 @@ static inline unsigned char descale_and_clamp(int x, int shift)
*/
void
-jpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride)
+tinyjpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride)
{
FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
@@ -269,14 +269,14 @@ jpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride)
/* Final output stage: scale down by a factor of 8 and range-limit */
- outptr[0] = descale_and_clamp(tmp0 + tmp7, 3);
- outptr[7] = descale_and_clamp(tmp0 - tmp7, 3);
- outptr[1] = descale_and_clamp(tmp1 + tmp6, 3);
- outptr[6] = descale_and_clamp(tmp1 - tmp6, 3);
- outptr[2] = descale_and_clamp(tmp2 + tmp5, 3);
- outptr[5] = descale_and_clamp(tmp2 - tmp5, 3);
- outptr[4] = descale_and_clamp(tmp3 + tmp4, 3);
- outptr[3] = descale_and_clamp(tmp3 - tmp4, 3);
+ outptr[0] = descale_and_clamp((int)(tmp0 + tmp7), 3);
+ outptr[7] = descale_and_clamp((int)(tmp0 - tmp7), 3);
+ outptr[1] = descale_and_clamp((int)(tmp1 + tmp6), 3);
+ outptr[6] = descale_and_clamp((int)(tmp1 - tmp6), 3);
+ outptr[2] = descale_and_clamp((int)(tmp2 + tmp5), 3);
+ outptr[5] = descale_and_clamp((int)(tmp2 - tmp5), 3);
+ outptr[4] = descale_and_clamp((int)(tmp3 + tmp4), 3);
+ outptr[3] = descale_and_clamp((int)(tmp3 - tmp4), 3);
wsptr += DCTSIZE; /* advance pointer to next row */
diff --git a/com32/lib/jpeg/tinyjpeg-internal.h b/com32/lib/jpeg/tinyjpeg-internal.h
index 78cb0421..b04a302a 100644
--- a/com32/lib/jpeg/tinyjpeg-internal.h
+++ b/com32/lib/jpeg/tinyjpeg-internal.h
@@ -35,14 +35,21 @@
#ifndef __TINYJPEG_INTERNAL_H_
#define __TINYJPEG_INTERNAL_H_
+#include <setjmp.h>
+
+#define SANITY_CHECK 1
+
struct jdec_private;
+#define HUFFMAN_BITS_SIZE 256
#define HUFFMAN_HASH_NBITS 9
#define HUFFMAN_HASH_SIZE (1UL<<HUFFMAN_HASH_NBITS)
#define HUFFMAN_HASH_MASK (HUFFMAN_HASH_SIZE-1)
#define HUFFMAN_TABLES 4
-#define COMPONENTS 4
+#define COMPONENTS 3
+#define JPEG_MAX_WIDTH 2048
+#define JPEG_MAX_HEIGHT 2048
struct huffman_table
{
@@ -66,6 +73,9 @@ struct component
struct huffman_table *DC_table;
short int previous_DC; /* Previous DC coefficient */
short int DCT[64]; /* DCT coef */
+#if SANITY_CHECK
+ unsigned int cid;
+#endif
};
@@ -81,7 +91,7 @@ struct jdec_private
unsigned int flags;
/* Private variables */
- const unsigned char *stream_begin;
+ const unsigned char *stream_begin, *stream_end;
unsigned int stream_length;
const unsigned char *stream; /* Pointer to the current stream */
@@ -92,24 +102,28 @@ struct jdec_private
struct huffman_table HTDC[HUFFMAN_TABLES]; /* DC huffman tables */
struct huffman_table HTAC[HUFFMAN_TABLES]; /* AC huffman tables */
int default_huffman_table_initialized;
+ int restart_interval;
+ int restarts_to_go; /* MCUs left in this restart interval */
+ int last_rst_marker_seen; /* Rst marker is incremented each time */
/* Temp space used after the IDCT to store each components */
uint8_t Y[64*4], Cr[64], Cb[64];
+ jmp_buf jump_state;
/* Internal Pointer use for colorspace conversion, do not modify it !!! */
uint8_t *plane[COMPONENTS];
};
+#define IDCT tinyjpeg_idct_float
+void tinyjpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride);
+
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];
@@ -121,13 +135,16 @@ enum std_markers {
DHT = 0xC4, /* Huffman Table */
SOI = 0xD8, /* Start of Image */
SOS = 0xDA, /* Start of Scan */
+ RST = 0xD0, /* Reset Marker d0 -> .. */
+ RST7 = 0xD7, /* Reset Marker .. -> d7 */
EOI = 0xD9, /* End of Image */
+ DRI = 0xDD, /* Define Restart Interval */
APP0 = 0xE0,
};
-#define cY 1
-#define cCb 2
-#define cCr 3
+#define cY 0
+#define cCb 1
+#define cCr 2
#define BLACK_Y 0
#define BLACK_U 127
diff --git a/com32/lib/jpeg/tinyjpeg.c b/com32/lib/jpeg/tinyjpeg.c
index f8e881f0..657ff6e1 100644
--- a/com32/lib/jpeg/tinyjpeg.c
+++ b/com32/lib/jpeg/tinyjpeg.c
@@ -35,6 +35,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
+#include <errno.h>
#include "tinyjpeg.h"
#include "tinyjpeg-internal.h"
@@ -162,7 +163,10 @@ static const unsigned char val_ac_chrominance[] =
#define fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
while (nbits_in_reservoir<nbits_wanted) \
{ \
- const unsigned char c = *stream++; \
+ unsigned char c; \
+ if (stream >= priv->stream_end) \
+ longjmp(priv->jump_state, -EIO); \
+ c = *stream++; \
reservoir <<= 8; \
if (c == 0xff && *stream == 0x00) \
stream++; \
@@ -177,7 +181,7 @@ static const unsigned char val_ac_chrominance[] =
result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \
nbits_in_reservoir -= (nbits_wanted); \
reservoir &= ((1U<<nbits_in_reservoir)-1); \
- if (result < (1UL<<((nbits_wanted)-1))) \
+ if ((unsigned int)result < (1UL<<((nbits_wanted)-1))) \
result += (0xFFFFFFFFUL<<(nbits_wanted))+1; \
} while(0);
@@ -186,8 +190,15 @@ static const unsigned char val_ac_chrominance[] =
result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \
} while(0);
+/* To speed up the decoding, we assume that the reservoir have enough bit
+ * slow version:
+ * #define skip_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
+ * fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \
+ * nbits_in_reservoir -= (nbits_wanted); \
+ * reservoir &= ((1U<<nbits_in_reservoir)-1); \
+ * } while(0);
+ */
#define skip_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
- fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \
nbits_in_reservoir -= (nbits_wanted); \
reservoir &= ((1U<<nbits_in_reservoir)-1); \
} while(0);
@@ -195,6 +206,7 @@ static const unsigned char val_ac_chrominance[] =
#define be16_to_cpu(x) (((x)[0]<<8)|(x)[1])
+static void resync(struct jdec_private *priv);
/**
* Get the next (valid) huffman code in the stream.
@@ -215,9 +227,9 @@ static int get_next_huffman_code(struct jdec_private *priv, struct huffman_table
look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, HUFFMAN_HASH_NBITS, hcode);
value = huffman_table->lookup[hcode];
- if (value>=0)
+ if (__likely(value >= 0))
{
- int code_size = huffman_table->code_size[value];
+ unsigned int code_size = huffman_table->code_size[value];
skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, code_size);
return value;
}
@@ -253,17 +265,19 @@ static int get_next_huffman_code(struct jdec_private *priv, struct huffman_table
void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component)
{
unsigned char j;
- int huff_code;
+ unsigned int huff_code;
unsigned char size_val, count_0;
struct component *c = &priv->component_infos[component];
short int DCT[64];
+
/* Initialize the DCT coef table */
memset(DCT, 0, sizeof(DCT));
/* DC coefficient decoding */
huff_code = get_next_huffman_code(priv, c->DC_table);
+ //trace("+ %x\n", huff_code);
if (huff_code) {
get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, huff_code, DCT[0]);
DCT[0] += c->previous_DC;
@@ -277,6 +291,7 @@ void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component
while (j<64)
{
huff_code = get_next_huffman_code(priv, c->AC_table);
+ //trace("- %x\n", huff_code);
size_val = huff_code & 0xF;
count_0 = huff_code >> 4;
@@ -291,6 +306,11 @@ void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component
else
{
j += count_0; /* skip count_0 zeroes */
+ if (__unlikely(j >= 64))
+ {
+ snprintf(error_string, sizeof(error_string), "Bad huffman data (buffer overflow)");
+ break;
+ }
get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, size_val, DCT[j]);
j++;
}
@@ -298,7 +318,6 @@ void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component
for (j = 0; j < 64; j++)
c->DCT[j] = DCT[zigzag[j]];
-
}
/*
@@ -311,8 +330,8 @@ void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component
static void build_huffman_table(const unsigned char *bits, const unsigned char *vals, struct huffman_table *table)
{
unsigned int i, j, code, code_size, val, nbits;
- unsigned char huffsize[257], *hz;
- unsigned int huffcode[257], *hc;
+ unsigned char huffsize[HUFFMAN_BITS_SIZE+1], *hz;
+ unsigned int huffcode[HUFFMAN_BITS_SIZE+1], *hc;
int next_free_entry;
/*
@@ -340,10 +359,11 @@ static void build_huffman_table(const unsigned char *bits, const unsigned char *
nbits = *hz;
while (*hz)
{
- while (*hz == nbits) {
+ while (*hz == nbits)
+ {
*hc++ = code++;
hz++;
- }
+ }
code <<= 1;
nbits++;
}
@@ -358,7 +378,7 @@ static void build_huffman_table(const unsigned char *bits, const unsigned char *
code = huffcode[i];
code_size = huffsize[i];
- trace("val=%2.2x code=%8.8x codesize=%2.2d\n", i, code, code_size);
+ trace("val=%2.2x code=%8.8x codesize=%2.2d\n", val, code, code_size);
table->code_size[val] = code_size;
if (code_size <= HUFFMAN_HASH_NBITS)
@@ -386,7 +406,6 @@ static void build_huffman_table(const unsigned char *bits, const unsigned char *
}
}
-
}
static void build_default_huffman_tables(struct jdec_private *priv)
@@ -483,14 +502,15 @@ static void build_quantization_table(float *qtable, const unsigned char *ref_tab
static int parse_DQT(struct jdec_private *priv, const unsigned char *stream)
{
- int length, qi;
+ int qi;
float *table;
+ const unsigned char *dqt_block_end;
trace("> DQT marker\n");
- length = be16_to_cpu(stream) - 2;
+ dqt_block_end = stream + be16_to_cpu(stream);
stream += 2; /* Skip length */
- while (length>0)
+ while (stream < dqt_block_end)
{
qi = *stream++;
#if SANITY_CHECK
@@ -502,8 +522,8 @@ static int parse_DQT(struct jdec_private *priv, const unsigned char *stream)
table = priv->Q_tables[qi];
build_quantization_table(table, stream);
stream += 64;
- length -= 65;
}
+ trace("< DQT marker\n");
return 0;
}
@@ -513,6 +533,7 @@ static int parse_SOF(struct jdec_private *priv, const unsigned char *stream)
int Q_table;
struct component *c;
+ trace("> SOF marker\n");
print_SOF(stream);
height = be16_to_cpu(stream+3);
@@ -521,31 +542,40 @@ static int parse_SOF(struct jdec_private *priv, const unsigned char *stream)
#if SANITY_CHECK
if (stream[2] != 8)
error("Precision other than 8 is not supported\n");
- if (width>2048 || height>2048)
+ if (width>JPEG_MAX_WIDTH || height>JPEG_MAX_HEIGHT)
error("Width and Height (%dx%d) seems suspicious\n", width, height);
if (nr_components != 3)
error("We only support YUV images\n");
+#if 0
if (height%16)
error("Height need to be a multiple of 16 (current height is %d)\n", height);
if (width%16)
error("Width need to be a multiple of 16 (current Width is %d)\n", width);
#endif
+#endif
stream += 8;
for (i=0; i<nr_components; i++) {
cid = *stream++;
sampling_factor = *stream++;
Q_table = *stream++;
- c = &priv->component_infos[cid];
+ c = &priv->component_infos[i];
+#if SANITY_CHECK
+ c->cid = cid;
+ if (Q_table >= COMPONENTS)
+ error("Bad Quantization table index (got %d, max allowed %d)\n", Q_table, COMPONENTS-1);
+#endif
c->Vfactor = sampling_factor&0xf;
c->Hfactor = sampling_factor>>4;
c->Q_table = priv->Q_tables[Q_table];
trace("Component:%d factor:%dx%d Quantization table:%d\n",
- cid, c->Hfactor, c->Hfactor, Q_table );
+ cid, c->Hfactor, c->Hfactor, Q_table );
}
priv->width = width;
priv->height = height;
+ trace("< SOF marker\n");
+
return 0;
}
@@ -570,12 +600,16 @@ static int parse_SOS(struct jdec_private *priv, const unsigned char *stream)
error("We do not support more than 2 AC Huffman table\n");
if ((table>>4)>=4)
error("We do not support more than 2 DC Huffman table\n");
+ if (cid != priv->component_infos[i].cid)
+ error("SOS cid order (%d:%d) isn't compatible with the SOF marker (%d:%d)\n",
+ i, cid, i, priv->component_infos[i].cid);
trace("ComponentId:%d tableAC:%d tableDC:%d\n", cid, table&0xf, table>>4);
#endif
- priv->component_infos[cid].AC_table = &priv->HTAC[table&0xf];
- priv->component_infos[cid].DC_table = &priv->HTDC[table>>4];
+ priv->component_infos[i].AC_table = &priv->HTAC[table&0xf];
+ priv->component_infos[i].DC_table = &priv->HTDC[table>>4];
}
priv->stream = stream+3;
+ trace("< SOS marker\n");
return 0;
}
@@ -601,12 +635,11 @@ static int parse_DHT(struct jdec_private *priv, const unsigned char *stream)
count += huff_bits[i];
}
#if SANITY_CHECK
- if (count > 1024)
- error("No more than 1024 bytes is allowed to describe a huffman table");
+ if (count >= HUFFMAN_BITS_SIZE)
+ error("No more than %d bytes is allowed to describe a huffman table", HUFFMAN_BITS_SIZE);
if ( (index &0xf) >= HUFFMAN_TABLES)
- error("No mode than %d Huffman tables is supported\n", HUFFMAN_TABLES);
- trace("Huffman table %s n%d\n", (index&0xf0)?"AC":"DC", index&0xf);
- trace("Length of the table: %d\n", count);
+ error("No more than %d Huffman tables is supported (got %d)\n", HUFFMAN_TABLES, index&0xf);
+ trace("Huffman table %s[%d] length=%d\n", (index&0xf0)?"AC":"DC", index&0xf, count);
#endif
if (index & 0xf0 )
@@ -617,11 +650,38 @@ static int parse_DHT(struct jdec_private *priv, const unsigned char *stream)
length -= 1;
length -= 16;
length -= count;
+ stream += count;
}
trace("< DHT marker\n");
return 0;
}
+static int parse_DRI(struct jdec_private *priv, const unsigned char *stream)
+{
+ unsigned int length;
+
+ trace("> DRI marker\n");
+
+ length = be16_to_cpu(stream);
+
+#if SANITY_CHECK
+ if (length != 4)
+ error("Length of DRI marker need to be 4\n");
+#endif
+
+ priv->restart_interval = be16_to_cpu(stream+2);
+
+#if DEBUG
+ trace("Restart interval = %d\n", priv->restart_interval);
+#endif
+
+ trace("< DRI marker\n");
+
+ return 0;
+}
+
+
+
static void resync(struct jdec_private *priv)
{
int i;
@@ -632,9 +692,46 @@ static void resync(struct jdec_private *priv)
priv->reservoir = 0;
priv->nbits_in_reservoir = 0;
-
+ if (priv->restart_interval > 0)
+ priv->restarts_to_go = priv->restart_interval;
+ else
+ priv->restarts_to_go = -1;
}
+static int find_next_rst_marker(struct jdec_private *priv)
+{
+ int rst_marker_found = 0;
+ int marker;
+ const unsigned char *stream = priv->stream;
+
+ /* Parse marker */
+ while (!rst_marker_found)
+ {
+ while (*stream++ != 0xff)
+ {
+ if (stream >= priv->stream_end)
+ error("EOF while search for a RST marker.");
+ }
+ /* Skip any padding ff byte (this is normal) */
+ while (*stream == 0xff)
+ stream++;
+
+ marker = *stream++;
+ if ((RST+priv->last_rst_marker_seen) == marker)
+ rst_marker_found = 1;
+ else if (marker >= RST && marker <= RST7)
+ error("Wrong Reset marker found, abording");
+ else if (marker == EOI)
+ return 0;
+ }
+ trace("RST Marker %d found at offset %d\n", priv->last_rst_marker_seen, stream - priv->stream_begin);
+
+ priv->stream = stream;
+ priv->last_rst_marker_seen++;
+ priv->last_rst_marker_seen &= 7;
+
+ return 0;
+}
static int parse_JFIF(struct jdec_private *priv, const unsigned char *stream)
{
@@ -676,6 +773,10 @@ static int parse_JFIF(struct jdec_private *priv, const unsigned char *stream)
return -1;
dht_marker_found = 1;
break;
+ case DRI:
+ if (parse_DRI(priv, stream) < 0)
+ return -1;
+ break;
default:
trace("> Unknown marker %2.2x\n", marker);
break;
@@ -767,6 +868,7 @@ int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, u
priv->stream_begin = buf+2;
priv->stream_length = size-2;
+ priv->stream_end = priv->stream_begin + priv->stream_length;
ret = parse_JFIF(priv, priv->stream_begin);
@@ -840,15 +942,30 @@ int tinyjpeg_decode(struct jdec_private *priv,
priv->plane[0] += bytes_per_mcu[0];
priv->plane[1] += bytes_per_mcu[1];
priv->plane[2] += bytes_per_mcu[2];
-
+ if (priv->restarts_to_go>0)
+ {
+ priv->restarts_to_go--;
+ if (priv->restarts_to_go == 0)
+ {
+ priv->stream -= (priv->nbits_in_reservoir/8);
+ resync(priv);
+ if (find_next_rst_marker(priv) < 0)
+ return -1;
+ }
+ }
}
}
+ trace("Input file size: %d\n", priv->stream_length+2);
+ trace("Input bytes actually read: %d\n", priv->stream - priv->stream_begin + 2);
+
return 0;
}
const char *tinyjpeg_get_errorstring(struct jdec_private *priv)
{
+ /* FIXME: the error string must be store in the context */
+ priv = priv;
return error_string;
}
@@ -860,7 +977,7 @@ void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned
int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **components, unsigned int ncomponents)
{
- int i;
+ unsigned int i;
if (ncomponents > COMPONENTS)
ncomponents = COMPONENTS;
for (i=0; i<ncomponents; i++)
@@ -870,7 +987,7 @@ int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **component
int tinyjpeg_set_components(struct jdec_private *priv, unsigned char * const *components, unsigned int ncomponents)
{
- int i;
+ unsigned int i;
if (ncomponents > COMPONENTS)
ncomponents = COMPONENTS;
for (i=0; i<ncomponents; i++)
@@ -882,7 +999,7 @@ int tinyjpeg_get_bytes_per_row(struct jdec_private *priv,
unsigned int *bytes,
unsigned int ncomponents)
{
- int i;
+ unsigned int i;
if (ncomponents > COMPONENTS)
ncomponents = COMPONENTS;
for (i=0; i<ncomponents; i++)
@@ -894,7 +1011,7 @@ int tinyjpeg_set_bytes_per_row(struct jdec_private *priv,
const unsigned int *bytes,
unsigned int ncomponents)
{
- int i;
+ unsigned int i;
if (ncomponents > COMPONENTS)
ncomponents = COMPONENTS;
for (i=0; i<ncomponents; i++)
diff --git a/com32/lib/jpeg/yuv420p.c b/com32/lib/jpeg/yuv420p.c
index 0c5edf7c..f8aeb447 100644
--- a/com32/lib/jpeg/yuv420p.c
+++ b/com32/lib/jpeg/yuv420p.c
@@ -43,6 +43,21 @@
#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
+ *
+ ******************************************************************************/
+
/**
* YCrCb -> YUV420P (1x1)
* .---.
@@ -61,7 +76,7 @@ static void YCrCB_to_YUV420P_1x1(struct jdec_private *priv)
{
memcpy(p, y, 8);
p += priv->bytes_per_row[0];
- y += 8;
+ y+=8;
}
p = priv->plane[1];
@@ -95,7 +110,7 @@ static void YCrCB_to_YUV420P_2x1(struct jdec_private *priv)
{
unsigned char *p;
const unsigned char *s, *y1;
- int i,j;
+ unsigned int i;
p = priv->plane[0];
y1 = priv->Y;
@@ -110,20 +125,18 @@ static void YCrCB_to_YUV420P_2x1(struct jdec_private *priv)
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->bytes_per_row[1] - 8;
+ memcpy(p, s, 8);
+ s += 16; /* Skip one line */
+ p += priv->bytes_per_row[1];
}
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->bytes_per_row[2] - 8;
+ memcpy(p, s, 8);
+ s += 16; /* Skip one line */
+ p += priv->bytes_per_row[2];
}
}
@@ -182,7 +195,7 @@ static void YCrCB_to_YUV420P_2x2(struct jdec_private *priv)
{
unsigned char *p;
const unsigned char *s, *y1;
- int i;
+ unsigned int i;
p = priv->plane[0];
y1 = priv->Y;