blob: cd00a21892fb9f1f9a8b67ac4e6ba43b109a06bb [file] [log] [blame]
hbono@chromium.org98626972011-08-03 03:13:08 +00001/*
Chris Blumecca8c4d2019-03-01 01:09:50 -08002 * Copyright (C)2009-2014, 2017-2018 D. R. Commander. All Rights Reserved.
hbono@chromium.org98626972011-08-03 03:13:08 +00003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * - Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * - Neither the name of the libjpeg-turbo Project nor the names of its
13 * contributors may be used to endorse or promote products derived from this
14 * software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * This program tests the various code paths in the TurboJPEG C Wrapper
31 */
32
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <errno.h>
Chris Blumecca8c4d2019-03-01 01:09:50 -080037#include "tjutil.h"
38#include "turbojpeg.h"
39#include "md5/md5.h"
40#include "cmyk.h"
hbono@chromium.org98626972011-08-03 03:13:08 +000041#ifdef _WIN32
Chris Blumecca8c4d2019-03-01 01:09:50 -080042#include <time.h>
43#define random() rand()
44#else
45#include <unistd.h>
hbono@chromium.org98626972011-08-03 03:13:08 +000046#endif
47
48
Jonathan Wright6cb95b82020-06-11 16:10:15 +010049#ifndef GTEST
50static void usage(char *progName)
hbono@chromium.org98626972011-08-03 03:13:08 +000051{
Chris Blumecca8c4d2019-03-01 01:09:50 -080052 printf("\nUSAGE: %s [options]\n\n", progName);
53 printf("Options:\n");
54 printf("-yuv = test YUV encoding/decoding support\n");
55 printf("-noyuvpad = do not pad each line of each Y, U, and V plane to the nearest\n");
56 printf(" 4-byte boundary\n");
57 printf("-alloc = test automatic buffer allocation\n");
58 printf("-bmp = tjLoadImage()/tjSaveImage() unit test\n\n");
59 exit(1);
hbono@chromium.org98626972011-08-03 03:13:08 +000060}
Jonathan Wright6cb95b82020-06-11 16:10:15 +010061#endif
hbono@chromium.org98626972011-08-03 03:13:08 +000062
63
Chris Blumecca8c4d2019-03-01 01:09:50 -080064#define _throwtj() { \
Jonathan Wrighta145af12020-06-11 23:22:17 +010065 fprintf(stderr, "TurboJPEG ERROR:\n%s\n", tjGetErrorStr()); \
Chris Blumecca8c4d2019-03-01 01:09:50 -080066 bailout() \
67}
68#define _tj(f) { if ((f) == -1) _throwtj(); }
Jonathan Wrighta145af12020-06-11 23:22:17 +010069#define _throw(m) { fprintf(stderr, "ERROR: %s\n", m); bailout() }
Chris Blumecca8c4d2019-03-01 01:09:50 -080070#define _throwmd5(filename, md5sum, ref) { \
Jonathan Wrighta145af12020-06-11 23:22:17 +010071 fprintf(stderr, "\n%s has an MD5 sum of %s.\n Should be %s.\n", filename, \
72 md5sum, ref); \
Chris Blumecca8c4d2019-03-01 01:09:50 -080073 bailout() \
74}
hbono@chromium.org98626972011-08-03 03:13:08 +000075
Jonathan Wright6cb95b82020-06-11 16:10:15 +010076static const char *subNameLong[TJ_NUMSAMP] = {
Chris Blumecca8c4d2019-03-01 01:09:50 -080077 "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1"
hbono@chromium.org98626972011-08-03 03:13:08 +000078};
Jonathan Wright6cb95b82020-06-11 16:10:15 +010079static const char *subName[TJ_NUMSAMP] = {
Chris Blumecca8c4d2019-03-01 01:09:50 -080080 "444", "422", "420", "GRAY", "440", "411"
hbono@chromium.org98626972011-08-03 03:13:08 +000081};
82
Chris Blumecca8c4d2019-03-01 01:09:50 -080083const char *pixFormatStr[TJ_NUMPF] = {
84 "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale",
85 "RGBA", "BGRA", "ABGR", "ARGB", "CMYK"
86};
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000087
Jonathan Wright6cb95b82020-06-11 16:10:15 +010088static const int _3byteFormats[] = { TJPF_RGB, TJPF_BGR };
89static const int _4byteFormats[] = {
Chris Blumecca8c4d2019-03-01 01:09:50 -080090 TJPF_RGBX, TJPF_BGRX, TJPF_XBGR, TJPF_XRGB, TJPF_CMYK
91};
Jonathan Wright6cb95b82020-06-11 16:10:15 +010092static const int _onlyGray[] = { TJPF_GRAY };
93static const int _onlyRGB[] = { TJPF_RGB };
hbono@chromium.org98626972011-08-03 03:13:08 +000094
Jonathan Wright6cb95b82020-06-11 16:10:15 +010095static int doYUV = 0, alloc = 0, pad = 4;
hbono@chromium.org98626972011-08-03 03:13:08 +000096
Jonathan Wright6cb95b82020-06-11 16:10:15 +010097static int exitStatus = 0;
Chris Blumecca8c4d2019-03-01 01:09:50 -080098#define bailout() { exitStatus = -1; goto bailout; }
hbono@chromium.org98626972011-08-03 03:13:08 +000099
100
Jonathan Wright6cb95b82020-06-11 16:10:15 +0100101static void initBuf(unsigned char *buf, int w, int h, int pf, int flags)
hbono@chromium.org98626972011-08-03 03:13:08 +0000102{
Chris Blumecca8c4d2019-03-01 01:09:50 -0800103 int roffset = tjRedOffset[pf];
104 int goffset = tjGreenOffset[pf];
105 int boffset = tjBlueOffset[pf];
106 int ps = tjPixelSize[pf];
107 int index, row, col, halfway = 16;
hbono@chromium.org98626972011-08-03 03:13:08 +0000108
Chris Blumecca8c4d2019-03-01 01:09:50 -0800109 if (pf == TJPF_GRAY) {
110 memset(buf, 0, w * h * ps);
111 for (row = 0; row < h; row++) {
112 for (col = 0; col < w; col++) {
113 if (flags & TJFLAG_BOTTOMUP) index = (h - row - 1) * w + col;
114 else index = row * w + col;
115 if (((row / 8) + (col / 8)) % 2 == 0)
116 buf[index] = (row < halfway) ? 255 : 0;
117 else buf[index] = (row < halfway) ? 76 : 226;
118 }
119 }
120 } else if (pf == TJPF_CMYK) {
121 memset(buf, 255, w * h * ps);
122 for (row = 0; row < h; row++) {
123 for (col = 0; col < w; col++) {
124 if (flags & TJFLAG_BOTTOMUP) index = (h - row - 1) * w + col;
125 else index = row * w + col;
126 if (((row / 8) + (col / 8)) % 2 == 0) {
127 if (row >= halfway) buf[index * ps + 3] = 0;
128 } else {
129 buf[index * ps + 2] = 0;
130 if (row < halfway) buf[index * ps + 1] = 0;
131 }
132 }
133 }
134 } else {
135 memset(buf, 0, w * h * ps);
136 for (row = 0; row < h; row++) {
137 for (col = 0; col < w; col++) {
138 if (flags & TJFLAG_BOTTOMUP) index = (h - row - 1) * w + col;
139 else index = row * w + col;
140 if (((row / 8) + (col / 8)) % 2 == 0) {
141 if (row < halfway) {
142 buf[index * ps + roffset] = 255;
143 buf[index * ps + goffset] = 255;
144 buf[index * ps + boffset] = 255;
145 }
146 } else {
147 buf[index * ps + roffset] = 255;
148 if (row >= halfway) buf[index * ps + goffset] = 255;
149 }
150 }
151 }
152 }
hbono@chromium.org98626972011-08-03 03:13:08 +0000153}
154
155
156#define checkval(v, cv) { \
Chris Blumecca8c4d2019-03-01 01:09:50 -0800157 if (v < cv - 1 || v > cv + 1) { \
Jonathan Wrighta145af12020-06-11 23:22:17 +0100158 fprintf(stderr, "\nComp. %s at %d,%d should be %d, not %d\n", #v, row, \
159 col, cv, v); \
Chris Blumecca8c4d2019-03-01 01:09:50 -0800160 retval = 0; exitStatus = -1; goto bailout; \
161 } \
162}
hbono@chromium.org98626972011-08-03 03:13:08 +0000163
164#define checkval0(v) { \
Chris Blumecca8c4d2019-03-01 01:09:50 -0800165 if (v > 1) { \
Jonathan Wrighta145af12020-06-11 23:22:17 +0100166 fprintf(stderr, "\nComp. %s at %d,%d should be 0, not %d\n", #v, row, \
167 col, v); \
Chris Blumecca8c4d2019-03-01 01:09:50 -0800168 retval = 0; exitStatus = -1; goto bailout; \
169 } \
170}
hbono@chromium.org98626972011-08-03 03:13:08 +0000171
172#define checkval255(v) { \
Chris Blumecca8c4d2019-03-01 01:09:50 -0800173 if (v < 254) { \
Jonathan Wrighta145af12020-06-11 23:22:17 +0100174 fprintf(stderr, "\nComp. %s at %d,%d should be 255, not %d\n", #v, row, \
175 col, v); \
Chris Blumecca8c4d2019-03-01 01:09:50 -0800176 retval = 0; exitStatus = -1; goto bailout; \
177 } \
hbono@chromium.org98626972011-08-03 03:13:08 +0000178}
179
180
Jonathan Wright6cb95b82020-06-11 16:10:15 +0100181static int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp,
182 tjscalingfactor sf, int flags)
Chris Blumecca8c4d2019-03-01 01:09:50 -0800183{
184 int roffset = tjRedOffset[pf];
185 int goffset = tjGreenOffset[pf];
186 int boffset = tjBlueOffset[pf];
187 int aoffset = tjAlphaOffset[pf];
188 int ps = tjPixelSize[pf];
189 int index, row, col, retval = 1;
190 int halfway = 16 * sf.num / sf.denom;
191 int blocksize = 8 * sf.num / sf.denom;
192
193 if (pf == TJPF_GRAY) roffset = goffset = boffset = 0;
194
195 if (pf == TJPF_CMYK) {
196 for (row = 0; row < h; row++) {
197 for (col = 0; col < w; col++) {
198 unsigned char c, m, y, k;
199
200 if (flags & TJFLAG_BOTTOMUP) index = (h - row - 1) * w + col;
201 else index = row * w + col;
202 c = buf[index * ps];
203 m = buf[index * ps + 1];
204 y = buf[index * ps + 2];
205 k = buf[index * ps + 3];
206 if (((row / blocksize) + (col / blocksize)) % 2 == 0) {
207 checkval255(c); checkval255(m); checkval255(y);
208 if (row < halfway) checkval255(k)
209 else checkval0(k)
210 } else {
211 checkval255(c); checkval0(y); checkval255(k);
212 if (row < halfway) checkval0(m)
213 else checkval255(m)
214 }
215 }
216 }
217 return 1;
218 }
219
220 for (row = 0; row < h; row++) {
221 for (col = 0; col < w; col++) {
222 unsigned char r, g, b, a;
223
224 if (flags & TJFLAG_BOTTOMUP) index = (h - row - 1) * w + col;
225 else index = row * w + col;
226 r = buf[index * ps + roffset];
227 g = buf[index * ps + goffset];
228 b = buf[index * ps + boffset];
229 a = aoffset >= 0 ? buf[index * ps + aoffset] : 0xFF;
230 if (((row / blocksize) + (col / blocksize)) % 2 == 0) {
231 if (row < halfway) {
232 checkval255(r); checkval255(g); checkval255(b);
233 } else {
234 checkval0(r); checkval0(g); checkval0(b);
235 }
236 } else {
237 if (subsamp == TJSAMP_GRAY) {
238 if (row < halfway) {
239 checkval(r, 76); checkval(g, 76); checkval(b, 76);
240 } else {
241 checkval(r, 226); checkval(g, 226); checkval(b, 226);
242 }
243 } else {
244 if (row < halfway) {
245 checkval255(r); checkval0(g); checkval0(b);
246 } else {
247 checkval255(r); checkval255(g); checkval0(b);
248 }
249 }
250 }
251 checkval255(a);
252 }
253 }
254
255bailout:
256 if (retval == 0) {
257 for (row = 0; row < h; row++) {
258 for (col = 0; col < w; col++) {
259 if (pf == TJPF_CMYK)
Jonathan Wrighta145af12020-06-11 23:22:17 +0100260 fprintf(stderr, "%.3d/%.3d/%.3d/%.3d ", buf[(row * w + col) * ps],
261 buf[(row * w + col) * ps + 1], buf[(row * w + col) * ps + 2],
262 buf[(row * w + col) * ps + 3]);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800263 else
Jonathan Wrighta145af12020-06-11 23:22:17 +0100264 fprintf(stderr, "%.3d/%.3d/%.3d ", buf[(row * w + col) * ps + roffset],
265 buf[(row * w + col) * ps + goffset],
266 buf[(row * w + col) * ps + boffset]);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800267 }
Jonathan Wrighta145af12020-06-11 23:22:17 +0100268 fprintf(stderr, "\n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800269 }
270 }
271 return retval;
272}
273
274
275#define PAD(v, p) ((v + (p) - 1) & (~((p) - 1)))
hbono@chromium.org98626972011-08-03 03:13:08 +0000276
Jonathan Wright6cb95b82020-06-11 16:10:15 +0100277static int checkBufYUV(unsigned char *buf, int w, int h, int subsamp,
278 tjscalingfactor sf)
hbono@chromium.org98626972011-08-03 03:13:08 +0000279{
Chris Blumecca8c4d2019-03-01 01:09:50 -0800280 int row, col;
281 int hsf = tjMCUWidth[subsamp] / 8, vsf = tjMCUHeight[subsamp] / 8;
282 int pw = PAD(w, hsf), ph = PAD(h, vsf);
283 int cw = pw / hsf, ch = ph / vsf;
284 int ypitch = PAD(pw, pad), uvpitch = PAD(cw, pad);
285 int retval = 1;
286 int halfway = 16 * sf.num / sf.denom;
287 int blocksize = 8 * sf.num / sf.denom;
hbono@chromium.org98626972011-08-03 03:13:08 +0000288
Chris Blumecca8c4d2019-03-01 01:09:50 -0800289 for (row = 0; row < ph; row++) {
290 for (col = 0; col < pw; col++) {
291 unsigned char y = buf[ypitch * row + col];
hbono@chromium.org98626972011-08-03 03:13:08 +0000292
Chris Blumecca8c4d2019-03-01 01:09:50 -0800293 if (((row / blocksize) + (col / blocksize)) % 2 == 0) {
294 if (row < halfway) checkval255(y)
295 else checkval0(y);
296 } else {
297 if (row < halfway) checkval(y, 76)
298 else checkval(y, 226);
299 }
300 }
301 }
302 if (subsamp != TJSAMP_GRAY) {
303 int halfway = 16 / vsf * sf.num / sf.denom;
hbono@chromium.org98626972011-08-03 03:13:08 +0000304
Chris Blumecca8c4d2019-03-01 01:09:50 -0800305 for (row = 0; row < ch; row++) {
306 for (col = 0; col < cw; col++) {
307 unsigned char u = buf[ypitch * ph + (uvpitch * row + col)],
308 v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)];
309
310 if (((row * vsf / blocksize) + (col * hsf / blocksize)) % 2 == 0) {
311 checkval(u, 128); checkval(v, 128);
312 } else {
313 if (row < halfway) {
314 checkval(u, 85); checkval255(v);
315 } else {
316 checkval0(u); checkval(v, 149);
317 }
318 }
319 }
320 }
321 }
322
323bailout:
324 if (retval == 0) {
325 for (row = 0; row < ph; row++) {
326 for (col = 0; col < pw; col++)
Jonathan Wrighta145af12020-06-11 23:22:17 +0100327 fprintf(stderr, "%.3d ", buf[ypitch * row + col]);
328 fprintf(stderr, "\n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800329 }
Jonathan Wrighta145af12020-06-11 23:22:17 +0100330 fprintf(stderr, "\n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800331 for (row = 0; row < ch; row++) {
332 for (col = 0; col < cw; col++)
Jonathan Wrighta145af12020-06-11 23:22:17 +0100333 fprintf(stderr, "%.3d ", buf[ypitch * ph + (uvpitch * row + col)]);
334 fprintf(stderr, "\n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800335 }
Jonathan Wrighta145af12020-06-11 23:22:17 +0100336 fprintf(stderr, "\n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800337 for (row = 0; row < ch; row++) {
338 for (col = 0; col < cw; col++)
Jonathan Wrighta145af12020-06-11 23:22:17 +0100339 fprintf(stderr, "%.3d ",
340 buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)]);
341 fprintf(stderr, "\n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800342 }
343 }
344
345 return retval;
hbono@chromium.org98626972011-08-03 03:13:08 +0000346}
347
348
Jonathan Wright6cb95b82020-06-11 16:10:15 +0100349static void writeJPEG(unsigned char *jpegBuf, unsigned long jpegSize,
350 char *filename)
hbono@chromium.org98626972011-08-03 03:13:08 +0000351{
Chris Blumecca8c4d2019-03-01 01:09:50 -0800352 FILE *file = fopen(filename, "wb");
hbono@chromium.org98626972011-08-03 03:13:08 +0000353
Chris Blumecca8c4d2019-03-01 01:09:50 -0800354 if (!file || fwrite(jpegBuf, jpegSize, 1, file) != 1) {
Jonathan Wrighta145af12020-06-11 23:22:17 +0100355 fprintf(stderr, "ERROR: Could not write to %s.\n%s\n", filename,
356 strerror(errno));
Chris Blumecca8c4d2019-03-01 01:09:50 -0800357 bailout()
358 }
359
360bailout:
361 if (file) fclose(file);
hbono@chromium.org98626972011-08-03 03:13:08 +0000362}
363
364
Jonathan Wright6cb95b82020-06-11 16:10:15 +0100365static void compTest(tjhandle handle, unsigned char **dstBuf,
366 unsigned long *dstSize, int w, int h, int pf,
367 char *basename, int subsamp, int jpegQual, int flags)
hbono@chromium.org98626972011-08-03 03:13:08 +0000368{
Chris Blumecca8c4d2019-03-01 01:09:50 -0800369 char tempStr[1024];
370 unsigned char *srcBuf = NULL, *yuvBuf = NULL;
371 const char *pfStr = pixFormatStr[pf];
372 const char *buStrLong =
373 (flags & TJFLAG_BOTTOMUP) ? "Bottom-Up" : "Top-Down ";
374 const char *buStr = (flags & TJFLAG_BOTTOMUP) ? "BU" : "TD";
hbono@chromium.org98626972011-08-03 03:13:08 +0000375
Chris Blumecca8c4d2019-03-01 01:09:50 -0800376 if ((srcBuf = (unsigned char *)malloc(w * h * tjPixelSize[pf])) == NULL)
377 _throw("Memory allocation failure");
378 initBuf(srcBuf, w, h, pf, flags);
Tom Hudson0d47d2d2016-05-04 13:22:56 -0400379
Chris Blumecca8c4d2019-03-01 01:09:50 -0800380 if (*dstBuf && *dstSize > 0) memset(*dstBuf, 0, *dstSize);
hbono@chromium.org98626972011-08-03 03:13:08 +0000381
Chris Blumecca8c4d2019-03-01 01:09:50 -0800382 if (!alloc) flags |= TJFLAG_NOREALLOC;
383 if (doYUV) {
384 unsigned long yuvSize = tjBufSizeYUV2(w, pad, h, subsamp);
385 tjscalingfactor sf = { 1, 1 };
386 tjhandle handle2 = tjInitCompress();
Tom Hudson0d47d2d2016-05-04 13:22:56 -0400387
Chris Blumecca8c4d2019-03-01 01:09:50 -0800388 if (!handle2) _throwtj();
Tom Hudson0d47d2d2016-05-04 13:22:56 -0400389
Chris Blumecca8c4d2019-03-01 01:09:50 -0800390 if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL)
391 _throw("Memory allocation failure");
392 memset(yuvBuf, 0, yuvSize);
Tom Hudson0d47d2d2016-05-04 13:22:56 -0400393
Jonathan Wrighta145af12020-06-11 23:22:17 +0100394 fprintf(stderr, "%s %s -> YUV %s ... ", pfStr, buStrLong,
395 subNameLong[subsamp]);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800396 _tj(tjEncodeYUV3(handle2, srcBuf, w, 0, h, pf, yuvBuf, pad, subsamp,
397 flags));
398 tjDestroy(handle2);
Jonathan Wrighta145af12020-06-11 23:22:17 +0100399 if (checkBufYUV(yuvBuf, w, h, subsamp, sf)) fprintf(stderr, "Passed.\n");
400 else fprintf(stderr, "FAILED!\n");
Tom Hudson0d47d2d2016-05-04 13:22:56 -0400401
Jonathan Wrighta145af12020-06-11 23:22:17 +0100402 fprintf(stderr, "YUV %s %s -> JPEG Q%d ... ", subNameLong[subsamp], buStrLong,
403 jpegQual);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800404 _tj(tjCompressFromYUV(handle, yuvBuf, w, pad, h, subsamp, dstBuf, dstSize,
405 jpegQual, flags));
406 } else {
Jonathan Wrighta145af12020-06-11 23:22:17 +0100407 fprintf(stderr, "%s %s -> %s Q%d ... ", pfStr, buStrLong,
408 subNameLong[subsamp], jpegQual);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800409 _tj(tjCompress2(handle, srcBuf, w, 0, h, pf, dstBuf, dstSize, subsamp,
410 jpegQual, flags));
411 }
hbono@chromium.org98626972011-08-03 03:13:08 +0000412
Chris Blumecca8c4d2019-03-01 01:09:50 -0800413 snprintf(tempStr, 1024, "%s_enc_%s_%s_%s_Q%d.jpg", basename, pfStr, buStr,
414 subName[subsamp], jpegQual);
415 writeJPEG(*dstBuf, *dstSize, tempStr);
Jonathan Wrighta145af12020-06-11 23:22:17 +0100416 fprintf(stderr, "Done.\n Result in %s\n", tempStr);
hbono@chromium.org98626972011-08-03 03:13:08 +0000417
Chris Blumecca8c4d2019-03-01 01:09:50 -0800418bailout:
419 if (yuvBuf) free(yuvBuf);
420 if (srcBuf) free(srcBuf);
hbono@chromium.org98626972011-08-03 03:13:08 +0000421}
422
423
Jonathan Wright6cb95b82020-06-11 16:10:15 +0100424static void _decompTest(tjhandle handle, unsigned char *jpegBuf,
425 unsigned long jpegSize, int w, int h, int pf,
426 char *basename, int subsamp, int flags,
427 tjscalingfactor sf)
hbono@chromium.org98626972011-08-03 03:13:08 +0000428{
Chris Blumecca8c4d2019-03-01 01:09:50 -0800429 unsigned char *dstBuf = NULL, *yuvBuf = NULL;
430 int _hdrw = 0, _hdrh = 0, _hdrsubsamp = -1;
431 int scaledWidth = TJSCALED(w, sf);
432 int scaledHeight = TJSCALED(h, sf);
433 unsigned long dstSize = 0;
hbono@chromium.org98626972011-08-03 03:13:08 +0000434
Chris Blumecca8c4d2019-03-01 01:09:50 -0800435 _tj(tjDecompressHeader2(handle, jpegBuf, jpegSize, &_hdrw, &_hdrh,
436 &_hdrsubsamp));
437 if (_hdrw != w || _hdrh != h || _hdrsubsamp != subsamp)
438 _throw("Incorrect JPEG header");
hbono@chromium.org98626972011-08-03 03:13:08 +0000439
Chris Blumecca8c4d2019-03-01 01:09:50 -0800440 dstSize = scaledWidth * scaledHeight * tjPixelSize[pf];
441 if ((dstBuf = (unsigned char *)malloc(dstSize)) == NULL)
442 _throw("Memory allocation failure");
443 memset(dstBuf, 0, dstSize);
Tom Hudson0d47d2d2016-05-04 13:22:56 -0400444
Chris Blumecca8c4d2019-03-01 01:09:50 -0800445 if (doYUV) {
446 unsigned long yuvSize = tjBufSizeYUV2(scaledWidth, pad, scaledHeight,
447 subsamp);
448 tjhandle handle2 = tjInitDecompress();
Tom Hudson0d47d2d2016-05-04 13:22:56 -0400449
Chris Blumecca8c4d2019-03-01 01:09:50 -0800450 if (!handle2) _throwtj();
Tom Hudson0d47d2d2016-05-04 13:22:56 -0400451
Chris Blumecca8c4d2019-03-01 01:09:50 -0800452 if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL)
453 _throw("Memory allocation failure");
454 memset(yuvBuf, 0, yuvSize);
Tom Hudson0d47d2d2016-05-04 13:22:56 -0400455
Jonathan Wrighta145af12020-06-11 23:22:17 +0100456 fprintf(stderr, "JPEG -> YUV %s ", subNameLong[subsamp]);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800457 if (sf.num != 1 || sf.denom != 1)
Jonathan Wrighta145af12020-06-11 23:22:17 +0100458 fprintf(stderr, "%d/%d ... ", sf.num, sf.denom);
459 else fprintf(stderr, "... ");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800460 _tj(tjDecompressToYUV2(handle, jpegBuf, jpegSize, yuvBuf, scaledWidth, pad,
461 scaledHeight, flags));
462 if (checkBufYUV(yuvBuf, scaledWidth, scaledHeight, subsamp, sf))
Jonathan Wrighta145af12020-06-11 23:22:17 +0100463 fprintf(stderr, "Passed.\n");
464 else fprintf(stderr, "FAILED!\n");
hbono@chromium.org98626972011-08-03 03:13:08 +0000465
Jonathan Wrighta145af12020-06-11 23:22:17 +0100466 fprintf(stderr, "YUV %s -> %s %s ... ", subNameLong[subsamp],
467 pixFormatStr[pf],
468 (flags & TJFLAG_BOTTOMUP) ? "Bottom-Up" : "Top-Down ");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800469 _tj(tjDecodeYUV(handle2, yuvBuf, pad, subsamp, dstBuf, scaledWidth, 0,
470 scaledHeight, pf, flags));
471 tjDestroy(handle2);
472 } else {
Jonathan Wrighta145af12020-06-11 23:22:17 +0100473 fprintf(stderr, "JPEG -> %s %s ", pixFormatStr[pf],
474 (flags & TJFLAG_BOTTOMUP) ? "Bottom-Up" : "Top-Down ");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800475 if (sf.num != 1 || sf.denom != 1)
Jonathan Wrighta145af12020-06-11 23:22:17 +0100476 fprintf(stderr, "%d/%d ... ", sf.num, sf.denom);
477 else fprintf(stderr, "... ");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800478 _tj(tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, scaledWidth, 0,
479 scaledHeight, pf, flags));
480 }
hbono@chromium.org98626972011-08-03 03:13:08 +0000481
Chris Blumecca8c4d2019-03-01 01:09:50 -0800482 if (checkBuf(dstBuf, scaledWidth, scaledHeight, pf, subsamp, sf, flags))
Jonathan Wrighta145af12020-06-11 23:22:17 +0100483 fprintf(stderr, "Passed.");
484 else fprintf(stderr, "FAILED!");
485 fprintf(stderr, "\n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800486
487bailout:
488 if (yuvBuf) free(yuvBuf);
489 if (dstBuf) free(dstBuf);
hbono@chromium.org98626972011-08-03 03:13:08 +0000490}
491
492
Jonathan Wright6cb95b82020-06-11 16:10:15 +0100493static void decompTest(tjhandle handle, unsigned char *jpegBuf,
494 unsigned long jpegSize, int w, int h, int pf,
495 char *basename, int subsamp, int flags)
hbono@chromium.org98626972011-08-03 03:13:08 +0000496{
Chris Blumecca8c4d2019-03-01 01:09:50 -0800497 int i, n = 0;
498 tjscalingfactor *sf = tjGetScalingFactors(&n);
hbono@chromium.org98626972011-08-03 03:13:08 +0000499
Chris Blumecca8c4d2019-03-01 01:09:50 -0800500 if (!sf || !n) _throwtj();
hbono@chromium.org98626972011-08-03 03:13:08 +0000501
Chris Blumecca8c4d2019-03-01 01:09:50 -0800502 for (i = 0; i < n; i++) {
503 if (subsamp == TJSAMP_444 || subsamp == TJSAMP_GRAY ||
504 (subsamp == TJSAMP_411 && sf[i].num == 1 &&
505 (sf[i].denom == 2 || sf[i].denom == 1)) ||
506 (subsamp != TJSAMP_411 && sf[i].num == 1 &&
507 (sf[i].denom == 4 || sf[i].denom == 2 || sf[i].denom == 1)))
508 _decompTest(handle, jpegBuf, jpegSize, w, h, pf, basename, subsamp,
509 flags, sf[i]);
510 }
511
512bailout:
513 return;
hbono@chromium.org98626972011-08-03 03:13:08 +0000514}
515
516
Jonathan Wright6cb95b82020-06-11 16:10:15 +0100517static void doTest(int w, int h, const int *formats, int nformats, int subsamp,
518 char *basename)
hbono@chromium.org98626972011-08-03 03:13:08 +0000519{
Chris Blumecca8c4d2019-03-01 01:09:50 -0800520 tjhandle chandle = NULL, dhandle = NULL;
521 unsigned char *dstBuf = NULL;
522 unsigned long size = 0;
523 int pfi, pf, i;
hbono@chromium.org98626972011-08-03 03:13:08 +0000524
Chris Blumecca8c4d2019-03-01 01:09:50 -0800525 if (!alloc)
526 size = tjBufSize(w, h, subsamp);
527 if (size != 0)
528 if ((dstBuf = (unsigned char *)tjAlloc(size)) == NULL)
529 _throw("Memory allocation failure.");
hbono@chromium.org98626972011-08-03 03:13:08 +0000530
Chris Blumecca8c4d2019-03-01 01:09:50 -0800531 if ((chandle = tjInitCompress()) == NULL ||
532 (dhandle = tjInitDecompress()) == NULL)
533 _throwtj();
hbono@chromium.org98626972011-08-03 03:13:08 +0000534
Chris Blumecca8c4d2019-03-01 01:09:50 -0800535 for (pfi = 0; pfi < nformats; pfi++) {
536 for (i = 0; i < 2; i++) {
537 int flags = 0;
hbono@chromium.org98626972011-08-03 03:13:08 +0000538
Chris Blumecca8c4d2019-03-01 01:09:50 -0800539 if (subsamp == TJSAMP_422 || subsamp == TJSAMP_420 ||
540 subsamp == TJSAMP_440 || subsamp == TJSAMP_411)
541 flags |= TJFLAG_FASTUPSAMPLE;
542 if (i == 1) flags |= TJFLAG_BOTTOMUP;
543 pf = formats[pfi];
544 compTest(chandle, &dstBuf, &size, w, h, pf, basename, subsamp, 100,
545 flags);
546 decompTest(dhandle, dstBuf, size, w, h, pf, basename, subsamp, flags);
547 if (pf >= TJPF_RGBX && pf <= TJPF_XRGB) {
Jonathan Wrighta145af12020-06-11 23:22:17 +0100548 fprintf(stderr, "\n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800549 decompTest(dhandle, dstBuf, size, w, h, pf + (TJPF_RGBA - TJPF_RGBX),
550 basename, subsamp, flags);
551 }
Jonathan Wrighta145af12020-06-11 23:22:17 +0100552 fprintf(stderr, "\n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800553 }
554 }
Jonathan Wrighta145af12020-06-11 23:22:17 +0100555 fprintf(stderr, "--------------------\n\n");
hbono@chromium.org98626972011-08-03 03:13:08 +0000556
Chris Blumecca8c4d2019-03-01 01:09:50 -0800557bailout:
558 if (chandle) tjDestroy(chandle);
559 if (dhandle) tjDestroy(dhandle);
560 if (dstBuf) tjFree(dstBuf);
hbono@chromium.org98626972011-08-03 03:13:08 +0000561}
562
563
Jonathan Wright6cb95b82020-06-11 16:10:15 +0100564static void bufSizeTest(void)
hbono@chromium.org98626972011-08-03 03:13:08 +0000565{
Chris Blumecca8c4d2019-03-01 01:09:50 -0800566 int w, h, i, subsamp;
567 unsigned char *srcBuf = NULL, *dstBuf = NULL;
568 tjhandle handle = NULL;
569 unsigned long dstSize = 0;
hbono@chromium.org98626972011-08-03 03:13:08 +0000570
Chris Blumecca8c4d2019-03-01 01:09:50 -0800571 if ((handle = tjInitCompress()) == NULL) _throwtj();
hbono@chromium.org98626972011-08-03 03:13:08 +0000572
Jonathan Wrighta145af12020-06-11 23:22:17 +0100573 fprintf(stderr, "Buffer size regression test\n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800574 for (subsamp = 0; subsamp < TJ_NUMSAMP; subsamp++) {
575 for (w = 1; w < 48; w++) {
576 int maxh = (w == 1) ? 2048 : 48;
hbono@chromium.org98626972011-08-03 03:13:08 +0000577
Chris Blumecca8c4d2019-03-01 01:09:50 -0800578 for (h = 1; h < maxh; h++) {
Jonathan Wrighta145af12020-06-11 23:22:17 +0100579 if (h % 100 == 0)
580 fprintf(stderr, "%.4d x %.4d\b\b\b\b\b\b\b\b\b\b\b", w, h);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800581 if ((srcBuf = (unsigned char *)malloc(w * h * 4)) == NULL)
582 _throw("Memory allocation failure");
583 if (!alloc || doYUV) {
584 if (doYUV) dstSize = tjBufSizeYUV2(w, pad, h, subsamp);
585 else dstSize = tjBufSize(w, h, subsamp);
586 if ((dstBuf = (unsigned char *)tjAlloc(dstSize)) == NULL)
587 _throw("Memory allocation failure");
588 }
hbono@chromium.org98626972011-08-03 03:13:08 +0000589
Chris Blumecca8c4d2019-03-01 01:09:50 -0800590 for (i = 0; i < w * h * 4; i++) {
591 if (random() < RAND_MAX / 2) srcBuf[i] = 0;
592 else srcBuf[i] = 255;
593 }
hbono@chromium.org98626972011-08-03 03:13:08 +0000594
Chris Blumecca8c4d2019-03-01 01:09:50 -0800595 if (doYUV) {
596 _tj(tjEncodeYUV3(handle, srcBuf, w, 0, h, TJPF_BGRX, dstBuf, pad,
597 subsamp, 0));
598 } else {
599 _tj(tjCompress2(handle, srcBuf, w, 0, h, TJPF_BGRX, &dstBuf,
600 &dstSize, subsamp, 100,
601 alloc ? 0 : TJFLAG_NOREALLOC));
602 }
603 free(srcBuf); srcBuf = NULL;
604 if (!alloc || doYUV) {
605 tjFree(dstBuf); dstBuf = NULL;
606 }
hbono@chromium.org98626972011-08-03 03:13:08 +0000607
Chris Blumecca8c4d2019-03-01 01:09:50 -0800608 if ((srcBuf = (unsigned char *)malloc(h * w * 4)) == NULL)
609 _throw("Memory allocation failure");
610 if (!alloc || doYUV) {
611 if (doYUV) dstSize = tjBufSizeYUV2(h, pad, w, subsamp);
612 else dstSize = tjBufSize(h, w, subsamp);
613 if ((dstBuf = (unsigned char *)tjAlloc(dstSize)) == NULL)
614 _throw("Memory allocation failure");
615 }
hbono@chromium.org98626972011-08-03 03:13:08 +0000616
Chris Blumecca8c4d2019-03-01 01:09:50 -0800617 for (i = 0; i < h * w * 4; i++) {
618 if (random() < RAND_MAX / 2) srcBuf[i] = 0;
619 else srcBuf[i] = 255;
620 }
hbono@chromium.org98626972011-08-03 03:13:08 +0000621
Chris Blumecca8c4d2019-03-01 01:09:50 -0800622 if (doYUV) {
623 _tj(tjEncodeYUV3(handle, srcBuf, h, 0, w, TJPF_BGRX, dstBuf, pad,
624 subsamp, 0));
625 } else {
626 _tj(tjCompress2(handle, srcBuf, h, 0, w, TJPF_BGRX, &dstBuf,
627 &dstSize, subsamp, 100,
628 alloc ? 0 : TJFLAG_NOREALLOC));
629 }
630 free(srcBuf); srcBuf = NULL;
631 if (!alloc || doYUV) {
632 tjFree(dstBuf); dstBuf = NULL;
633 }
634 }
635 }
636 }
Jonathan Wrighta145af12020-06-11 23:22:17 +0100637 fprintf(stderr, "Done. \n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800638
639bailout:
640 if (srcBuf) free(srcBuf);
641 if (dstBuf) tjFree(dstBuf);
642 if (handle) tjDestroy(handle);
643}
644
645
Jonathan Wright6cb95b82020-06-11 16:10:15 +0100646static void initBitmap(unsigned char *buf, int width, int pitch, int height,
647 int pf, int flags)
Chris Blumecca8c4d2019-03-01 01:09:50 -0800648{
649 int roffset = tjRedOffset[pf];
650 int goffset = tjGreenOffset[pf];
651 int boffset = tjBlueOffset[pf];
652 int ps = tjPixelSize[pf];
653 int i, j;
654
655 for (j = 0; j < height; j++) {
656 int row = (flags & TJFLAG_BOTTOMUP) ? height - j - 1 : j;
657
658 for (i = 0; i < width; i++) {
659 unsigned char r = (i * 256 / width) % 256;
660 unsigned char g = (j * 256 / height) % 256;
661 unsigned char b = (j * 256 / height + i * 256 / width) % 256;
662
663 memset(&buf[row * pitch + i * ps], 0, ps);
664 if (pf == TJPF_GRAY) buf[row * pitch + i * ps] = b;
665 else if (pf == TJPF_CMYK)
666 rgb_to_cmyk(r, g, b, &buf[row * pitch + i * ps + 0],
667 &buf[row * pitch + i * ps + 1],
668 &buf[row * pitch + i * ps + 2],
669 &buf[row * pitch + i * ps + 3]);
670 else {
671 buf[row * pitch + i * ps + roffset] = r;
672 buf[row * pitch + i * ps + goffset] = g;
673 buf[row * pitch + i * ps + boffset] = b;
674 }
675 }
676 }
677}
678
679
Jonathan Wright6cb95b82020-06-11 16:10:15 +0100680static int cmpBitmap(unsigned char *buf, int width, int pitch, int height,
681 int pf, int flags, int gray2rgb)
Chris Blumecca8c4d2019-03-01 01:09:50 -0800682{
683 int roffset = tjRedOffset[pf];
684 int goffset = tjGreenOffset[pf];
685 int boffset = tjBlueOffset[pf];
686 int aoffset = tjAlphaOffset[pf];
687 int ps = tjPixelSize[pf];
688 int i, j;
689
690 for (j = 0; j < height; j++) {
691 int row = (flags & TJFLAG_BOTTOMUP) ? height - j - 1 : j;
692
693 for (i = 0; i < width; i++) {
694 unsigned char r = (i * 256 / width) % 256;
695 unsigned char g = (j * 256 / height) % 256;
696 unsigned char b = (j * 256 / height + i * 256 / width) % 256;
697
698 if (pf == TJPF_GRAY) {
699 if (buf[row * pitch + i * ps] != b)
700 return 0;
701 } else if (pf == TJPF_CMYK) {
702 unsigned char rf, gf, bf;
703
704 cmyk_to_rgb(buf[row * pitch + i * ps + 0],
705 buf[row * pitch + i * ps + 1],
706 buf[row * pitch + i * ps + 2],
707 buf[row * pitch + i * ps + 3], &rf, &gf, &bf);
708 if (gray2rgb) {
709 if (rf != b || gf != b || bf != b)
710 return 0;
711 } else if (rf != r || gf != g || bf != b) return 0;
712 } else {
713 if (gray2rgb) {
714 if (buf[row * pitch + i * ps + roffset] != b ||
715 buf[row * pitch + i * ps + goffset] != b ||
716 buf[row * pitch + i * ps + boffset] != b)
717 return 0;
718 } else if (buf[row * pitch + i * ps + roffset] != r ||
719 buf[row * pitch + i * ps + goffset] != g ||
720 buf[row * pitch + i * ps + boffset] != b)
721 return 0;
722 if (aoffset >= 0 && buf[row * pitch + i * ps + aoffset] != 0xFF)
723 return 0;
724 }
725 }
726 }
727 return 1;
728}
729
730
Jonathan Wright6cb95b82020-06-11 16:10:15 +0100731static int doBmpTest(const char *ext, int width, int align, int height, int pf,
732 int flags)
Chris Blumecca8c4d2019-03-01 01:09:50 -0800733{
734 char filename[80], *md5sum, md5buf[65];
735 int ps = tjPixelSize[pf], pitch = PAD(width * ps, align), loadWidth = 0,
736 loadHeight = 0, retval = 0, pixelFormat = pf;
737 unsigned char *buf = NULL;
738 char *md5ref;
739
740 if (pf == TJPF_GRAY) {
741 md5ref = !strcasecmp(ext, "ppm") ? "112c682e82ce5de1cca089e20d60000b" :
742 "51976530acf75f02beddf5d21149101d";
743 } else {
744 md5ref = !strcasecmp(ext, "ppm") ? "c0c9f772b464d1896326883a5c79c545" :
745 "6d659071b9bfcdee2def22cb58ddadca";
746 }
747
748 if ((buf = (unsigned char *)tjAlloc(pitch * height)) == NULL)
749 _throw("Could not allocate memory");
750 initBitmap(buf, width, pitch, height, pf, flags);
751
752 snprintf(filename, 80, "test_bmp_%s_%d_%s.%s", pixFormatStr[pf], align,
753 (flags & TJFLAG_BOTTOMUP) ? "bu" : "td", ext);
754 _tj(tjSaveImage(filename, buf, width, pitch, height, pf, flags));
755 md5sum = MD5File(filename, md5buf);
756 if (strcasecmp(md5sum, md5ref))
757 _throwmd5(filename, md5sum, md5ref);
758
759 tjFree(buf); buf = NULL;
760 if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf,
761 flags)) == NULL)
762 _throwtj();
763 if (width != loadWidth || height != loadHeight) {
Jonathan Wrighta145af12020-06-11 23:22:17 +0100764 fprintf(stderr, "\n Image dimensions of %s are bogus\n", filename);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800765 retval = -1; goto bailout;
766 }
767 if (!cmpBitmap(buf, width, pitch, height, pf, flags, 0)) {
Jonathan Wrighta145af12020-06-11 23:22:17 +0100768 fprintf(stderr, "\n Pixel data in %s is bogus\n", filename);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800769 retval = -1; goto bailout;
770 }
771 if (pf == TJPF_GRAY) {
772 tjFree(buf); buf = NULL;
773 pf = TJPF_XBGR;
774 if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf,
775 flags)) == NULL)
776 _throwtj();
777 pitch = PAD(width * tjPixelSize[pf], align);
778 if (!cmpBitmap(buf, width, pitch, height, pf, flags, 1)) {
Jonathan Wrighta145af12020-06-11 23:22:17 +0100779 fprintf(stderr, "\n Converting %s to RGB failed\n", filename);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800780 retval = -1; goto bailout;
781 }
782
783 tjFree(buf); buf = NULL;
784 pf = TJPF_CMYK;
785 if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf,
786 flags)) == NULL)
787 _throwtj();
788 pitch = PAD(width * tjPixelSize[pf], align);
789 if (!cmpBitmap(buf, width, pitch, height, pf, flags, 1)) {
Jonathan Wrighta145af12020-06-11 23:22:17 +0100790 fprintf(stderr, "\n Converting %s to CMYK failed\n", filename);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800791 retval = -1; goto bailout;
792 }
793 }
794 /* Verify that tjLoadImage() returns the proper "preferred" pixel format for
795 the file type. */
796 tjFree(buf); buf = NULL;
797 pf = pixelFormat;
798 pixelFormat = TJPF_UNKNOWN;
799 if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight,
800 &pixelFormat, flags)) == NULL)
801 _throwtj();
802 if ((pf == TJPF_GRAY && pixelFormat != TJPF_GRAY) ||
803 (pf != TJPF_GRAY && !strcasecmp(ext, "bmp") &&
804 pixelFormat != TJPF_BGR) ||
805 (pf != TJPF_GRAY && !strcasecmp(ext, "ppm") &&
806 pixelFormat != TJPF_RGB)) {
Jonathan Wrighta145af12020-06-11 23:22:17 +0100807 fprintf(stderr,
808 "\n tjLoadImage() returned unexpected pixel format: %s\n",
809 pixFormatStr[pixelFormat]);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800810 retval = -1;
811 }
812 unlink(filename);
813
814bailout:
815 if (buf) tjFree(buf);
816 if (exitStatus < 0) return exitStatus;
817 return retval;
818}
819
820
Jonathan Wright6cb95b82020-06-11 16:10:15 +0100821static int bmpTest(void)
Chris Blumecca8c4d2019-03-01 01:09:50 -0800822{
823 int align, width = 35, height = 39, format;
824
825 for (align = 1; align <= 8; align *= 2) {
826 for (format = 0; format < TJ_NUMPF; format++) {
Jonathan Wrighta145af12020-06-11 23:22:17 +0100827 fprintf(stderr, "%s Top-Down BMP (row alignment = %d bytes) ... ",
828 pixFormatStr[format], align);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800829 if (doBmpTest("bmp", width, align, height, format, 0) == -1)
830 return -1;
Jonathan Wrighta145af12020-06-11 23:22:17 +0100831 fprintf(stderr, "OK.\n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800832
Jonathan Wrighta145af12020-06-11 23:22:17 +0100833 fprintf(stderr, "%s Top-Down PPM (row alignment = %d bytes) ... ",
834 pixFormatStr[format], align);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800835 if (doBmpTest("ppm", width, align, height, format,
836 TJFLAG_BOTTOMUP) == -1)
837 return -1;
Jonathan Wrighta145af12020-06-11 23:22:17 +0100838 fprintf(stderr, "OK.\n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800839
Jonathan Wrighta145af12020-06-11 23:22:17 +0100840 fprintf(stderr, "%s Bottom-Up BMP (row alignment = %d bytes) ... ",
841 pixFormatStr[format], align);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800842 if (doBmpTest("bmp", width, align, height, format, 0) == -1)
843 return -1;
Jonathan Wrighta145af12020-06-11 23:22:17 +0100844 fprintf(stderr, "OK.\n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800845
Jonathan Wrighta145af12020-06-11 23:22:17 +0100846 fprintf(stderr, "%s Bottom-Up PPM (row alignment = %d bytes) ... ",
847 pixFormatStr[format], align);
Chris Blumecca8c4d2019-03-01 01:09:50 -0800848 if (doBmpTest("ppm", width, align, height, format,
849 TJFLAG_BOTTOMUP) == -1)
850 return -1;
Jonathan Wrighta145af12020-06-11 23:22:17 +0100851 fprintf(stderr, "OK.\n");
Chris Blumecca8c4d2019-03-01 01:09:50 -0800852 }
853 }
854
855 return 0;
hbono@chromium.org98626972011-08-03 03:13:08 +0000856}
857
Jonathan Wright6cb95b82020-06-11 16:10:15 +0100858#ifdef GTEST
859static void initTJUnitTest(int yuv, int noyuvpad, int autoalloc)
860{
861 doYUV = yuv ? 1 : 0;
862 pad = noyuvpad ? 1 : 4;
863 alloc = autoalloc ? 1 : 0;
864
865 exitStatus = 0;
866}
867
868
869int testBmp(int yuv, int noyuvpad, int autoalloc)
870{
871 initTJUnitTest(yuv, noyuvpad, autoalloc);
872
873 return bmpTest();
874}
875
876
877int testThreeByte444(int yuv, int noyuvpad, int autoalloc)
878{
879 initTJUnitTest(yuv, noyuvpad, autoalloc);
880
881 doTest(35, 39, _3byteFormats, 2, TJSAMP_444, "test");
882 return exitStatus;
883}
884
885
886int testFourByte444(int yuv, int noyuvpad, int autoalloc)
887{
888 initTJUnitTest(yuv, noyuvpad, autoalloc);
889
890 int num4bf = doYUV ? 4 : 5;
891 doTest(39, 41, _4byteFormats, num4bf, TJSAMP_444, "test");
892 return exitStatus;
893}
894
895
896int testThreeByte422(int yuv, int noyuvpad, int autoalloc)
897{
898 initTJUnitTest(yuv, noyuvpad, autoalloc);
899
900 doTest(41, 35, _3byteFormats, 2, TJSAMP_422, "test");
901 return exitStatus;
902}
903
904
905int testFourByte422(int yuv, int noyuvpad, int autoalloc)
906{
907 initTJUnitTest(yuv, noyuvpad, autoalloc);
908
909 int num4bf = doYUV ? 4 : 5;
910 doTest(35, 39, _4byteFormats, num4bf, TJSAMP_422, "test");
911 return exitStatus;
912}
913
914
915int testThreeByte420(int yuv, int noyuvpad, int autoalloc)
916{
917 initTJUnitTest(yuv, noyuvpad, autoalloc);
918
919 doTest(39, 41, _3byteFormats, 2, TJSAMP_420, "test");
920 return exitStatus;
921}
922
923
924int testFourByte420(int yuv, int noyuvpad, int autoalloc)
925{
926 initTJUnitTest(yuv, noyuvpad, autoalloc);
927
928 int num4bf = doYUV ? 4 : 5;
929 doTest(41, 35, _4byteFormats, num4bf, TJSAMP_420, "test");
930 return exitStatus;
931}
932
933
934int testThreeByte440(int yuv, int noyuvpad, int autoalloc)
935{
936 initTJUnitTest(yuv, noyuvpad, autoalloc);
937
938 doTest(35, 39, _3byteFormats, 2, TJSAMP_440, "test");
939 return exitStatus;
940}
941
942
943int testFourByte440(int yuv, int noyuvpad, int autoalloc)
944{
945 initTJUnitTest(yuv, noyuvpad, autoalloc);
946
947 int num4bf = doYUV ? 4 : 5;
948 doTest(39, 41, _4byteFormats, num4bf, TJSAMP_440, "test");
949 return exitStatus;
950}
951
952
953int testThreeByte411(int yuv, int noyuvpad, int autoalloc)
954{
955 initTJUnitTest(yuv, noyuvpad, autoalloc);
956
957 doTest(41, 35, _3byteFormats, 2, TJSAMP_411, "test");
958 return exitStatus;
959}
960
961
962int testFourByte411(int yuv, int noyuvpad, int autoalloc)
963{
964 initTJUnitTest(yuv, noyuvpad, autoalloc);
965
966 int num4bf = doYUV ? 4 : 5;
967 doTest(35, 39, _4byteFormats, num4bf, TJSAMP_411, "test");
968 return exitStatus;
969}
970
971
972int testOnlyGray(int yuv, int noyuvpad, int autoalloc)
973{
974 initTJUnitTest(yuv, noyuvpad, autoalloc);
975
976 doTest(39, 41, _onlyGray, 1, TJSAMP_GRAY, "test");
977 return exitStatus;
978}
979
980
981int testThreeByteGray(int yuv, int noyuvpad, int autoalloc)
982{
983 initTJUnitTest(yuv, noyuvpad, autoalloc);
984
985 doTest(41, 35, _3byteFormats, 2, TJSAMP_GRAY, "test");
986 return exitStatus;
987}
988
989
990int testFourByteGray(int yuv, int noyuvpad, int autoalloc)
991{
992 initTJUnitTest(yuv, noyuvpad, autoalloc);
993
994 doTest(35, 39, _4byteFormats, 4, TJSAMP_GRAY, "test");
995 return exitStatus;
996}
997
998
999int testBufSize(int yuv, int noyuvpad, int autoalloc)
1000{
1001 initTJUnitTest(yuv, noyuvpad, autoalloc);
1002
1003 bufSizeTest();
1004 return exitStatus;
1005}
1006
1007
1008int testYUVOnlyRGB444(int noyuvpad, int autoalloc)
1009{
1010 initTJUnitTest(1, noyuvpad, autoalloc);
1011
1012 doTest(48, 48, _onlyRGB, 1, TJSAMP_444, "test_yuv0");
1013 return exitStatus;
1014}
1015
1016
1017int testYUVOnlyRGB422(int noyuvpad, int autoalloc)
1018{
1019 initTJUnitTest(1, noyuvpad, autoalloc);
1020
1021 doTest(48, 48, _onlyRGB, 1, TJSAMP_422, "test_yuv0");
1022 return exitStatus;
1023}
1024
1025
1026int testYUVOnlyRGB420(int noyuvpad, int autoalloc)
1027{
1028 initTJUnitTest(1, noyuvpad, autoalloc);
1029
1030 doTest(48, 48, _onlyRGB, 1, TJSAMP_420, "test_yuv0");
1031 return exitStatus;
1032}
1033
1034
1035int testYUVOnlyRGB440(int noyuvpad, int autoalloc)
1036{
1037 initTJUnitTest(1, noyuvpad, autoalloc);
1038
1039 doTest(48, 48, _onlyRGB, 1, TJSAMP_440, "test_yuv0");
1040 return exitStatus;
1041}
1042
1043
1044int testYUVOnlyRGB411(int noyuvpad, int autoalloc)
1045{
1046 initTJUnitTest(1, noyuvpad, autoalloc);
1047
1048 doTest(48, 48, _onlyRGB, 1, TJSAMP_411, "test_yuv0");
1049 return exitStatus;
1050}
1051
1052
1053int testYUVOnlyRGBGray(int noyuvpad, int autoalloc)
1054{
1055 initTJUnitTest(1, noyuvpad, autoalloc);
1056
1057 doTest(48, 48, _onlyRGB, 1, TJSAMP_GRAY, "test_yuv0");
1058 return exitStatus;
1059}
1060
1061
1062int testYUVOnlyGrayGray(int noyuvpad, int autoalloc)
1063{
1064 initTJUnitTest(1, noyuvpad, autoalloc);
1065
1066 doTest(48, 48, _onlyGray, 1, TJSAMP_GRAY, "test_yuv0");
1067 return exitStatus;
1068}
1069
1070#else
hbono@chromium.org98626972011-08-03 03:13:08 +00001071
1072int main(int argc, char *argv[])
1073{
Chris Blumecca8c4d2019-03-01 01:09:50 -08001074 int i, num4bf = 5;
hbono@chromium.org98626972011-08-03 03:13:08 +00001075
Chris Blumecca8c4d2019-03-01 01:09:50 -08001076#ifdef _WIN32
1077 srand((unsigned int)time(NULL));
1078#endif
1079 if (argc > 1) {
1080 for (i = 1; i < argc; i++) {
1081 if (!strcasecmp(argv[i], "-yuv")) doYUV = 1;
1082 else if (!strcasecmp(argv[i], "-noyuvpad")) pad = 1;
1083 else if (!strcasecmp(argv[i], "-alloc")) alloc = 1;
1084 else if (!strcasecmp(argv[i], "-bmp")) return bmpTest();
1085 else usage(argv[0]);
1086 }
1087 }
1088 if (alloc) printf("Testing automatic buffer allocation\n");
1089 if (doYUV) num4bf = 4;
1090 doTest(35, 39, _3byteFormats, 2, TJSAMP_444, "test");
1091 doTest(39, 41, _4byteFormats, num4bf, TJSAMP_444, "test");
1092 doTest(41, 35, _3byteFormats, 2, TJSAMP_422, "test");
1093 doTest(35, 39, _4byteFormats, num4bf, TJSAMP_422, "test");
1094 doTest(39, 41, _3byteFormats, 2, TJSAMP_420, "test");
1095 doTest(41, 35, _4byteFormats, num4bf, TJSAMP_420, "test");
1096 doTest(35, 39, _3byteFormats, 2, TJSAMP_440, "test");
1097 doTest(39, 41, _4byteFormats, num4bf, TJSAMP_440, "test");
1098 doTest(41, 35, _3byteFormats, 2, TJSAMP_411, "test");
1099 doTest(35, 39, _4byteFormats, num4bf, TJSAMP_411, "test");
1100 doTest(39, 41, _onlyGray, 1, TJSAMP_GRAY, "test");
1101 doTest(41, 35, _3byteFormats, 2, TJSAMP_GRAY, "test");
1102 doTest(35, 39, _4byteFormats, 4, TJSAMP_GRAY, "test");
1103 bufSizeTest();
1104 if (doYUV) {
1105 printf("\n--------------------\n\n");
1106 doTest(48, 48, _onlyRGB, 1, TJSAMP_444, "test_yuv0");
1107 doTest(48, 48, _onlyRGB, 1, TJSAMP_422, "test_yuv0");
1108 doTest(48, 48, _onlyRGB, 1, TJSAMP_420, "test_yuv0");
1109 doTest(48, 48, _onlyRGB, 1, TJSAMP_440, "test_yuv0");
1110 doTest(48, 48, _onlyRGB, 1, TJSAMP_411, "test_yuv0");
1111 doTest(48, 48, _onlyRGB, 1, TJSAMP_GRAY, "test_yuv0");
1112 doTest(48, 48, _onlyGray, 1, TJSAMP_GRAY, "test_yuv0");
1113 }
1114
1115 return exitStatus;
hbono@chromium.org98626972011-08-03 03:13:08 +00001116}
Jonathan Wright6cb95b82020-06-11 16:10:15 +01001117#endif