• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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