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