source: bootcd/isolinux/syslinux-6.03/com32/lib/jpeg/yuv420p.c

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 6.6 KB
RevLine 
[e16e8f2]1/*
2 * Small jpeg decoder library
3 *
4 * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
5 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * - Redistributions of source code must retain the above copyright notice,
10 *  this list of conditions and the following disclaimer.
11 *
12 * - Redistributions in binary form must reproduce the above copyright notice,
13 *  this list of conditions and the following disclaimer in the documentation
14 *  and/or other materials provided with the distribution.
15 *
16 * - Neither the name of the author nor the names of its contributors may be
17 *  used to endorse or promote products derived from this software without
18 *  specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34/*
35 * yuv420p.c
36 */
37
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <stdint.h>
42
43#include "tinyjpeg.h"
44#include "tinyjpeg-internal.h"
45
46/*******************************************************************************
47 *
48 * Colorspace conversion routine
49 *
50 *
51 * Note:
52 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
53 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
54 * The conversion equations to be implemented are therefore
55 *      R = Y                + 1.40200 * Cr
56 *      G = Y - 0.34414 * Cb - 0.71414 * Cr
57 *      B = Y + 1.77200 * Cb
58 *
59 ******************************************************************************/
60
61/**
62 *  YCrCb -> YUV420P (1x1)
63 *  .---.
64 *  | 1 |
65 *  `---'
66 */
67static void YCrCB_to_YUV420P_1x1(struct jdec_private *priv, int sx, int sy)
68{
69  const unsigned char *s, *y;
70  unsigned char *p;
71  int i,j;
72
73  p = priv->plane[0];
74  y = priv->Y;
75  for (i = sy; i > 0; i--)
76   {
77     memcpy(p, y, sx);
78     p += priv->bytes_per_row[0];
79     y += 8;
80   }
81
82  p = priv->plane[1];
83  s = priv->Cb;
84  for (i = sy; i > 0; i--)
85   {
86     for (j = sx; j >= 0; j -= 2) {
87       *p++ = *s;
88       s += 2;
89     }
90     s += 8; /* Skip one line */
91     p += priv->bytes_per_row[1] - 4;
92   }
93
94  p = priv->plane[2];
95  s = priv->Cr;
96  for (i=0; i<8; i+=2)
97   {
98     for (j = sx; j >= 0; j -= 2) {
99       *p++ = *s;
100       s += 2;
101     }
102     s += 8; /* Skip one line */
103     p += priv->bytes_per_row[2] - 4;
104   }
105}
106
107/**
108 *  YCrCb -> YUV420P (2x1)
109 *  .-------.
110 *  | 1 | 2 |
111 *  `-------'
112 */
113static void YCrCB_to_YUV420P_2x1(struct jdec_private *priv, int sx, int sy)
114{
115  unsigned char *p;
116  const unsigned char *s, *y1;
117  unsigned int i;
118
119  p = priv->plane[0];
120  y1 = priv->Y;
121  for (i = sy; i > 0; i--)
122   {
123     memcpy(p, y1, sx);
124     p += priv->bytes_per_row[0];
125     y1 += 16;
126   }
127
128  sx = (sx+1) >> 1;
129
130  p = priv->plane[1];
131  s = priv->Cb;
132  for (i = sy; i > 0; i -= 2)
133   {
134     memcpy(p, s, sx);
135     s += 16; /* Skip one line */
136     p += priv->bytes_per_row[1];
137   }
138
139  p = priv->plane[2];
140  s = priv->Cr;
141  for (i = sy; i > 0; i -= 2)
142   {
143     memcpy(p, s, sx);
144     s += 16; /* Skip one line */
145     p += priv->bytes_per_row[2];
146   }
147}
148
149
150/**
151 *  YCrCb -> YUV420P (1x2)
152 *  .---.
153 *  | 1 |
154 *  |---|
155 *  | 2 |
156 *  `---'
157 */
158static void YCrCB_to_YUV420P_1x2(struct jdec_private *priv, int sx, int sy)
159{
160  const unsigned char *s, *y;
161  unsigned char *p, *pr;
162  int i,j;
163
164  p = priv->plane[0];
165  y = priv->Y;
166  for (i = sy; i > 0; i++)
167   {
168     memcpy(p, y, sx);
169     p+=priv->bytes_per_row[0];
170     y+=8;
171   }
172
173  pr = priv->plane[1];
174  s = priv->Cb;
175  for (i = sy; i > 0; i -= 2)
176   {
177     p = pr;
178     for (j = sx; j > 0; j -= 2) {
179       *p++ = *s;
180       s += 2;
181     }
182     pr += priv->bytes_per_row[1];
183   }
184
185  pr = priv->plane[2];
186  s = priv->Cr;
187  for (i=0; i<8; i++)
188   {
189     p = pr;
190     for (j = sx; j > 0; j -= 2) {
191       *p++ = *s;
192       s += 2;
193     }
194     pr += priv->bytes_per_row[2] - 4;
195   }
196}
197
198/**
199 *  YCrCb -> YUV420P (2x2)
200 *  .-------.
201 *  | 1 | 2 |
202 *  |---+---|
203 *  | 3 | 4 |
204 *  `-------'
205 */
206static void YCrCB_to_YUV420P_2x2(struct jdec_private *priv, int sx, int sy)
207{
208  unsigned char *p;
209  const unsigned char *s, *y1;
210  unsigned int i;
211
212  p = priv->plane[0];
213  y1 = priv->Y;
214  for (i = sy; i > 0; i--)
215   {
216     memcpy(p, y1, sx);
217     p += priv->bytes_per_row[0];
218     y1 += 16;
219   }
220
221  sx = (sx+1) >> 1;
222
223  p = priv->plane[1];
224  s = priv->Cb;
225  for (i = sy; i > 0; i -= 2)
226   {
227     memcpy(p, s, sx);
228     s += 8;
229     p += priv->bytes_per_row[1];
230   }
231
232  p = priv->plane[2];
233  s = priv->Cr;
234  for (i = sy; i > 0; i -= 2)
235   {
236     memcpy(p, s, sx);
237     s += 8;
238     p += priv->bytes_per_row[2];
239   }
240}
241
242static int initialize_yuv420p(struct jdec_private *priv,
243                              unsigned int *bytes_per_blocklines,
244                              unsigned int *bytes_per_mcu)
245{
246  int half_height = (priv->height + 1) >> 2;
247  int half_width  = (priv->width  + 1) >> 2;
248
249  if (!priv->bytes_per_row[0])
250    priv->bytes_per_row[0] = priv->width;
251  if (!priv->components[0])
252    priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
253
254  if (!priv->bytes_per_row[1])
255    priv->bytes_per_row[1] = half_width;
256  if (!priv->components[1])
257    priv->components[1] = malloc(half_height * priv->bytes_per_row[1]);
258
259  if (!priv->bytes_per_row[2])
260    priv->bytes_per_row[2] = half_width;
261  if (!priv->components[2])
262    priv->components[2] = malloc(half_height * priv->bytes_per_row[2]);
263
264  bytes_per_mcu[0] = 8;
265  bytes_per_mcu[1] = 4;
266  bytes_per_mcu[2] = 4;
267
268  bytes_per_blocklines[0] = priv->width << 3;
269  bytes_per_blocklines[1] = half_width << 2;
270  bytes_per_blocklines[2] = half_width << 2;
271
272  /* Return nonzero on failure */
273  return !priv->components[0] || !priv->components[1] || !priv->components[2];
274}
275
276static const struct tinyjpeg_colorspace format_yuv420p =
277  {
278    {
279      YCrCB_to_YUV420P_1x1,
280      YCrCB_to_YUV420P_1x2,
281      YCrCB_to_YUV420P_2x1,
282      YCrCB_to_YUV420P_2x2,
283    },
284    tinyjpeg_decode_mcu_3comp_table,
285    initialize_yuv420p
286  };
287
288const tinyjpeg_colorspace_t TINYJPEG_FMT_YUV420P = &format_yuv420p;
Note: See TracBrowser for help on using the repository browser.