aboutsummaryrefslogtreecommitdiffstats
path: root/benchmarks/CHStone/jpeg/decode.c
diff options
context:
space:
mode:
Diffstat (limited to 'benchmarks/CHStone/jpeg/decode.c')
-rwxr-xr-xbenchmarks/CHStone/jpeg/decode.c464
1 files changed, 464 insertions, 0 deletions
diff --git a/benchmarks/CHStone/jpeg/decode.c b/benchmarks/CHStone/jpeg/decode.c
new file mode 100755
index 0000000..a670381
--- /dev/null
+++ b/benchmarks/CHStone/jpeg/decode.c
@@ -0,0 +1,464 @@
+/*
++--------------------------------------------------------------------------+
+| CHStone : a suite of benchmark programs for C-based High-Level Synthesis |
+| ======================================================================== |
+| |
+| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, |
+| H. Takada and K. Ishii |
+| Nagoya University, Japan |
+| |
+| * Remark : |
+| 1. This source code is modified to unify the formats of the benchmark |
+| programs in CHStone. |
+| 2. Test vectors are added for CHStone. |
+| 3. If "main_result" is 0 at the end of the program, the program is |
+| correctly executed. |
+| 4. Please follow the copyright of each benchmark program. |
++--------------------------------------------------------------------------+
+*/
+/*************************************************************
+Copyright (C) 1990, 1991, 1993 Andy C. Hung, all rights reserved.
+PUBLIC DOMAIN LICENSE: Stanford University Portable Video Research
+Group. If you use this software, you agree to the following: This
+program package is purely experimental, and is licensed "as is".
+Permission is granted to use, modify, and distribute this program
+without charge for any purpose, provided this license/ disclaimer
+notice appears in the copies. No warranty or maintenance is given,
+either expressed or implied. In no event shall the author(s) be
+liable to you or a third party for any special, incidental,
+consequential, or other damages, arising out of the use or inability
+to use the program for any purpose (or the loss of data), even if we
+have been advised of such possibilities. Any public reference or
+advertisement of this source code should refer to it as the Portable
+Video Research Group (PVRG) code, and not by any author(s) (or
+Stanford University) name.
+*************************************************************/
+
+/*
+************************************************************
+decode.c (original: transform.c)
+
+This file contains the reference DCT, the zig-zag and quantization
+algorithms.
+
+************************************************************
+*/
+/*
+ * Decoder
+ *
+ * @(#) $Id: decode.c,v 1.2 2003/07/18 10:19:21 honda Exp $
+ */
+void ChenIDct (int *x, int *y);
+
+int rgb_buf[4][RGB_NUM][DCTSIZE2];
+
+const int zigzag_index[64] = /* Is zig-zag map for matrix -> scan array */
+{ 0, 1, 5, 6, 14, 15, 27, 28,
+ 2, 4, 7, 13, 16, 26, 29, 42,
+ 3, 8, 12, 17, 25, 30, 41, 43,
+ 9, 11, 18, 24, 31, 40, 44, 53,
+ 10, 19, 23, 32, 39, 45, 52, 54,
+ 20, 22, 33, 38, 46, 51, 55, 60,
+ 21, 34, 37, 47, 50, 56, 59, 61,
+ 35, 36, 48, 49, 57, 58, 62, 63
+};
+
+
+/*
+ * IZigzagMatrix() performs an inverse zig-zag translation on the
+ * input imatrix and places the output in omatrix.
+ */
+void
+IZigzagMatrix (int *imatrix, int *omatrix)
+{
+ int i;
+
+ for (i = 0; i < DCTSIZE2; i++)
+
+ {
+
+*(omatrix++) = imatrix[zigzag_index[i]];
+
+}
+}
+
+
+/*
+ * IQuantize() takes an input matrix and does an inverse quantization
+ * and puts the output int qmatrix.
+ */
+void
+IQuantize (int *matrix, unsigned int *qmatrix)
+{
+ int *mptr;
+
+ for (mptr = matrix; mptr < matrix + DCTSIZE2; mptr++)
+ {
+ *mptr = *mptr * (*qmatrix);
+ qmatrix++;
+ }
+}
+
+
+/*
+ * PostshiftIDctMatrix() adds 128 (2048) to all 64 elements of an 8x8 matrix.
+ * This results in strictly positive values for all pixel coefficients.
+ */
+void
+PostshiftIDctMatrix (int *matrix, int shift)
+{
+ int *mptr;
+ for (mptr = matrix; mptr < matrix + DCTSIZE2; mptr++)
+ {
+ *mptr += shift;
+ }
+}
+
+
+/*
+ * BoundIDctMatrix bounds the inverse dct matrix so that no pixel has a
+ * value greater than 255 (4095) or less than 0.
+ */
+void
+BoundIDctMatrix (int *matrix, int Bound)
+{
+ int *mptr;
+
+ for (mptr = matrix; mptr < matrix + DCTSIZE2; mptr++)
+ {
+ if (*mptr < 0)
+ {
+ *mptr = 0;
+ }
+ else if (*mptr > Bound)
+ {
+ *mptr = Bound;
+ }
+ }
+}
+
+
+
+void
+WriteOneBlock (int *store, unsigned char *out_buf, int width, int height,
+ int voffs, int hoffs)
+{
+ int i, e;
+
+
+ /* Find vertical buffer offs. */
+ for (i = voffs; i < voffs + DCTSIZE; i++)
+ {
+ if (i < height)
+ {
+ int diff;
+ diff = width * i;
+ for (e = hoffs; e < hoffs + DCTSIZE; e++)
+ {
+ if (e < width)
+ {
+ out_buf[diff + e] = (unsigned char) (*(store++));
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+
+}
+
+/*
+ * WriteBlock() writes an array of data in the integer array pointed to
+ * by store out to the driver specified by the IOB. The integer array is
+ * stored in row-major form, that is, the first row of (8) elements, the
+ * second row of (8) elements....
+ * ONLY for MCU 1:1:1
+ */
+void
+WriteBlock (int *store, int *p_out_vpos, int *p_out_hpos,
+ unsigned char *p_out_buf)
+{
+ int voffs, hoffs;
+
+ /*
+ * Get vertical offsets
+ */
+ voffs = *p_out_vpos * DCTSIZE;
+ hoffs = *p_out_hpos * DCTSIZE;
+
+ /*
+ * Write block
+ */
+ WriteOneBlock (store,
+ p_out_buf,
+ p_jinfo_image_width, p_jinfo_image_height, voffs, hoffs);
+
+ /*
+ * Add positions
+ */
+ (*p_out_hpos)++;
+ (*p_out_vpos)++;
+
+ if (*p_out_hpos < p_jinfo_MCUWidth)
+ {
+ (*p_out_vpos)--;
+ }
+ else
+ {
+ *p_out_hpos = 0; /* If at end of image (width) */
+ }
+}
+
+/*
+ * 4:1:1
+ */
+void
+Write4Blocks (int *store1, int *store2, int *store3, int *store4,
+ int *p_out_vpos, int *p_out_hpos, unsigned char *p_out_buf)
+{
+ int voffs, hoffs;
+
+ /*
+ * OX
+ * XX
+ */
+ voffs = *p_out_vpos * DCTSIZE;
+ hoffs = *p_out_hpos * DCTSIZE;
+ WriteOneBlock (store1, p_out_buf,
+ p_jinfo_image_width, p_jinfo_image_height, voffs, hoffs);
+
+ /*
+ * XO
+ * XX
+ */
+ hoffs += DCTSIZE;
+ WriteOneBlock (store2, p_out_buf,
+ p_jinfo_image_width, p_jinfo_image_height, voffs, hoffs);
+
+ /*
+ * XX
+ * OX
+ */
+ voffs += DCTSIZE;
+ hoffs -= DCTSIZE;
+ WriteOneBlock (store3, p_out_buf,
+ p_jinfo_image_width, p_jinfo_image_height, voffs, hoffs);
+
+
+ /*
+ * XX
+ * XO
+ */
+ hoffs += DCTSIZE;
+ WriteOneBlock (store4,
+ p_out_buf, p_jinfo_image_width, p_jinfo_image_height,
+ voffs, hoffs);
+
+ /*
+ * Add positions
+ */
+ *p_out_hpos = *p_out_hpos + 2;
+ *p_out_vpos = *p_out_vpos + 2;
+
+
+ if (*p_out_hpos < p_jinfo_MCUWidth)
+ {
+ *p_out_vpos = *p_out_vpos - 2;
+ }
+ else
+ {
+ *p_out_hpos = 0; /* If at end of image (width) */
+ }
+}
+
+
+/*
+ * Transform from Yuv into RGB
+ */
+void
+YuvToRgb (int p, int *y_buf, int *u_buf, int *v_buf)
+{
+ int r, g, b;
+ int y, u, v;
+ int i;
+
+ for (i = 0; i < DCTSIZE2; i++)
+ {
+ y = y_buf[i];
+ u = u_buf[i] - 128;
+ v = v_buf[i] - 128;
+
+ r = (y * 256 + v * 359 + 128) >> 8;
+ g = (y * 256 - u * 88 - v * 182 + 128) >> 8;
+ b = (y * 256 + u * 454 + 128) >> 8;
+
+ if (r < 0)
+ r = 0;
+ else if (r > 255)
+ r = 255;
+
+ if (g < 0)
+ g = 0;
+ else if (g > 255)
+ g = 255;
+
+ if (b < 0)
+ b = 0;
+ else if (b > 255)
+ b = 255;
+
+ rgb_buf[p][0][i] = r;
+ rgb_buf[p][1][i] = g;
+ rgb_buf[p][2][i] = b;
+
+ }
+}
+
+
+/*
+ * Decode one block
+ */
+void
+decode_block (int comp_no, int *out_buf, int *HuffBuff)
+{
+ int QuantBuff[DCTSIZE2];
+ unsigned int *p_quant_tbl;
+
+ DecodeHuffMCU (HuffBuff, comp_no);
+
+ IZigzagMatrix (HuffBuff, QuantBuff);
+
+ p_quant_tbl =
+ &p_jinfo_quant_tbl_quantval[(int)p_jinfo_comps_info_quant_tbl_no[comp_no]][DCTSIZE2];
+ IQuantize (QuantBuff, p_quant_tbl);
+
+ ChenIDct (QuantBuff, out_buf);
+
+ PostshiftIDctMatrix (out_buf, IDCT_SHIFT);
+
+ BoundIDctMatrix (out_buf, IDCT_BOUNT);
+
+}
+
+
+void
+decode_start (int *out_data_image_width, int *out_data_image_height,
+ int *out_data_comp_vpos, int *out_data_comp_hpos)
+{
+ int i;
+ int CurrentMCU = 0;
+ int HuffBuff[NUM_COMPONENT][DCTSIZE2];
+ int IDCTBuff[6][DCTSIZE2];
+
+ /* Read buffer */
+ CurHuffReadBuf = p_jinfo_jpeg_data;
+
+ /*
+ * Initial value of DC element is 0
+ */
+ for (i = 0; i < NUM_COMPONENT; i++)
+ {
+ HuffBuff[i][0] = 0;
+ }
+
+ /*
+ * Set the size of image to output buffer
+ */
+ *out_data_image_width = p_jinfo_image_width;
+ *out_data_image_height = p_jinfo_image_height;
+
+ /*
+ * Initialize output buffer
+ */
+ for (i = 0; i < RGB_NUM; i++)
+ {
+ out_data_comp_vpos[i] = 0;
+ out_data_comp_hpos[i] = 0;
+ }
+
+
+ if (p_jinfo_smp_fact == SF1_1_1)
+ {
+ printf ("Decode 1:1:1 NumMCU = %d\n", p_jinfo_NumMCU);
+
+ /*
+ * 1_1_1
+ */
+ while (CurrentMCU < p_jinfo_NumMCU)
+ {
+
+ for (i = 0; i < NUM_COMPONENT; i++)
+ {
+ decode_block (i, IDCTBuff[i], HuffBuff[i]);
+ }
+
+
+ YuvToRgb (0, IDCTBuff[0], IDCTBuff[1], IDCTBuff[2]);
+ /*
+ * Write
+ */
+ for (i = 0; i < RGB_NUM; i++)
+ {
+ WriteBlock (&rgb_buf[0][i][0],
+ &out_data_comp_vpos[i],
+ &out_data_comp_hpos[i], &OutData_comp_buf[i][0]);
+ }
+ CurrentMCU++;
+ }
+
+ }
+ else
+ {
+ printf ("Decode 4:1:1 NumMCU = %d\n", p_jinfo_NumMCU);
+ /*
+ * 4_1_1
+ */
+ while (CurrentMCU < p_jinfo_NumMCU)
+ {
+ /*
+ * Decode Y element
+ * Decoding Y, U and V elements should be sequentially conducted for the use of Huffman table
+ */
+
+ for (i = 0; i < 4; i++)
+ {
+ decode_block (0, IDCTBuff[i], HuffBuff[0]);
+ }
+
+ /* Decode U */
+ decode_block (1, IDCTBuff[4], HuffBuff[1]);
+
+ /* Decode V */
+ decode_block (2, IDCTBuff[5], HuffBuff[2]);
+
+
+ /* Transform from Yuv into RGB */
+
+ for (i = 0; i < 4; i++)
+ {
+ YuvToRgb (i, IDCTBuff[i], IDCTBuff[4], IDCTBuff[5]);
+ }
+
+
+ for (i = 0; i < RGB_NUM; i++)
+ {
+ Write4Blocks (&rgb_buf[0][i][0],
+ &rgb_buf[1][i][0],
+ &rgb_buf[2][i][0],
+ &rgb_buf[3][i][0],
+ &out_data_comp_vpos[i],
+ &out_data_comp_hpos[i], &OutData_comp_buf[i][0]);
+ }
+
+
+ CurrentMCU += 4;
+ }
+ }
+}