blob: d5211f1539187948823cf38f341a3ada3c199b84 [file] [log] [blame]
Kaido Kert25902c62024-06-17 17:10:28 -07001/*
2 * Copyright (C)2009-2014, 2017-2019, 2022-2023 D. R. Commander.
3 * All Rights Reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * - Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * - Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * - Neither the name of the libjpeg-turbo Project nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/*
31 * This program tests the various code paths in the TurboJPEG C Wrapper
32 */
33
34#ifdef _MSC_VER
35#define _CRT_SECURE_NO_DEPRECATE
36#endif
37
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <limits.h>
42#include <errno.h>
43#include "tjutil.h"
44#include "turbojpeg.h"
45#include "md5/md5.h"
46#include "cmyk.h"
47#ifdef _WIN32
48#include <time.h>
49#define random() rand()
50#else
51#include <unistd.h>
52#endif
53
54
55#ifndef GTEST
56static void usage(char *progName)
57{
58 printf("\nUSAGE: %s [options]\n\n", progName);
59 printf("Options:\n");
60 printf("-yuv = test YUV encoding/compression/decompression/decoding\n");
61 printf("-noyuvpad = do not pad each row in each Y, U, and V plane to the nearest\n");
62 printf(" multiple of 4 bytes\n");
63 printf("-alloc = test automatic JPEG buffer allocation\n");
64 printf("-bmp = test packed-pixel image I/O\n");
65 exit(1);
66}
67#endif
68
69
70#define THROW_TJ() { \
71 fprintf(stderr, "TurboJPEG ERROR:\n%s\n", tjGetErrorStr()); \
72 BAILOUT() \
73}
74#define TRY_TJ(f) { if ((f) == -1) THROW_TJ(); }
75#define THROW(m) { printf("ERROR: %s\n", m); BAILOUT() }
76#define THROW_MD5(filename, md5sum, ref) { \
77 fprintf(stderr, "\n%s has an MD5 sum of %s.\n Should be %s.\n", filename, \
78 md5sum, ref); \
79 BAILOUT() \
80}
81
82static const char *subNameLong[TJ_NUMSAMP] = {
83 "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1"
84};
85static const char *subName[TJ_NUMSAMP] = {
86 "444", "422", "420", "GRAY", "440", "411"
87};
88
89static const char *pixFormatStr[TJ_NUMPF] = {
90 "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale",
91 "RGBA", "BGRA", "ABGR", "ARGB", "CMYK"
92};
93
94static const int _3byteFormats[] = { TJPF_RGB, TJPF_BGR };
95static const int _4byteFormats[] = {
96 TJPF_RGBX, TJPF_BGRX, TJPF_XBGR, TJPF_XRGB, TJPF_CMYK
97};
98static const int _onlyGray[] = { TJPF_GRAY };
99static const int _onlyRGB[] = { TJPF_RGB };
100
101static int doYUV = 0, alloc = 0, yuvAlign = 4;
102
103static int exitStatus = 0;
104#define BAILOUT() { exitStatus = -1; goto bailout; }
105
106static const size_t filePathSize = 1024;
107
108
109static void initBuf(unsigned char *buf, int w, int h, int pf, int flags)
110{
111 int roffset = tjRedOffset[pf];
112 int goffset = tjGreenOffset[pf];
113 int boffset = tjBlueOffset[pf];
114 int ps = tjPixelSize[pf];
115 int index, row, col, halfway = 16;
116
117 if (pf == TJPF_GRAY) {
118 memset(buf, 0, w * h * ps);
119 for (row = 0; row < h; row++) {
120 for (col = 0; col < w; col++) {
121 if (flags & TJFLAG_BOTTOMUP) index = (h - row - 1) * w + col;
122 else index = row * w + col;
123 if (((row / 8) + (col / 8)) % 2 == 0)
124 buf[index] = (row < halfway) ? 255 : 0;
125 else buf[index] = (row < halfway) ? 76 : 226;
126 }
127 }
128 } else if (pf == TJPF_CMYK) {
129 memset(buf, 255, w * h * ps);
130 for (row = 0; row < h; row++) {
131 for (col = 0; col < w; col++) {
132 if (flags & TJFLAG_BOTTOMUP) index = (h - row - 1) * w + col;
133 else index = row * w + col;
134 if (((row / 8) + (col / 8)) % 2 == 0) {
135 if (row >= halfway) buf[index * ps + 3] = 0;
136 } else {
137 buf[index * ps + 2] = 0;
138 if (row < halfway) buf[index * ps + 1] = 0;
139 }
140 }
141 }
142 } else {
143 memset(buf, 0, w * h * ps);
144 for (row = 0; row < h; row++) {
145 for (col = 0; col < w; col++) {
146 if (flags & TJFLAG_BOTTOMUP) index = (h - row - 1) * w + col;
147 else index = row * w + col;
148 if (((row / 8) + (col / 8)) % 2 == 0) {
149 if (row < halfway) {
150 buf[index * ps + roffset] = 255;
151 buf[index * ps + goffset] = 255;
152 buf[index * ps + boffset] = 255;
153 }
154 } else {
155 buf[index * ps + roffset] = 255;
156 if (row >= halfway) buf[index * ps + goffset] = 255;
157 }
158 }
159 }
160 }
161}
162
163
164#define CHECKVAL(v, cv) { \
165 if (v < cv - 1 || v > cv + 1) { \
166 fprintf(stderr, "\nComp. %s at %d,%d should be %d, not %d\n", #v, row, \
167 col, cv, v); \
168 retval = 0; exitStatus = -1; goto bailout; \
169 } \
170}
171
172#define CHECKVAL0(v) { \
173 if (v > 1) { \
174 fprintf(stderr, "\nComp. %s at %d,%d should be 0, not %d\n", #v, row, \
175 col, v); \
176 retval = 0; exitStatus = -1; goto bailout; \
177 } \
178}
179
180#define CHECKVAL255(v) { \
181 if (v < 254) { \
182 fprintf(stderr, "\nComp. %s at %d,%d should be 255, not %d\n", #v, row, \
183 col, v); \
184 retval = 0; exitStatus = -1; goto bailout; \
185 } \
186}
187
188
189static int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp,
190 tjscalingfactor sf, int flags)
191{
192 int roffset = tjRedOffset[pf];
193 int goffset = tjGreenOffset[pf];
194 int boffset = tjBlueOffset[pf];
195 int aoffset = tjAlphaOffset[pf];
196 int ps = tjPixelSize[pf];
197 int index, row, col, retval = 1;
198 int halfway = 16 * sf.num / sf.denom;
199 int blocksize = 8 * sf.num / sf.denom;
200
201 if (pf == TJPF_GRAY) roffset = goffset = boffset = 0;
202
203 if (pf == TJPF_CMYK) {
204 for (row = 0; row < h; row++) {
205 for (col = 0; col < w; col++) {
206 unsigned char c, m, y, k;
207
208 if (flags & TJFLAG_BOTTOMUP) index = (h - row - 1) * w + col;
209 else index = row * w + col;
210 c = buf[index * ps];
211 m = buf[index * ps + 1];
212 y = buf[index * ps + 2];
213 k = buf[index * ps + 3];
214 if (((row / blocksize) + (col / blocksize)) % 2 == 0) {
215 CHECKVAL255(c); CHECKVAL255(m); CHECKVAL255(y);
216 if (row < halfway) CHECKVAL255(k)
217 else CHECKVAL0(k)
218 } else {
219 CHECKVAL255(c); CHECKVAL0(y); CHECKVAL255(k);
220 if (row < halfway) CHECKVAL0(m)
221 else CHECKVAL255(m)
222 }
223 }
224 }
225 return 1;
226 }
227
228 for (row = 0; row < h; row++) {
229 for (col = 0; col < w; col++) {
230 unsigned char r, g, b, a;
231
232 if (flags & TJFLAG_BOTTOMUP) index = (h - row - 1) * w + col;
233 else index = row * w + col;
234 r = buf[index * ps + roffset];
235 g = buf[index * ps + goffset];
236 b = buf[index * ps + boffset];
237 a = aoffset >= 0 ? buf[index * ps + aoffset] : 0xFF;
238 if (((row / blocksize) + (col / blocksize)) % 2 == 0) {
239 if (row < halfway) {
240 CHECKVAL255(r); CHECKVAL255(g); CHECKVAL255(b);
241 } else {
242 CHECKVAL0(r); CHECKVAL0(g); CHECKVAL0(b);
243 }
244 } else {
245 if (subsamp == TJSAMP_GRAY) {
246 if (row < halfway) {
247 CHECKVAL(r, 76); CHECKVAL(g, 76); CHECKVAL(b, 76);
248 } else {
249 CHECKVAL(r, 226); CHECKVAL(g, 226); CHECKVAL(b, 226);
250 }
251 } else {
252 if (row < halfway) {
253 CHECKVAL255(r); CHECKVAL0(g); CHECKVAL0(b);
254 } else {
255 CHECKVAL255(r); CHECKVAL255(g); CHECKVAL0(b);
256 }
257 }
258 }
259 CHECKVAL255(a);
260 }
261 }
262
263bailout:
264 if (retval == 0) {
265 for (row = 0; row < h; row++) {
266 for (col = 0; col < w; col++) {
267 if (pf == TJPF_CMYK)
268 fprintf(stderr, "%.3d/%.3d/%.3d/%.3d ", buf[(row * w + col) * ps],
269 buf[(row * w + col) * ps + 1], buf[(row * w + col) * ps + 2],
270 buf[(row * w + col) * ps + 3]);
271 else
272 fprintf(stderr, "%.3d/%.3d/%.3d ",
273 buf[(row * w + col) * ps + roffset],
274 buf[(row * w + col) * ps + goffset],
275 buf[(row * w + col) * ps + boffset]);
276 }
277 fprintf(stderr, "\n");
278 }
279 }
280 return retval;
281}
282
283
284#define PAD(v, p) ((v + (p) - 1) & (~((p) - 1)))
285
286static int checkBufYUV(unsigned char *buf, int w, int h, int subsamp,
287 tjscalingfactor sf)
288{
289 int row, col;
290 int hsf = tjMCUWidth[subsamp] / 8, vsf = tjMCUHeight[subsamp] / 8;
291 int pw = PAD(w, hsf), ph = PAD(h, vsf);
292 int cw = pw / hsf, ch = ph / vsf;
293 int ypitch = PAD(pw, yuvAlign), uvpitch = PAD(cw, yuvAlign);
294 int retval = 1;
295 int halfway = 16 * sf.num / sf.denom;
296 int blocksize = 8 * sf.num / sf.denom;
297
298 for (row = 0; row < ph; row++) {
299 for (col = 0; col < pw; col++) {
300 unsigned char y = buf[ypitch * row + col];
301
302 if (((row / blocksize) + (col / blocksize)) % 2 == 0) {
303 if (row < halfway) CHECKVAL255(y)
304 else CHECKVAL0(y);
305 } else {
306 if (row < halfway) CHECKVAL(y, 76)
307 else CHECKVAL(y, 226);
308 }
309 }
310 }
311 if (subsamp != TJSAMP_GRAY) {
312 halfway = 16 / vsf * sf.num / sf.denom;
313
314 for (row = 0; row < ch; row++) {
315 for (col = 0; col < cw; col++) {
316 unsigned char u = buf[ypitch * ph + (uvpitch * row + col)],
317 v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)];
318
319 if (((row * vsf / blocksize) + (col * hsf / blocksize)) % 2 == 0) {
320 CHECKVAL(u, 128); CHECKVAL(v, 128);
321 } else {
322 if (row < halfway) {
323 CHECKVAL(u, 85); CHECKVAL255(v);
324 } else {
325 CHECKVAL0(u); CHECKVAL(v, 149);
326 }
327 }
328 }
329 }
330 }
331
332bailout:
333 if (retval == 0) {
334 for (row = 0; row < ph; row++) {
335 for (col = 0; col < pw; col++)
336 fprintf(stderr, "%.3d ", buf[ypitch * row + col]);
337 fprintf(stderr, "\n");
338 }
339 fprintf(stderr, "\n");
340 for (row = 0; row < ch; row++) {
341 for (col = 0; col < cw; col++)
342 fprintf(stderr, "%.3d ", buf[ypitch * ph + (uvpitch * row + col)]);
343 fprintf(stderr, "\n");
344 }
345 fprintf(stderr, "\n");
346 for (row = 0; row < ch; row++) {
347 for (col = 0; col < cw; col++)
348 fprintf(stderr, "%.3d ",
349 buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)]);
350 fprintf(stderr, "\n");
351 }
352 }
353
354 return retval;
355}
356
357
358static void writeJPEG(unsigned char *jpegBuf, unsigned long jpegSize,
359 char *filename)
360{
361#if defined(ANDROID) && defined(GTEST)
362 char path[filePathSize];
363 SNPRINTF(path, filePathSize, "/sdcard/%s", filename);
364 FILE *file = fopen(path, "wb");
365#else
366 FILE *file = fopen(filename, "wb");
367#endif
368 if (!file || fwrite(jpegBuf, jpegSize, 1, file) != 1) {
369 fprintf(stderr, "ERROR: Could not write to %s.\n%s\n", filename,
370 strerror(errno));
371 BAILOUT()
372 }
373
374bailout:
375 if (file) fclose(file);
376}
377
378
379static void compTest(tjhandle handle, unsigned char **dstBuf,
380 unsigned long *dstSize, int w, int h, int pf,
381 char *basename, int subsamp, int jpegQual, int flags)
382{
383 char tempStr[filePathSize];
384 unsigned char *srcBuf = NULL, *yuvBuf = NULL;
385 const char *pfStr = pixFormatStr[pf];
386 const char *buStrLong =
387 (flags & TJFLAG_BOTTOMUP) ? "Bottom-Up" : "Top-Down ";
388 const char *buStr = (flags & TJFLAG_BOTTOMUP) ? "BU" : "TD";
389
390 if ((srcBuf = (unsigned char *)malloc(w * h * tjPixelSize[pf])) == NULL)
391 THROW("Memory allocation failure");
392 initBuf(srcBuf, w, h, pf, flags);
393
394 if (*dstBuf && *dstSize > 0) memset(*dstBuf, 0, *dstSize);
395
396 if (!alloc) flags |= TJFLAG_NOREALLOC;
397 if (doYUV) {
398 unsigned long yuvSize = tjBufSizeYUV2(w, yuvAlign, h, subsamp);
399 tjscalingfactor sf = { 1, 1 };
400 tjhandle handle2 = tjInitCompress();
401
402 if (!handle2) THROW_TJ();
403
404 if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL)
405 THROW("Memory allocation failure");
406 memset(yuvBuf, 0, yuvSize);
407
408 fprintf(stderr, "%s %s -> YUV %s ... ", pfStr, buStrLong,
409 subNameLong[subsamp]);
410 TRY_TJ(tjEncodeYUV3(handle2, srcBuf, w, 0, h, pf, yuvBuf, yuvAlign,
411 subsamp, flags));
412 tjDestroy(handle2);
413 if (checkBufYUV(yuvBuf, w, h, subsamp, sf)) fprintf(stderr, "Passed.\n");
414 else fprintf(stderr, "FAILED!\n");
415
416 fprintf(stderr, "YUV %s %s -> JPEG Q%d ... ", subNameLong[subsamp],
417 buStrLong, jpegQual);
418 TRY_TJ(tjCompressFromYUV(handle, yuvBuf, w, yuvAlign, h, subsamp, dstBuf,
419 dstSize, jpegQual, flags));
420 } else {
421 fprintf(stderr, "%s %s -> %s Q%d ... ", pfStr, buStrLong,
422 subNameLong[subsamp], jpegQual);
423 TRY_TJ(tjCompress2(handle, srcBuf, w, 0, h, pf, dstBuf, dstSize, subsamp,
424 jpegQual, flags));
425 }
426
427 SNPRINTF(tempStr, filePathSize, "%s_enc_%s_%s_%s_Q%d.jpg", basename, pfStr,
428 buStr, subName[subsamp], jpegQual);
429 writeJPEG(*dstBuf, *dstSize, tempStr);
430 fprintf(stderr, "Done.\n Result in %s\n", tempStr);
431
432bailout:
433 free(yuvBuf);
434 free(srcBuf);
435}
436
437
438static void _decompTest(tjhandle handle, unsigned char *jpegBuf,
439 unsigned long jpegSize, int w, int h, int pf,
440 char *basename, int subsamp, int flags,
441 tjscalingfactor sf)
442{
443 unsigned char *dstBuf = NULL, *yuvBuf = NULL;
444 int _hdrw = 0, _hdrh = 0, _hdrsubsamp = -1;
445 int scaledWidth = TJSCALED(w, sf);
446 int scaledHeight = TJSCALED(h, sf);
447 unsigned long dstSize = 0;
448
449 TRY_TJ(tjDecompressHeader2(handle, jpegBuf, jpegSize, &_hdrw, &_hdrh,
450 &_hdrsubsamp));
451 if (_hdrw != w || _hdrh != h || _hdrsubsamp != subsamp)
452 THROW("Incorrect JPEG header");
453
454 dstSize = scaledWidth * scaledHeight * tjPixelSize[pf];
455 if ((dstBuf = (unsigned char *)malloc(dstSize)) == NULL)
456 THROW("Memory allocation failure");
457 memset(dstBuf, 0, dstSize);
458
459 if (doYUV) {
460 unsigned long yuvSize = tjBufSizeYUV2(scaledWidth, yuvAlign, scaledHeight,
461 subsamp);
462 tjhandle handle2 = tjInitDecompress();
463
464 if (!handle2) THROW_TJ();
465
466 if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL)
467 THROW("Memory allocation failure");
468 memset(yuvBuf, 0, yuvSize);
469
470 fprintf(stderr, "JPEG -> YUV %s ", subNameLong[subsamp]);
471 if (sf.num != 1 || sf.denom != 1)
472 fprintf(stderr, "%d/%d ... ", sf.num, sf.denom);
473 else fprintf(stderr, "... ");
474 /* We pass scaledWidth + 1 and scaledHeight + 1 to validate that
475 tjDecompressToYUV2() generates the largest possible scaled image that
476 fits within the desired dimensions, as documented. */
477 TRY_TJ(tjDecompressToYUV2(handle, jpegBuf, jpegSize, yuvBuf,
478 scaledWidth + 1, yuvAlign, scaledHeight + 1,
479 flags));
480 if (checkBufYUV(yuvBuf, scaledWidth, scaledHeight, subsamp, sf))
481 fprintf(stderr, "Passed.\n");
482 else fprintf(stderr, "FAILED!\n");
483
484 fprintf(stderr, "YUV %s -> %s %s ... ", subNameLong[subsamp],
485 pixFormatStr[pf],
486 (flags & TJFLAG_BOTTOMUP) ? "Bottom-Up" : "Top-Down ");
487 TRY_TJ(tjDecodeYUV(handle2, yuvBuf, yuvAlign, subsamp, dstBuf, scaledWidth, 0,
488 scaledHeight, pf, flags));
489 tjDestroy(handle2);
490 } else {
491 fprintf(stderr, "JPEG -> %s %s ", pixFormatStr[pf],
492 (flags & TJFLAG_BOTTOMUP) ? "Bottom-Up" : "Top-Down ");
493 if (sf.num != 1 || sf.denom != 1)
494 fprintf(stderr, "%d/%d ... ", sf.num, sf.denom);
495 else fprintf(stderr, "... ");
496 /* We pass scaledWidth + 1 and scaledHeight + 1 to validate that
497 tjDecompress2() generates the largest possible scaled image that fits
498 within the desired dimensions, as documented. */
499 TRY_TJ(tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, scaledWidth + 1, 0,
500 scaledHeight + 1, pf, flags));
501 }
502
503 if (checkBuf(dstBuf, scaledWidth, scaledHeight, pf, subsamp, sf, flags))
504 fprintf(stderr, "Passed.");
505 else fprintf(stderr, "FAILED!");
506 fprintf(stderr, "\n");
507
508bailout:
509 free(yuvBuf);
510 free(dstBuf);
511}
512
513
514static void decompTest(tjhandle handle, unsigned char *jpegBuf,
515 unsigned long jpegSize, int w, int h, int pf,
516 char *basename, int subsamp, int flags)
517{
518 int i, n = 0;
519 tjscalingfactor *sf = tjGetScalingFactors(&n);
520
521 if (!sf || !n) THROW_TJ();
522
523 for (i = 0; i < n; i++) {
524 if (subsamp == TJSAMP_444 || subsamp == TJSAMP_GRAY ||
525 (subsamp == TJSAMP_411 && sf[i].num == 1 &&
526 (sf[i].denom == 2 || sf[i].denom == 1)) ||
527 (subsamp != TJSAMP_411 && sf[i].num == 1 &&
528 (sf[i].denom == 4 || sf[i].denom == 2 || sf[i].denom == 1)))
529 _decompTest(handle, jpegBuf, jpegSize, w, h, pf, basename, subsamp,
530 flags, sf[i]);
531 }
532
533bailout:
534 return;
535}
536
537
538static void doTest(int w, int h, const int *formats, int nformats, int subsamp,
539 char *basename)
540{
541 tjhandle chandle = NULL, dhandle = NULL;
542 unsigned char *dstBuf = NULL;
543 unsigned long size = 0;
544 int pfi, pf, i;
545
546 if (!alloc)
547 size = tjBufSize(w, h, subsamp);
548 if (size != 0)
549 if ((dstBuf = (unsigned char *)tjAlloc(size)) == NULL)
550 THROW("Memory allocation failure.");
551
552 if ((chandle = tjInitCompress()) == NULL ||
553 (dhandle = tjInitDecompress()) == NULL)
554 THROW_TJ();
555
556 for (pfi = 0; pfi < nformats; pfi++) {
557 for (i = 0; i < 2; i++) {
558 int flags = 0;
559
560 if (subsamp == TJSAMP_422 || subsamp == TJSAMP_420 ||
561 subsamp == TJSAMP_440 || subsamp == TJSAMP_411)
562 flags |= TJFLAG_FASTUPSAMPLE;
563 if (i == 1) flags |= TJFLAG_BOTTOMUP;
564 pf = formats[pfi];
565 compTest(chandle, &dstBuf, &size, w, h, pf, basename, subsamp, 100,
566 flags);
567 decompTest(dhandle, dstBuf, size, w, h, pf, basename, subsamp, flags);
568 if (pf >= TJPF_RGBX && pf <= TJPF_XRGB) {
569 fprintf(stderr, "\n");
570 decompTest(dhandle, dstBuf, size, w, h, pf + (TJPF_RGBA - TJPF_RGBX),
571 basename, subsamp, flags);
572 }
573 fprintf(stderr, "\n");
574 }
575 }
576 fprintf(stderr, "--------------------\n\n");
577
578bailout:
579 if (chandle) tjDestroy(chandle);
580 if (dhandle) tjDestroy(dhandle);
581 tjFree(dstBuf);
582}
583
584
585#if SIZEOF_SIZE_T == 8
586#define CHECKSIZE(function) { \
587 if ((unsigned long long)size < (unsigned long long)0xFFFFFFFF) \
588 THROW(#function " overflow"); \
589}
590#else
591#define CHECKSIZE(function) { \
592 if (size != (unsigned long)(-1) || \
593 !strcmp(tjGetErrorStr2(NULL), "No error")) \
594 THROW(#function " overflow"); \
595}
596#endif
597#define CHECKSIZEINT(function) { \
598 if (intsize != -1 || !strcmp(tjGetErrorStr2(NULL), "No error")) \
599 THROW(#function " overflow"); \
600}
601
602#ifndef GTEST
603static void overflowTest(void)
604{
605 /* Ensure that the various buffer size functions don't overflow */
606 unsigned long size;
607 int intsize;
608
609 size = tjBufSize(26755, 26755, TJSAMP_444);
610 CHECKSIZE(tjBufSize());
611 size = TJBUFSIZE(26755, 26755);
612 CHECKSIZE(TJBUFSIZE());
613 size = tjBufSizeYUV2(37838, 1, 37838, TJSAMP_444);
614 CHECKSIZE(tjBufSizeYUV2());
615 size = tjBufSizeYUV2(37837, 3, 37837, TJSAMP_444);
616 CHECKSIZE(tjBufSizeYUV2());
617 size = tjBufSizeYUV2(37837, -1, 37837, TJSAMP_444);
618 CHECKSIZE(tjBufSizeYUV2());
619 size = TJBUFSIZEYUV(37838, 37838, TJSAMP_444);
620 CHECKSIZE(TJBUFSIZEYUV());
621 size = tjBufSizeYUV(37838, 37838, TJSAMP_444);
622 CHECKSIZE(tjBufSizeYUV());
623 size = tjPlaneSizeYUV(0, 65536, 0, 65536, TJSAMP_444);
624 CHECKSIZE(tjPlaneSizeYUV());
625 intsize = tjPlaneWidth(0, INT_MAX, TJSAMP_420);
626 CHECKSIZEINT(tjPlaneWidth());
627 intsize = tjPlaneHeight(0, INT_MAX, TJSAMP_420);
628 CHECKSIZEINT(tjPlaneHeight());
629
630bailout:
631 return;
632}
633#endif
634
635
636static void bufSizeTest(void)
637{
638 int w, h, i, subsamp;
639 unsigned char *srcBuf = NULL, *dstBuf = NULL;
640 tjhandle handle = NULL;
641 unsigned long dstSize = 0;
642
643 if ((handle = tjInitCompress()) == NULL) THROW_TJ();
644
645 fprintf(stderr, "Buffer size regression test\n");
646 for (subsamp = 0; subsamp < TJ_NUMSAMP; subsamp++) {
647 for (w = 1; w < 48; w++) {
648 int maxh = (w == 1) ? 2048 : 48;
649
650 for (h = 1; h < maxh; h++) {
651 if (h % 100 == 0)
652 fprintf(stderr, "%.4d x %.4d\b\b\b\b\b\b\b\b\b\b\b", w, h);
653 if ((srcBuf = (unsigned char *)malloc(w * h * 4)) == NULL)
654 THROW("Memory allocation failure");
655 if (!alloc || doYUV) {
656 if (doYUV) dstSize = tjBufSizeYUV2(w, yuvAlign, h, subsamp);
657 else dstSize = tjBufSize(w, h, subsamp);
658 if ((dstBuf = (unsigned char *)tjAlloc(dstSize)) == NULL)
659 THROW("Memory allocation failure");
660 }
661
662 for (i = 0; i < w * h * 4; i++) {
663 if (random() < RAND_MAX / 2) srcBuf[i] = 0;
664 else srcBuf[i] = 255;
665 }
666
667 if (doYUV) {
668 TRY_TJ(tjEncodeYUV3(handle, srcBuf, w, 0, h, TJPF_BGRX, dstBuf,
669 yuvAlign, subsamp, 0));
670 } else {
671 TRY_TJ(tjCompress2(handle, srcBuf, w, 0, h, TJPF_BGRX, &dstBuf,
672 &dstSize, subsamp, 100,
673 alloc ? 0 : TJFLAG_NOREALLOC));
674 }
675 free(srcBuf); srcBuf = NULL;
676 if (!alloc || doYUV) {
677 tjFree(dstBuf); dstBuf = NULL;
678 }
679
680 if ((srcBuf = (unsigned char *)malloc(h * w * 4)) == NULL)
681 THROW("Memory allocation failure");
682 if (!alloc || doYUV) {
683 if (doYUV) dstSize = tjBufSizeYUV2(h, yuvAlign, w, subsamp);
684 else dstSize = tjBufSize(h, w, subsamp);
685 if ((dstBuf = (unsigned char *)tjAlloc(dstSize)) == NULL)
686 THROW("Memory allocation failure");
687 }
688
689 for (i = 0; i < h * w * 4; i++) {
690 if (random() < RAND_MAX / 2) srcBuf[i] = 0;
691 else srcBuf[i] = 255;
692 }
693
694 if (doYUV) {
695 TRY_TJ(tjEncodeYUV3(handle, srcBuf, h, 0, w, TJPF_BGRX, dstBuf,
696 yuvAlign, subsamp, 0));
697 } else {
698 TRY_TJ(tjCompress2(handle, srcBuf, h, 0, w, TJPF_BGRX, &dstBuf,
699 &dstSize, subsamp, 100,
700 alloc ? 0 : TJFLAG_NOREALLOC));
701 }
702 free(srcBuf); srcBuf = NULL;
703 if (!alloc || doYUV) {
704 tjFree(dstBuf); dstBuf = NULL;
705 }
706 }
707 }
708 }
709 fprintf(stderr, "Done. \n");
710
711bailout:
712 free(srcBuf);
713 tjFree(dstBuf);
714 if (handle) tjDestroy(handle);
715}
716
717
718static void initBitmap(unsigned char *buf, int width, int pitch, int height,
719 int pf, int flags)
720{
721 int roffset = tjRedOffset[pf];
722 int goffset = tjGreenOffset[pf];
723 int boffset = tjBlueOffset[pf];
724 int ps = tjPixelSize[pf];
725 int i, j;
726
727 for (j = 0; j < height; j++) {
728 int row = (flags & TJFLAG_BOTTOMUP) ? height - j - 1 : j;
729
730 for (i = 0; i < width; i++) {
731 unsigned char r = (i * 256 / width) % 256;
732 unsigned char g = (j * 256 / height) % 256;
733 unsigned char b = (j * 256 / height + i * 256 / width) % 256;
734
735 memset(&buf[row * pitch + i * ps], 0, ps);
736 if (pf == TJPF_GRAY) buf[row * pitch + i * ps] = b;
737 else if (pf == TJPF_CMYK)
738 rgb_to_cmyk(r, g, b, &buf[row * pitch + i * ps + 0],
739 &buf[row * pitch + i * ps + 1],
740 &buf[row * pitch + i * ps + 2],
741 &buf[row * pitch + i * ps + 3]);
742 else {
743 buf[row * pitch + i * ps + roffset] = r;
744 buf[row * pitch + i * ps + goffset] = g;
745 buf[row * pitch + i * ps + boffset] = b;
746 }
747 }
748 }
749}
750
751
752static int cmpBitmap(unsigned char *buf, int width, int pitch, int height,
753 int pf, int flags, int gray2rgb)
754{
755 int roffset = tjRedOffset[pf];
756 int goffset = tjGreenOffset[pf];
757 int boffset = tjBlueOffset[pf];
758 int aoffset = tjAlphaOffset[pf];
759 int ps = tjPixelSize[pf];
760 int i, j;
761
762 for (j = 0; j < height; j++) {
763 int row = (flags & TJFLAG_BOTTOMUP) ? height - j - 1 : j;
764
765 for (i = 0; i < width; i++) {
766 unsigned char r = (i * 256 / width) % 256;
767 unsigned char g = (j * 256 / height) % 256;
768 unsigned char b = (j * 256 / height + i * 256 / width) % 256;
769
770 if (pf == TJPF_GRAY) {
771 if (buf[row * pitch + i * ps] != b)
772 return 0;
773 } else if (pf == TJPF_CMYK) {
774 unsigned char rf, gf, bf;
775
776 cmyk_to_rgb(buf[row * pitch + i * ps + 0],
777 buf[row * pitch + i * ps + 1],
778 buf[row * pitch + i * ps + 2],
779 buf[row * pitch + i * ps + 3], &rf, &gf, &bf);
780 if (gray2rgb) {
781 if (rf != b || gf != b || bf != b)
782 return 0;
783 } else if (rf != r || gf != g || bf != b) return 0;
784 } else {
785 if (gray2rgb) {
786 if (buf[row * pitch + i * ps + roffset] != b ||
787 buf[row * pitch + i * ps + goffset] != b ||
788 buf[row * pitch + i * ps + boffset] != b)
789 return 0;
790 } else if (buf[row * pitch + i * ps + roffset] != r ||
791 buf[row * pitch + i * ps + goffset] != g ||
792 buf[row * pitch + i * ps + boffset] != b)
793 return 0;
794 if (aoffset >= 0 && buf[row * pitch + i * ps + aoffset] != 0xFF)
795 return 0;
796 }
797 }
798 }
799 return 1;
800}
801
802
803static int doBmpTest(const char *ext, int width, int align, int height, int pf,
804 int flags)
805{
806 const size_t filenameSize = 80;
807 char filename[filenameSize], *md5sum, md5buf[65];
808 int ps = tjPixelSize[pf], pitch = PAD(width * ps, align), loadWidth = 0,
809 loadHeight = 0, retval = 0, pixelFormat = pf;
810 unsigned char *buf = NULL;
811 char *md5ref;
812
813 if (pf == TJPF_GRAY) {
814 md5ref = !strcasecmp(ext, "ppm") ? "112c682e82ce5de1cca089e20d60000b" :
815 "51976530acf75f02beddf5d21149101d";
816 } else {
817 md5ref = !strcasecmp(ext, "ppm") ? "c0c9f772b464d1896326883a5c79c545" :
818 "6d659071b9bfcdee2def22cb58ddadca";
819 }
820
821 if ((buf = (unsigned char *)tjAlloc(pitch * height)) == NULL)
822 THROW("Could not allocate memory");
823 initBitmap(buf, width, pitch, height, pf, flags);
824
825#if defined(ANDROID) && defined(GTEST)
826 SNPRINTF(filename, filenameSize, "/sdcard/test_bmp_%s_%d_%s.%s",
827 pixFormatStr[pf], align, (flags & TJFLAG_BOTTOMUP) ? "bu" : "td",
828 ext);
829#else
830 SNPRINTF(filename, filenameSize, "test_bmp_%s_%d_%s.%s", pixFormatStr[pf],
831 align, (flags & TJFLAG_BOTTOMUP) ? "bu" : "td", ext);
832#endif
833 TRY_TJ(tjSaveImage(filename, buf, width, pitch, height, pf, flags));
834 md5sum = MD5File(filename, md5buf);
835 if (strcasecmp(md5sum, md5ref))
836 THROW_MD5(filename, md5sum, md5ref);
837
838 tjFree(buf); buf = NULL;
839 if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf,
840 flags)) == NULL)
841 THROW_TJ();
842 if (width != loadWidth || height != loadHeight) {
843 fprintf(stderr, "\n Image dimensions of %s are bogus\n", filename);
844 retval = -1; goto bailout;
845 }
846 if (!cmpBitmap(buf, width, pitch, height, pf, flags, 0)) {
847 fprintf(stderr, "\n Pixel data in %s is bogus\n", filename);
848 retval = -1; goto bailout;
849 }
850 if (pf == TJPF_GRAY) {
851 tjFree(buf); buf = NULL;
852 pf = TJPF_XBGR;
853 if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf,
854 flags)) == NULL)
855 THROW_TJ();
856 pitch = PAD(width * tjPixelSize[pf], align);
857 if (!cmpBitmap(buf, width, pitch, height, pf, flags, 1)) {
858 fprintf(stderr, "\n Converting %s to RGB failed\n", filename);
859 retval = -1; goto bailout;
860 }
861
862 tjFree(buf); buf = NULL;
863 pf = TJPF_CMYK;
864 if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf,
865 flags)) == NULL)
866 THROW_TJ();
867 pitch = PAD(width * tjPixelSize[pf], align);
868 if (!cmpBitmap(buf, width, pitch, height, pf, flags, 1)) {
869 fprintf(stderr, "\n Converting %s to CMYK failed\n", filename);
870 retval = -1; goto bailout;
871 }
872 }
873 /* Verify that tjLoadImage() returns the proper "preferred" pixel format for
874 the file type. */
875 tjFree(buf); buf = NULL;
876 pf = pixelFormat;
877 pixelFormat = TJPF_UNKNOWN;
878 if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight,
879 &pixelFormat, flags)) == NULL)
880 THROW_TJ();
881 if ((pf == TJPF_GRAY && pixelFormat != TJPF_GRAY) ||
882 (pf != TJPF_GRAY && !strcasecmp(ext, "bmp") &&
883 pixelFormat != TJPF_BGR) ||
884 (pf != TJPF_GRAY && !strcasecmp(ext, "ppm") &&
885 pixelFormat != TJPF_RGB)) {
886 fprintf(stderr,
887 "\n tjLoadImage() returned unexpected pixel format: %s\n",
888 pixFormatStr[pixelFormat]);
889 retval = -1;
890 }
891 unlink(filename);
892
893bailout:
894 tjFree(buf);
895 if (exitStatus < 0) return exitStatus;
896 return retval;
897}
898
899
900static int bmpTest(void)
901{
902 int align, width = 35, height = 39, format;
903
904 for (align = 1; align <= 8; align *= 2) {
905 for (format = 0; format < TJ_NUMPF; format++) {
906 fprintf(stderr, "%s Top-Down BMP (row alignment = %d bytes) ... ",
907 pixFormatStr[format], align);
908 if (doBmpTest("bmp", width, align, height, format, 0) == -1)
909 return -1;
910 fprintf(stderr, "OK.\n");
911
912 fprintf(stderr, "%s Top-Down PPM (row alignment = %d bytes) ... ",
913 pixFormatStr[format], align);
914 if (doBmpTest("ppm", width, align, height, format,
915 TJFLAG_BOTTOMUP) == -1)
916 return -1;
917 fprintf(stderr, "OK.\n");
918
919 fprintf(stderr, "%s Bottom-Up BMP (row alignment = %d bytes) ... ",
920 pixFormatStr[format], align);
921 if (doBmpTest("bmp", width, align, height, format, 0) == -1)
922 return -1;
923 fprintf(stderr, "OK.\n");
924
925 fprintf(stderr, "%s Bottom-Up PPM (row alignment = %d bytes) ... ",
926 pixFormatStr[format], align);
927 if (doBmpTest("ppm", width, align, height, format,
928 TJFLAG_BOTTOMUP) == -1)
929 return -1;
930 fprintf(stderr, "OK.\n");
931 }
932 }
933
934 return 0;
935}
936
937
938#ifdef GTEST
939static void initTJUnitTest(int yuv, int noyuvpad, int autoalloc)
940{
941 doYUV = yuv ? 1 : 0;
942 yuvAlign = noyuvpad ? 1 : 4;
943 alloc = autoalloc ? 1 : 0;
944
945 exitStatus = 0;
946}
947
948
949int testBmp(int yuv, int noyuvpad, int autoalloc)
950{
951 initTJUnitTest(yuv, noyuvpad, autoalloc);
952
953 return bmpTest();
954}
955
956
957int testThreeByte444(int yuv, int noyuvpad, int autoalloc)
958{
959 initTJUnitTest(yuv, noyuvpad, autoalloc);
960
961 doTest(35, 39, _3byteFormats, 2, TJSAMP_444, "test");
962 return exitStatus;
963}
964
965
966int testFourByte444(int yuv, int noyuvpad, int autoalloc)
967{
968 initTJUnitTest(yuv, noyuvpad, autoalloc);
969
970 int num4bf = doYUV ? 4 : 5;
971 doTest(39, 41, _4byteFormats, num4bf, TJSAMP_444, "test");
972 return exitStatus;
973}
974
975
976int testThreeByte422(int yuv, int noyuvpad, int autoalloc)
977{
978 initTJUnitTest(yuv, noyuvpad, autoalloc);
979
980 doTest(41, 35, _3byteFormats, 2, TJSAMP_422, "test");
981 return exitStatus;
982}
983
984
985int testFourByte422(int yuv, int noyuvpad, int autoalloc)
986{
987 initTJUnitTest(yuv, noyuvpad, autoalloc);
988
989 int num4bf = doYUV ? 4 : 5;
990 doTest(35, 39, _4byteFormats, num4bf, TJSAMP_422, "test");
991 return exitStatus;
992}
993
994
995int testThreeByte420(int yuv, int noyuvpad, int autoalloc)
996{
997 initTJUnitTest(yuv, noyuvpad, autoalloc);
998
999 doTest(39, 41, _3byteFormats, 2, TJSAMP_420, "test");
1000 return exitStatus;
1001}
1002
1003
1004int testFourByte420(int yuv, int noyuvpad, int autoalloc)
1005{
1006 initTJUnitTest(yuv, noyuvpad, autoalloc);
1007
1008 int num4bf = doYUV ? 4 : 5;
1009 doTest(41, 35, _4byteFormats, num4bf, TJSAMP_420, "test");
1010 return exitStatus;
1011}
1012
1013
1014int testThreeByte440(int yuv, int noyuvpad, int autoalloc)
1015{
1016 initTJUnitTest(yuv, noyuvpad, autoalloc);
1017
1018 doTest(35, 39, _3byteFormats, 2, TJSAMP_440, "test");
1019 return exitStatus;
1020}
1021
1022
1023int testFourByte440(int yuv, int noyuvpad, int autoalloc)
1024{
1025 initTJUnitTest(yuv, noyuvpad, autoalloc);
1026
1027 int num4bf = doYUV ? 4 : 5;
1028 doTest(39, 41, _4byteFormats, num4bf, TJSAMP_440, "test");
1029 return exitStatus;
1030}
1031
1032
1033int testThreeByte411(int yuv, int noyuvpad, int autoalloc)
1034{
1035 initTJUnitTest(yuv, noyuvpad, autoalloc);
1036
1037 doTest(41, 35, _3byteFormats, 2, TJSAMP_411, "test");
1038 return exitStatus;
1039}
1040
1041
1042int testFourByte411(int yuv, int noyuvpad, int autoalloc)
1043{
1044 initTJUnitTest(yuv, noyuvpad, autoalloc);
1045
1046 int num4bf = doYUV ? 4 : 5;
1047 doTest(35, 39, _4byteFormats, num4bf, TJSAMP_411, "test");
1048 return exitStatus;
1049}
1050
1051
1052int testOnlyGray(int yuv, int noyuvpad, int autoalloc)
1053{
1054 initTJUnitTest(yuv, noyuvpad, autoalloc);
1055
1056 doTest(39, 41, _onlyGray, 1, TJSAMP_GRAY, "test");
1057 return exitStatus;
1058}
1059
1060
1061int testThreeByteGray(int yuv, int noyuvpad, int autoalloc)
1062{
1063 initTJUnitTest(yuv, noyuvpad, autoalloc);
1064
1065 doTest(41, 35, _3byteFormats, 2, TJSAMP_GRAY, "test");
1066 return exitStatus;
1067}
1068
1069
1070int testFourByteGray(int yuv, int noyuvpad, int autoalloc)
1071{
1072 initTJUnitTest(yuv, noyuvpad, autoalloc);
1073
1074 doTest(35, 39, _4byteFormats, 4, TJSAMP_GRAY, "test");
1075 return exitStatus;
1076}
1077
1078
1079int testBufSize(int yuv, int noyuvpad, int autoalloc)
1080{
1081 initTJUnitTest(yuv, noyuvpad, autoalloc);
1082
1083 bufSizeTest();
1084 return exitStatus;
1085}
1086
1087
1088int testYUVOnlyRGB444(int noyuvpad, int autoalloc)
1089{
1090 initTJUnitTest(1, noyuvpad, autoalloc);
1091
1092 doTest(48, 48, _onlyRGB, 1, TJSAMP_444, "test_yuv0");
1093 return exitStatus;
1094}
1095
1096
1097int testYUVOnlyRGB422(int noyuvpad, int autoalloc)
1098{
1099 initTJUnitTest(1, noyuvpad, autoalloc);
1100
1101 doTest(48, 48, _onlyRGB, 1, TJSAMP_422, "test_yuv0");
1102 return exitStatus;
1103}
1104
1105
1106int testYUVOnlyRGB420(int noyuvpad, int autoalloc)
1107{
1108 initTJUnitTest(1, noyuvpad, autoalloc);
1109
1110 doTest(48, 48, _onlyRGB, 1, TJSAMP_420, "test_yuv0");
1111 return exitStatus;
1112}
1113
1114
1115int testYUVOnlyRGB440(int noyuvpad, int autoalloc)
1116{
1117 initTJUnitTest(1, noyuvpad, autoalloc);
1118
1119 doTest(48, 48, _onlyRGB, 1, TJSAMP_440, "test_yuv0");
1120 return exitStatus;
1121}
1122
1123
1124int testYUVOnlyRGB411(int noyuvpad, int autoalloc)
1125{
1126 initTJUnitTest(1, noyuvpad, autoalloc);
1127
1128 doTest(48, 48, _onlyRGB, 1, TJSAMP_411, "test_yuv0");
1129 return exitStatus;
1130}
1131
1132
1133int testYUVOnlyRGBGray(int noyuvpad, int autoalloc)
1134{
1135 initTJUnitTest(1, noyuvpad, autoalloc);
1136
1137 doTest(48, 48, _onlyRGB, 1, TJSAMP_GRAY, "test_yuv0");
1138 return exitStatus;
1139}
1140
1141
1142int testYUVOnlyGrayGray(int noyuvpad, int autoalloc)
1143{
1144 initTJUnitTest(1, noyuvpad, autoalloc);
1145
1146 doTest(48, 48, _onlyGray, 1, TJSAMP_GRAY, "test_yuv0");
1147 return exitStatus;
1148}
1149
1150#else
1151
1152int main(int argc, char *argv[])
1153{
1154 int i, num4bf = 5;
1155
1156#ifdef _WIN32
1157 srand((unsigned int)time(NULL));
1158#endif
1159 if (argc > 1) {
1160 for (i = 1; i < argc; i++) {
1161 if (!strcasecmp(argv[i], "-yuv")) doYUV = 1;
1162 else if (!strcasecmp(argv[i], "-noyuvpad")) yuvAlign = 1;
1163 else if (!strcasecmp(argv[i], "-alloc")) alloc = 1;
1164 else if (!strcasecmp(argv[i], "-bmp")) return bmpTest();
1165 else usage(argv[0]);
1166 }
1167 }
1168 if (alloc) printf("Testing automatic buffer allocation\n");
1169 if (doYUV) num4bf = 4;
1170 overflowTest();
1171 doTest(35, 39, _3byteFormats, 2, TJSAMP_444, "test");
1172 doTest(39, 41, _4byteFormats, num4bf, TJSAMP_444, "test");
1173 doTest(41, 35, _3byteFormats, 2, TJSAMP_422, "test");
1174 doTest(35, 39, _4byteFormats, num4bf, TJSAMP_422, "test");
1175 doTest(39, 41, _3byteFormats, 2, TJSAMP_420, "test");
1176 doTest(41, 35, _4byteFormats, num4bf, TJSAMP_420, "test");
1177 doTest(35, 39, _3byteFormats, 2, TJSAMP_440, "test");
1178 doTest(39, 41, _4byteFormats, num4bf, TJSAMP_440, "test");
1179 doTest(41, 35, _3byteFormats, 2, TJSAMP_411, "test");
1180 doTest(35, 39, _4byteFormats, num4bf, TJSAMP_411, "test");
1181 doTest(39, 41, _onlyGray, 1, TJSAMP_GRAY, "test");
1182 doTest(41, 35, _3byteFormats, 2, TJSAMP_GRAY, "test");
1183 doTest(35, 39, _4byteFormats, 4, TJSAMP_GRAY, "test");
1184 bufSizeTest();
1185 if (doYUV) {
1186 printf("\n--------------------\n\n");
1187 doTest(48, 48, _onlyRGB, 1, TJSAMP_444, "test_yuv0");
1188 doTest(48, 48, _onlyRGB, 1, TJSAMP_422, "test_yuv0");
1189 doTest(48, 48, _onlyRGB, 1, TJSAMP_420, "test_yuv0");
1190 doTest(48, 48, _onlyRGB, 1, TJSAMP_440, "test_yuv0");
1191 doTest(48, 48, _onlyRGB, 1, TJSAMP_411, "test_yuv0");
1192 doTest(48, 48, _onlyRGB, 1, TJSAMP_GRAY, "test_yuv0");
1193 doTest(48, 48, _onlyGray, 1, TJSAMP_GRAY, "test_yuv0");
1194 }
1195
1196 return exitStatus;
1197}
1198#endif