1 /* -*-C-*-
2 ******************************************************************************
3 *
4 * File: process.c
5 * RCS: $Header: /ImageMagick/delegates/fpx/jpeg/process.c,v 1.3 2000/12/23 22:37:48 bfriesen Exp $
6 * Description: Default subsampling/YCbCr routines for the HP JPEG Encoder.
7 * Author: Kirt Winter
8 * Created: Fri Mar 1 09:04:22 1995
9 * Initial Source Release: Thursday, March 7 1996
10 * Language: C
11 * Package: Hewlett-Packard JPEG Encoder/Decoder
12 *
13 * Copyright (c) 1999 Digital Imaging Group, Inc.
14 * For conditions of distribution and use, see copyright notice
15 * in Flashpix.h
16 *
17 ******************************************************************************
18 */
19 #include <stdlib.h>
20 #include "jpegconf.h"
21 #include "fpxmem.h"
22 #include "process.h"
23
24 #include "ejpeg.h" /* CHG_JPEG_MEM_FIX - added this to get error code */
25
26 /*
27 ** This routine strips color information from an opponent color stream. Upon completion of
28 ** its assigned duty, the destination buffer will be filled with LLLLabLLLLabLLLLab,
29 ** assuming of course that it was originally LabLabLabLabLab. Alpha channel is
30 ** supported (as the last channel in the set), but is not subsampled.
31 **
32 */
33 int
SubSample411(const unsigned char * src,unsigned char * dst,int tileSize,int bpp)34 SubSample411(const unsigned char *src, unsigned char *dst, int tileSize, int bpp)
35 {
36 int x, y, blocks, acc, lineOffset;
37 unsigned char *dstPtr = dst;
38 const unsigned char *p1, *p2, *p3, *p4;
39
40 blocks = tileSize / 2;
41 lineOffset = tileSize * bpp;
42 for(x = 0; x < blocks; x++)
43 {
44 for(y = 0; y < blocks; y++)
45 {
46 p1 = src;
47 p2 = p1 + bpp;
48 p3 = p1 + lineOffset;
49 p4 = p3 + bpp;
50
51 *dstPtr++ = *p1++;
52 *dstPtr++ = *p2++;
53 *dstPtr++ = *p3++;
54 *dstPtr++ = *p4++;
55 /* p1 - p4 now point to first chroma sample
56 ** We take the average chroma of the 4 points in the quadrant
57 ** and place that in the destination buffer.
58 */
59 acc = *p1++ + *p2++ + *p3++ + *p4++;
60 *dstPtr++ = (unsigned char) ((acc + 2) >> 2);
61
62 /* p1 - p4 now point to second chroma sample
63 ** now, we repeat the above process for second chroma
64 */
65 acc = *p1++ + *p2++ + *p3++ + *p4++;
66 *dstPtr++ = (unsigned char) ((acc + 2) >> 2);
67
68 /* Alpha channel, if it exists, is never subsampled */
69 if (bpp == 4)
70 {
71 *dstPtr++ = *p1++;
72 *dstPtr++ = *p2++;
73 *dstPtr++ = *p3++;
74 *dstPtr++ = *p4++;
75 }
76
77 src += 2*bpp; /* skip over one triplet (quadlet?) and point to
78 the next quadrant */
79 }
80 src += lineOffset;
81 }
82 return(0);
83 }
84
85 int
SubSample422(const unsigned char * src,unsigned char * dst,int tileSize,int bpp)86 SubSample422(const unsigned char *src, unsigned char *dst, int tileSize, int bpp)
87 {
88 int x, y, blocks, acc;
89 unsigned char *dstPtr = dst;
90 const unsigned char *p1, *p2;
91
92 blocks = tileSize / 2;
93 for(x = 0; x < tileSize; x++)
94 {
95 for(y = 0; y < blocks; y++)
96 {
97 p1 = src;
98 p2 = p1 + bpp;
99
100 *dstPtr++ = *p1++;
101 *dstPtr++ = *p2++;
102
103 /* p1,p2 now point to first chroma sample
104 ** here we take the average chroma of the two points
105 ** and place that in the destination buffer
106 */
107 acc = *p1++ + *p2++;
108 *dstPtr++ = (unsigned char) ((acc + 1) >> 1);
109
110 /* p1,p4 now point to second chroma sample
111 ** so, we repeat the above process for second chroma
112 */
113 acc = *p1++ + *p2++;
114 *dstPtr++ = (unsigned char) ((acc + 1) >> 1);
115
116 /* If an alpha channel, it is never subsampled.*/
117 if(bpp == 4)
118 {
119 *dstPtr++ = *p1++;
120 *dstPtr++ = *p2++;
121 }
122
123 src += 2*bpp; /* skip over one triplet (quadlet?) and point to
124 the next quadrant. */
125 }
126 }
127 return(0);
128 }
129
130 /*
131 ** This routine does an RGB to YCbCr conversion. After complettion, the
132 ** destination buffer will be filled with YCbCrYCbCrYCbCrYCbCrYCbCr,
133 ** assuming of course that it was originally RGBRGBRGBRGBRGB.
134 ** The routine also handles RGBa data, and in that situation, you'll
135 ** get YCbCraYCbCraYCbCra...
136 **
137 */
138 int
RGBtoYCrCb(const unsigned char * src,unsigned char * dst,int tilerow,int bpp)139 RGBtoYCrCb(const unsigned char *src, unsigned char *dst, int tilerow, int bpp)
140 {
141 int x;
142 int tilesize = tilerow * tilerow * bpp;
143 unsigned char inpR,inpG,inpB;
144 long yo, cr, cb;
145 long A1, A2, A3, A4;
146 float F1, F2;
147
148 /*
149 ** the rotation routine is out of section 2.4.4.2
150 ** of Pennebaker/Mitchell book.
151 ** r,g,b values of 0-255 are mapped to 0-1 range, and then
152 ** all values are left shifted by 26 bits.
153 */
154 #if 0
155 /* Pennebaker book's numbers: */
156 A1 = 78952;
157 A2 = 157903;
158 A3 = 26317;
159 A4 = 33554432;
160 F1 = (float)1.6;
161 #endif
162
163 #if 1
164 /* IJG's numbers: */
165 A1 = 78381;
166 A2 = 153879;
167 A3 = 29884;
168 A4 = 33554432;
169 F1 = (float)1.402;
170 F2 = (float)1.772;
171 #endif
172
173 if (bpp==3) {
174 for(x = 0; x < tilesize; x+=bpp)
175 {
176 yo = A1*(long)(src[x]) + A2*(long)(src[x+1]) + A3*(long)(src[x+2]);
177
178 /* old (Pennebaker book's) way:
179 cb = (long)((((src[x+2])<<18) - yo) >> 1) + A4;
180 cr = (long)((((src[x])<<18) - yo) / F1) + A4;
181 */
182 cb = (long)((((src[x+2])<<18) - yo) / F2) + A4;
183 cr = (long)((((src[x])<<18) - yo) / F1) + A4;
184
185 dst[x] = (unsigned char)(yo >> 18);
186 dst[x+1] = (unsigned char)(cb >> 18);
187 dst[x+2] = (unsigned char)(cr >> 18);
188 }
189 } else { /* bpp = 4 */
190 for(x = 0; x < tilesize; x+=bpp)
191 {
192 inpR= (unsigned char) (255-src[x]);
193 inpG= (unsigned char) (255-src[x+1]);
194 inpB= (unsigned char) (255-src[x+2]);
195 yo = A1*(long)(inpR) + A2*(long)(inpG) + A3*(long)(inpB);
196
197 /* old (Pennebaker book's) way:
198 cb = (long)((((inpB)<<18) - yo) >> 1) + A4;
199 cr = (long)((((inpR)<<18) - yo) / F1) + A4;
200 */
201 cb = (long)((((inpB)<<18) - yo) / F2) + A4;
202 cr = (long)((((inpR)<<18) - yo) / F1) + A4;
203 dst[x] = (unsigned char)(yo >> 18);
204 dst[x+1] = (unsigned char)(cb >> 18);
205 dst[x+2] = (unsigned char)(cr >> 18);
206 dst[x+3] = src[x+3];
207 }
208 }
209 return(0);
210
211 } /* RGBtoYCrCb() */
212
213
214 /*
215 ** This routine does an RGB to YCbCr conversion, then strips color information. After
216 ** completion, the destination buffer will be filled with YYYYCbCrYYYYCbCrYYYYCbCr,
217 ** assuming of course that it was originally RGBRGBRGBRGBRGB. Note that the routine does
218 ** support conversion in place (i.e. src and dst can be the same buffer).
219 */
220 int
RGBtoYCrCb_SubSample411(const unsigned char * src,unsigned char * dst,int tilerow,int bpp)221 RGBtoYCrCb_SubSample411(const unsigned char *src, unsigned char *dst, int tilerow, int bpp)
222 {
223 int x, y, z, blocks, lineOffset;
224 unsigned char *dstPtr = dst;
225 const unsigned char *p[4], *q[4];
226 unsigned char inpR,inpG,inpB;
227 long yo[4], cr, cb;
228 long A1, A2, A3, A4;
229 float F1, F2;
230
231 blocks = tilerow / 2;
232 lineOffset = tilerow * bpp;
233
234 #if 0
235 /* Pennebaker book's numbers */
236 A1 = 78952;
237 A2 = 157903;
238 A3 = 26317;
239 A4 = 33554432;
240 F1 = 1.6;
241 F2 = 2.0; /* this can be a right shift */
242 #endif
243
244 #if 1
245 /* IJG's numbers: */
246 A1 = 78381;
247 A2 = 153879;
248 A3 = 29884;
249 A4 = 33554432;
250 F1 = (float)1.402;
251 F2 = (float)1.772;
252 #endif
253
254 if (bpp == 3)
255 { /* 3 channel */
256 for(x = 0; x < blocks; x++)
257 {
258 for(y = 0; y < blocks; y++)
259 {
260 p[0] = src;
261 p[1] = p[0] + bpp;
262 p[2] = p[0] + lineOffset;
263 p[3] = p[2] + bpp;
264 cb = 0;
265 cr = 0;
266 for(z = 0; z < 4; z++)
267 {
268 yo[z] = A1*(long)*(p[z]) + A2*(long)*(p[z]+1) + A3*(long)*(p[z]+2);
269
270 /* old (pink's book) way:
271 cb += ((((*(p[z]+2)<<18) - yo[z]) >> 1) + A4) >> 2;
272 cr += ((long)(((*(p[z])<<18) - yo[z]) / F1) + A4) >> 2;
273 */
274 cb += ((long)((((*(p[z]+2)<<18) - yo[z]) / F2) + A4) >> 2);
275 cr += ((long)((((*(p[z])<<18) - yo[z]) / F1) + A4) >> 2);
276
277 *dstPtr++ = (unsigned char)(yo[z] >> 18);
278 }
279
280 /* now it's time to write out a "u" and a "v" */
281 *dstPtr++ = (unsigned char)(cb >> 18);
282 *dstPtr++ = (unsigned char)(cr >> 18);
283
284 src += bpp*2; /* skip over one triplet and point to the next quadrant */
285 } /* for y */
286
287 src += lineOffset;
288 } /* for x */
289
290 }
291 else if (bpp == 4)
292 { /* 4 channel */
293 for(x = 0; x < blocks; x++)
294 {
295 for(y = 0; y < blocks; y++)
296 {
297 p[0] = src;
298 p[1] = p[0] + bpp;
299 p[2] = p[0] + lineOffset;
300 p[3] = p[2] + bpp;
301
302 q[0]=p[0]+3; /* used for alpha channel */
303 q[1]=p[1]+3;
304 q[2]=p[2]+3;
305 q[3]=p[3]+3;
306 cb = 0;
307 cr = 0;
308 for(z = 0; z < 4; z++)
309 {
310 inpR = (unsigned char) (255-*p[z]);
311 inpG = (unsigned char) (255-*(p[z]+1));
312 inpB = (unsigned char) (255-*(p[z]+2));
313 yo[z] = A1*(long)inpR + A2*(long)inpG + A3*(long)inpB;
314
315 /* old (Pennebaker book's) way:
316 cb += ((((inpB<<18) - yo[z]) >> 1) + A4) >> 2;
317 cr += ((long)(((inpR<<18) - yo[z]) / F1) + A4) >> 2;
318 */
319 cb += ((long)((((inpB<<18) - yo[z]) / F2) + A4) >> 2);
320 cr += ((long)((((inpR<<18) - yo[z]) / F1) + A4) >> 2);
321
322 *dstPtr++ = (unsigned char)(yo[z] >> 18);
323 }
324
325 /* now it's time to write out a "u" and a "v" */
326 *dstPtr++ = (unsigned char)(cb >> 18);
327 *dstPtr++ = (unsigned char)(cr >> 18);
328
329 /* write out the Alpha channel */
330 *dstPtr++ = *q[0];
331 *dstPtr++ = *q[1];
332 *dstPtr++ = *q[2];
333 *dstPtr++ = *q[3];
334
335 src += bpp*2; /* skip over one triplet and point to the next quadrant */
336 }
337 src += lineOffset;
338 }
339 }
340 return(0);
341
342 } /* RGBtoYCrCb_SubSample411() */
343
344
345 /*
346 ** This routine does an RGB to YCbCr conversion, then strips color information.
347 ** This is not done particularly efficiently, but it's important that it get done
348 ** correctly and on time. So, rather than write an integrated routine like the 411
349 ** subsampling, the individual pieces are called, simplifying coding and testing.
350 */
351 int
RGBtoYCrCb_SubSample422(const unsigned char * src,unsigned char * dst,int tileSize,int bpp)352 RGBtoYCrCb_SubSample422(const unsigned char *src, unsigned char *dst, int tileSize, int bpp)
353 {
354 unsigned char *dst0;
355 int error;
356
357 dst0 = (unsigned char *)FPX_malloc((size_t)(tileSize * tileSize * bpp));
358 if(dst0 == NULL) /* CHG_JPEG_MEM_FIX - added check */
359 return EJPEG_ERROR_MEM;
360
361 RGBtoYCrCb(src, dst0, tileSize, bpp);
362 error = SubSample422(dst0, dst, tileSize, bpp);
363
364 FPX_free(dst0);
365
366 return error;
367
368 } /* RGBtoYCrCb_SubSample422() */
369