OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C)2009-2012, 2014 D. R. Commander. All Rights Reserved. | 2 * Copyright (C)2009-2014 D. R. Commander. All Rights Reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are met: | 5 * modification, are permitted provided that the following conditions are met: |
6 * | 6 * |
7 * - Redistributions of source code must retain the above copyright notice, | 7 * - Redistributions of source code must retain the above copyright notice, |
8 * this list of conditions and the following disclaimer. | 8 * this list of conditions and the following disclaimer. |
9 * - Redistributions in binary form must reproduce the above copyright notice, | 9 * - Redistributions in binary form must reproduce the above copyright notice, |
10 * this list of conditions and the following disclaimer in the documentation | 10 * this list of conditions and the following disclaimer in the documentation |
11 * and/or other materials provided with the distribution. | 11 * and/or other materials provided with the distribution. |
12 * - Neither the name of the libjpeg-turbo Project nor the names of its | 12 * - Neither the name of the libjpeg-turbo Project nor the names of its |
(...skipping 27 matching lines...) Expand all Loading... |
40 #include <time.h> | 40 #include <time.h> |
41 #define random() rand() | 41 #define random() rand() |
42 #endif | 42 #endif |
43 | 43 |
44 | 44 |
45 void usage(char *progName) | 45 void usage(char *progName) |
46 { | 46 { |
47 printf("\nUSAGE: %s [options]\n", progName); | 47 printf("\nUSAGE: %s [options]\n", progName); |
48 printf("Options:\n"); | 48 printf("Options:\n"); |
49 printf("-yuv = test YUV encoding/decoding support\n"); | 49 printf("-yuv = test YUV encoding/decoding support\n"); |
| 50 printf("-noyuvpad = do not pad each line of each Y, U, and V plane to th
e nearest\n"); |
| 51 printf(" 4-byte boundary\n"); |
50 printf("-alloc = test automatic buffer allocation\n"); | 52 printf("-alloc = test automatic buffer allocation\n"); |
51 exit(1); | 53 exit(1); |
52 } | 54 } |
53 | 55 |
54 | 56 |
55 #define _throwtj() {printf("TurboJPEG ERROR:\n%s\n", tjGetErrorStr()); \ | 57 #define _throwtj() {printf("TurboJPEG ERROR:\n%s\n", tjGetErrorStr()); \ |
56 bailout();} | 58 bailout();} |
57 #define _tj(f) {if((f)==-1) _throwtj();} | 59 #define _tj(f) {if((f)==-1) _throwtj();} |
58 #define _throw(m) {printf("ERROR: %s\n", m); bailout();} | 60 #define _throw(m) {printf("ERROR: %s\n", m); bailout();} |
59 | 61 |
60 const char *subNameLong[TJ_NUMSAMP]= | 62 const char *subNameLong[TJ_NUMSAMP]= |
61 { | 63 { |
62 » "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0" | 64 » "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1" |
63 }; | 65 }; |
64 const char *subName[TJ_NUMSAMP]={"444", "422", "420", "GRAY", "440"}; | 66 const char *subName[TJ_NUMSAMP]={"444", "422", "420", "GRAY", "440", "411"}; |
65 | 67 |
66 const char *pixFormatStr[TJ_NUMPF]= | 68 const char *pixFormatStr[TJ_NUMPF]= |
67 { | 69 { |
68 "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale", | 70 "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale", |
69 » "RGBA", "BGRA", "ABGR", "ARGB" | 71 » "RGBA", "BGRA", "ABGR", "ARGB", "CMYK" |
70 }; | 72 }; |
71 | 73 |
72 const int alphaOffset[TJ_NUMPF] = {-1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0}; | 74 const int alphaOffset[TJ_NUMPF] = {-1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0, -1}; |
73 | 75 |
74 const int _3byteFormats[]={TJPF_RGB, TJPF_BGR}; | 76 const int _3byteFormats[]={TJPF_RGB, TJPF_BGR}; |
75 const int _4byteFormats[]={TJPF_RGBX, TJPF_BGRX, TJPF_XBGR, TJPF_XRGB}; | 77 const int _4byteFormats[]={TJPF_RGBX, TJPF_BGRX, TJPF_XBGR, TJPF_XRGB, |
| 78 » TJPF_CMYK}; |
76 const int _onlyGray[]={TJPF_GRAY}; | 79 const int _onlyGray[]={TJPF_GRAY}; |
77 const int _onlyRGB[]={TJPF_RGB}; | 80 const int _onlyRGB[]={TJPF_RGB}; |
78 | 81 |
79 enum {YUVENCODE=1, YUVDECODE}; | 82 int doyuv=0, alloc=0, pad=4; |
80 int yuv=0, alloc=0; | |
81 | 83 |
82 int exitStatus=0; | 84 int exitStatus=0; |
83 #define bailout() {exitStatus=-1; goto bailout;} | 85 #define bailout() {exitStatus=-1; goto bailout;} |
84 | 86 |
85 | 87 |
86 void initBuf(unsigned char *buf, int w, int h, int pf, int flags) | 88 void initBuf(unsigned char *buf, int w, int h, int pf, int flags) |
87 { | 89 { |
88 int roffset=tjRedOffset[pf]; | 90 int roffset=tjRedOffset[pf]; |
89 int goffset=tjGreenOffset[pf]; | 91 int goffset=tjGreenOffset[pf]; |
90 int boffset=tjBlueOffset[pf]; | 92 int boffset=tjBlueOffset[pf]; |
91 int ps=tjPixelSize[pf]; | 93 int ps=tjPixelSize[pf]; |
92 int index, row, col, halfway=16; | 94 int index, row, col, halfway=16; |
93 | 95 |
94 memset(buf, 0, w*h*ps); | |
95 if(pf==TJPF_GRAY) | 96 if(pf==TJPF_GRAY) |
96 { | 97 { |
| 98 memset(buf, 0, w*h*ps); |
97 for(row=0; row<h; row++) | 99 for(row=0; row<h; row++) |
98 { | 100 { |
99 for(col=0; col<w; col++) | 101 for(col=0; col<w; col++) |
100 { | 102 { |
101 if(flags&TJFLAG_BOTTOMUP) index=(h-row-1)*w+col; | 103 if(flags&TJFLAG_BOTTOMUP) index=(h-row-1)*w+col; |
102 else index=row*w+col; | 104 else index=row*w+col; |
103 if(((row/8)+(col/8))%2==0) buf[index]=(row<halfw
ay)? 255:0; | 105 if(((row/8)+(col/8))%2==0) buf[index]=(row<halfw
ay)? 255:0; |
104 else buf[index]=(row<halfway)? 76:226; | 106 else buf[index]=(row<halfway)? 76:226; |
105 } | 107 } |
106 } | 108 } |
107 } | 109 } |
| 110 else if(pf==TJPF_CMYK) |
| 111 { |
| 112 memset(buf, 255, w*h*ps); |
| 113 for(row=0; row<h; row++) |
| 114 { |
| 115 for(col=0; col<w; col++) |
| 116 { |
| 117 if(flags&TJFLAG_BOTTOMUP) index=(h-row-1)*w+col; |
| 118 else index=row*w+col; |
| 119 if(((row/8)+(col/8))%2==0) |
| 120 { |
| 121 if(row>=halfway) buf[index*ps+3]=0; |
| 122 } |
| 123 else |
| 124 { |
| 125 buf[index*ps+2]=0; |
| 126 if(row<halfway) buf[index*ps+1]=0; |
| 127 } |
| 128 } |
| 129 } |
| 130 } |
108 else | 131 else |
109 { | 132 { |
| 133 memset(buf, 0, w*h*ps); |
110 for(row=0; row<h; row++) | 134 for(row=0; row<h; row++) |
111 { | 135 { |
112 for(col=0; col<w; col++) | 136 for(col=0; col<w; col++) |
113 { | 137 { |
114 if(flags&TJFLAG_BOTTOMUP) index=(h-row-1)*w+col; | 138 if(flags&TJFLAG_BOTTOMUP) index=(h-row-1)*w+col; |
115 else index=row*w+col; | 139 else index=row*w+col; |
116 if(((row/8)+(col/8))%2==0) | 140 if(((row/8)+(col/8))%2==0) |
117 { | 141 { |
118 if(row<halfway) | 142 if(row<halfway) |
119 { | 143 { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 { | 182 { |
159 int roffset=tjRedOffset[pf]; | 183 int roffset=tjRedOffset[pf]; |
160 int goffset=tjGreenOffset[pf]; | 184 int goffset=tjGreenOffset[pf]; |
161 int boffset=tjBlueOffset[pf]; | 185 int boffset=tjBlueOffset[pf]; |
162 int aoffset=alphaOffset[pf]; | 186 int aoffset=alphaOffset[pf]; |
163 int ps=tjPixelSize[pf]; | 187 int ps=tjPixelSize[pf]; |
164 int index, row, col, retval=1; | 188 int index, row, col, retval=1; |
165 int halfway=16*sf.num/sf.denom; | 189 int halfway=16*sf.num/sf.denom; |
166 int blocksize=8*sf.num/sf.denom; | 190 int blocksize=8*sf.num/sf.denom; |
167 | 191 |
| 192 if(pf==TJPF_CMYK) |
| 193 { |
| 194 for(row=0; row<h; row++) |
| 195 { |
| 196 for(col=0; col<w; col++) |
| 197 { |
| 198 unsigned char c, m, y, k; |
| 199 if(flags&TJFLAG_BOTTOMUP) index=(h-row-1)*w+col; |
| 200 else index=row*w+col; |
| 201 c=buf[index*ps]; |
| 202 m=buf[index*ps+1]; |
| 203 y=buf[index*ps+2]; |
| 204 k=buf[index*ps+3]; |
| 205 if(((row/blocksize)+(col/blocksize))%2==0) |
| 206 { |
| 207 checkval255(c); checkval255(m); checkv
al255(y); |
| 208 if(row<halfway) checkval255(k) |
| 209 else checkval0(k) |
| 210 } |
| 211 else |
| 212 { |
| 213 checkval255(c); checkval0(y); checkval
255(k); |
| 214 if(row<halfway) checkval0(m) |
| 215 else checkval255(m) |
| 216 } |
| 217 } |
| 218 } |
| 219 return 1; |
| 220 } |
| 221 |
168 for(row=0; row<h; row++) | 222 for(row=0; row<h; row++) |
169 { | 223 { |
170 for(col=0; col<w; col++) | 224 for(col=0; col<w; col++) |
171 { | 225 { |
172 unsigned char r, g, b, a; | 226 unsigned char r, g, b, a; |
173 if(flags&TJFLAG_BOTTOMUP) index=(h-row-1)*w+col; | 227 if(flags&TJFLAG_BOTTOMUP) index=(h-row-1)*w+col; |
174 else index=row*w+col; | 228 else index=row*w+col; |
175 r=buf[index*ps+roffset]; | 229 r=buf[index*ps+roffset]; |
176 g=buf[index*ps+goffset]; | 230 g=buf[index*ps+goffset]; |
177 b=buf[index*ps+boffset]; | 231 b=buf[index*ps+boffset]; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 } | 270 } |
217 } | 271 } |
218 | 272 |
219 bailout: | 273 bailout: |
220 if(retval==0) | 274 if(retval==0) |
221 { | 275 { |
222 for(row=0; row<h; row++) | 276 for(row=0; row<h; row++) |
223 { | 277 { |
224 for(col=0; col<w; col++) | 278 for(col=0; col<w; col++) |
225 { | 279 { |
226 » » » » printf("%.3d/%.3d/%.3d ", buf[(row*w+col)*ps+rof
fset], | 280 » » » » if(pf==TJPF_CMYK) |
227 » » » » » buf[(row*w+col)*ps+goffset], buf[(row*w+
col)*ps+boffset]); | 281 » » » » » printf("%.3d/%.3d/%.3d/%.3d ", buf[(row*
w+col)*ps], |
| 282 » » » » » » buf[(row*w+col)*ps+1], buf[(row*
w+col)*ps+2], |
| 283 » » » » » » buf[(row*w+col)*ps+3]); |
| 284 » » » » else |
| 285 » » » » » printf("%.3d/%.3d/%.3d ", buf[(row*w+col
)*ps+roffset], |
| 286 » » » » » » buf[(row*w+col)*ps+goffset], buf
[(row*w+col)*ps+boffset]); |
228 } | 287 } |
229 printf("\n"); | 288 printf("\n"); |
230 } | 289 } |
231 } | 290 } |
232 return retval; | 291 return retval; |
233 } | 292 } |
234 | 293 |
235 | 294 |
236 #define PAD(v, p) ((v+(p)-1)&(~((p)-1))) | 295 #define PAD(v, p) ((v+(p)-1)&(~((p)-1))) |
237 | 296 |
238 int checkBufYUV(unsigned char *buf, int w, int h, int subsamp) | 297 int checkBufYUV(unsigned char *buf, int w, int h, int subsamp, |
| 298 » tjscalingfactor sf) |
239 { | 299 { |
240 int row, col; | 300 int row, col; |
241 int hsf=tjMCUWidth[subsamp]/8, vsf=tjMCUHeight[subsamp]/8; | 301 int hsf=tjMCUWidth[subsamp]/8, vsf=tjMCUHeight[subsamp]/8; |
242 int pw=PAD(w, hsf), ph=PAD(h, vsf); | 302 int pw=PAD(w, hsf), ph=PAD(h, vsf); |
243 int cw=pw/hsf, ch=ph/vsf; | 303 int cw=pw/hsf, ch=ph/vsf; |
244 » int ypitch=PAD(pw, 4), uvpitch=PAD(cw, 4); | 304 » int ypitch=PAD(pw, pad), uvpitch=PAD(cw, pad); |
245 int retval=1; | 305 int retval=1; |
246 » int halfway=16; | 306 » int halfway=16*sf.num/sf.denom; |
| 307 » int blocksize=8*sf.num/sf.denom; |
247 | 308 |
248 for(row=0; row<ph; row++) | 309 for(row=0; row<ph; row++) |
249 { | 310 { |
250 for(col=0; col<pw; col++) | 311 for(col=0; col<pw; col++) |
251 { | 312 { |
252 unsigned char y=buf[ypitch*row+col]; | 313 unsigned char y=buf[ypitch*row+col]; |
253 » » » if(((row/8)+(col/8))%2==0) | 314 » » » if(((row/blocksize)+(col/blocksize))%2==0) |
254 { | 315 { |
255 if(row<halfway) checkval255(y) else checkval0(y
); | 316 if(row<halfway) checkval255(y) else checkval0(y
); |
256 } | 317 } |
257 else | 318 else |
258 { | 319 { |
259 if(row<halfway) checkval(y, 76) else checkval(y
, 226); | 320 if(row<halfway) checkval(y, 76) else checkval(y
, 226); |
260 } | 321 } |
261 } | 322 } |
262 } | 323 } |
263 if(subsamp!=TJSAMP_GRAY) | 324 if(subsamp!=TJSAMP_GRAY) |
264 { | 325 { |
265 » » halfway=16/vsf; | 326 » » int halfway=16/vsf*sf.num/sf.denom; |
266 for(row=0; row<ch; row++) | 327 for(row=0; row<ch; row++) |
267 { | 328 { |
268 for(col=0; col<cw; col++) | 329 for(col=0; col<cw; col++) |
269 { | 330 { |
270 unsigned char u=buf[ypitch*ph + (uvpitch*row+col
)], | 331 unsigned char u=buf[ypitch*ph + (uvpitch*row+col
)], |
271 v=buf[ypitch*ph + uvpitch*ch + (uvpitch*
row+col)]; | 332 v=buf[ypitch*ph + uvpitch*ch + (uvpitch*
row+col)]; |
272 » » » » if(((row*vsf/8)+(col*hsf/8))%2==0) | 333 » » » » if(((row*vsf/blocksize)+(col*hsf/blocksize))%2==
0) |
273 { | 334 { |
274 checkval(u, 128); checkval(v, 128); | 335 checkval(u, 128); checkval(v, 128); |
275 } | 336 } |
276 else | 337 else |
277 { | 338 { |
278 if(row<halfway) | 339 if(row<halfway) |
279 { | 340 { |
280 checkval(u, 85); checkval255(v)
; | 341 checkval(u, 85); checkval255(v)
; |
281 } | 342 } |
282 else | 343 else |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 | 389 |
329 bailout: | 390 bailout: |
330 if(file) fclose(file); | 391 if(file) fclose(file); |
331 } | 392 } |
332 | 393 |
333 | 394 |
334 void compTest(tjhandle handle, unsigned char **dstBuf, | 395 void compTest(tjhandle handle, unsigned char **dstBuf, |
335 unsigned long *dstSize, int w, int h, int pf, char *basename, | 396 unsigned long *dstSize, int w, int h, int pf, char *basename, |
336 int subsamp, int jpegQual, int flags) | 397 int subsamp, int jpegQual, int flags) |
337 { | 398 { |
338 » char tempStr[1024]; unsigned char *srcBuf=NULL; | 399 » char tempStr[1024]; unsigned char *srcBuf=NULL, *yuvBuf=NULL; |
339 » double t; | 400 » const char *pfStr=pixFormatStr[pf]; |
340 | 401 » const char *buStrLong=(flags&TJFLAG_BOTTOMUP)? "Bottom-Up":"Top-Down "; |
341 » if(yuv==YUVENCODE) | 402 » const char *buStr=(flags&TJFLAG_BOTTOMUP)? "BU":"TD"; |
342 » » printf("%s %s -> %s YUV ... ", pixFormatStr[pf], | |
343 » » » (flags&TJFLAG_BOTTOMUP)? "Bottom-Up":"Top-Down ", subNam
eLong[subsamp]); | |
344 » else | |
345 » » printf("%s %s -> %s Q%d ... ", pixFormatStr[pf], | |
346 » » » (flags&TJFLAG_BOTTOMUP)? "Bottom-Up":"Top-Down ", subNam
eLong[subsamp], | |
347 » » » jpegQual); | |
348 | 403 |
349 if((srcBuf=(unsigned char *)malloc(w*h*tjPixelSize[pf]))==NULL) | 404 if((srcBuf=(unsigned char *)malloc(w*h*tjPixelSize[pf]))==NULL) |
350 _throw("Memory allocation failure"); | 405 _throw("Memory allocation failure"); |
351 initBuf(srcBuf, w, h, pf, flags); | 406 initBuf(srcBuf, w, h, pf, flags); |
| 407 |
352 if(*dstBuf && *dstSize>0) memset(*dstBuf, 0, *dstSize); | 408 if(*dstBuf && *dstSize>0) memset(*dstBuf, 0, *dstSize); |
353 | 409 |
354 » t=gettime(); | 410 |
355 » if(yuv==YUVENCODE) | 411 » if(!alloc) flags|=TJFLAG_NOREALLOC; |
| 412 » if(doyuv) |
356 { | 413 { |
357 » » _tj(tjEncodeYUV2(handle, srcBuf, w, 0, h, pf, *dstBuf, subsamp,
flags)); | 414 » » unsigned long yuvSize=tjBufSizeYUV2(w, pad, h, subsamp); |
| 415 » » tjscalingfactor sf={1, 1}; |
| 416 » » tjhandle handle2=tjInitCompress(); |
| 417 » » if(!handle2) _throwtj(); |
| 418 |
| 419 » » if((yuvBuf=(unsigned char *)malloc(yuvSize))==NULL) |
| 420 » » » _throw("Memory allocation failure"); |
| 421 » » memset(yuvBuf, 0, yuvSize); |
| 422 |
| 423 » » printf("%s %s -> YUV %s ... ", pfStr, buStrLong, subNameLong[sub
samp]); |
| 424 » » _tj(tjEncodeYUV3(handle2, srcBuf, w, 0, h, pf, yuvBuf, pad, subs
amp, |
| 425 » » » flags)); |
| 426 » » tjDestroy(handle2); |
| 427 » » if(checkBufYUV(yuvBuf, w, h, subsamp, sf)) printf("Passed.\n"); |
| 428 » » else printf("FAILED!\n"); |
| 429 |
| 430 » » printf("YUV %s %s -> JPEG Q%d ... ", subNameLong[subsamp], buStr
Long, |
| 431 » » » jpegQual); |
| 432 » » _tj(tjCompressFromYUV(handle, yuvBuf, w, pad, h, subsamp, dstBuf
, |
| 433 » » » dstSize, jpegQual, flags)); |
358 } | 434 } |
359 else | 435 else |
360 { | 436 { |
361 » » if(!alloc) | 437 » » printf("%s %s -> %s Q%d ... ", pfStr, buStrLong, subNameLong[sub
samp], |
362 » » { | 438 » » » jpegQual); |
363 » » » flags|=TJFLAG_NOREALLOC; | |
364 » » » *dstSize=(yuv==YUVENCODE? tjBufSizeYUV(w, h, subsamp) | |
365 » » » » : tjBufSize(w, h, subsamp)); | |
366 » » } | |
367 _tj(tjCompress2(handle, srcBuf, w, 0, h, pf, dstBuf, dstSize, su
bsamp, | 439 _tj(tjCompress2(handle, srcBuf, w, 0, h, pf, dstBuf, dstSize, su
bsamp, |
368 jpegQual, flags)); | 440 jpegQual, flags)); |
369 } | 441 } |
370 t=gettime()-t; | |
371 | 442 |
372 » if(yuv==YUVENCODE) | 443 » snprintf(tempStr, 1024, "%s_enc_%s_%s_%s_Q%d.jpg", basename, pfStr, buSt
r, |
373 » » snprintf(tempStr, 1024, "%s_enc_%s_%s_%s.yuv", basename, pixForm
atStr[pf], | 444 » » subName[subsamp], jpegQual); |
374 » » » (flags&TJFLAG_BOTTOMUP)? "BU":"TD", subName[subsamp]); | |
375 » else | |
376 » » snprintf(tempStr, 1024, "%s_enc_%s_%s_%s_Q%d.jpg", basename, | |
377 » » » pixFormatStr[pf], (flags&TJFLAG_BOTTOMUP)? "BU":"TD", su
bName[subsamp], | |
378 » » » jpegQual); | |
379 writeJPEG(*dstBuf, *dstSize, tempStr); | 445 writeJPEG(*dstBuf, *dstSize, tempStr); |
380 » if(yuv==YUVENCODE) | 446 » printf("Done.\n Result in %s\n", tempStr); |
381 » { | |
382 » » if(checkBufYUV(*dstBuf, w, h, subsamp)) printf("Passed."); | |
383 » » else printf("FAILED!"); | |
384 » } | |
385 » else printf("Done."); | |
386 » printf(" %f ms\n Result in %s\n", t*1000., tempStr); | |
387 | 447 |
388 bailout: | 448 bailout: |
| 449 if(yuvBuf) free(yuvBuf); |
389 if(srcBuf) free(srcBuf); | 450 if(srcBuf) free(srcBuf); |
390 } | 451 } |
391 | 452 |
392 | 453 |
393 void _decompTest(tjhandle handle, unsigned char *jpegBuf, | 454 void _decompTest(tjhandle handle, unsigned char *jpegBuf, |
394 unsigned long jpegSize, int w, int h, int pf, char *basename, int subsam
p, | 455 unsigned long jpegSize, int w, int h, int pf, char *basename, int subsam
p, |
395 int flags, tjscalingfactor sf) | 456 int flags, tjscalingfactor sf) |
396 { | 457 { |
397 » unsigned char *dstBuf=NULL; | 458 » unsigned char *dstBuf=NULL, *yuvBuf=NULL; |
398 » int _hdrw=0, _hdrh=0, _hdrsubsamp=-1; double t; | 459 » int _hdrw=0, _hdrh=0, _hdrsubsamp=-1; |
399 int scaledWidth=TJSCALED(w, sf); | 460 int scaledWidth=TJSCALED(w, sf); |
400 int scaledHeight=TJSCALED(h, sf); | 461 int scaledHeight=TJSCALED(h, sf); |
401 unsigned long dstSize=0; | 462 unsigned long dstSize=0; |
402 | 463 |
403 » if(yuv==YUVENCODE) return; | 464 » _tj(tjDecompressHeader2(handle, jpegBuf, jpegSize, &_hdrw, &_hdrh, |
| 465 » » &_hdrsubsamp)); |
| 466 » if(_hdrw!=w || _hdrh!=h || _hdrsubsamp!=subsamp) |
| 467 » » _throw("Incorrect JPEG header"); |
404 | 468 |
405 » if(yuv==YUVDECODE) | 469 » dstSize=scaledWidth*scaledHeight*tjPixelSize[pf]; |
406 » » printf("JPEG -> YUV %s ... ", subNameLong[subsamp]); | 470 » if((dstBuf=(unsigned char *)malloc(dstSize))==NULL) |
| 471 » » _throw("Memory allocation failure"); |
| 472 » memset(dstBuf, 0, dstSize); |
| 473 |
| 474 » if(doyuv) |
| 475 » { |
| 476 » » unsigned long yuvSize=tjBufSizeYUV2(scaledWidth, pad, scaledHeig
ht, |
| 477 » » » subsamp); |
| 478 » » tjhandle handle2=tjInitDecompress(); |
| 479 » » if(!handle2) _throwtj(); |
| 480 |
| 481 » » if((yuvBuf=(unsigned char *)malloc(yuvSize))==NULL) |
| 482 » » » _throw("Memory allocation failure"); |
| 483 » » memset(yuvBuf, 0, yuvSize); |
| 484 |
| 485 » » printf("JPEG -> YUV %s ", subNameLong[subsamp]); |
| 486 » » if(sf.num!=1 || sf.denom!=1) |
| 487 » » » printf("%d/%d ... ", sf.num, sf.denom); |
| 488 » » else printf("... "); |
| 489 » » _tj(tjDecompressToYUV2(handle, jpegBuf, jpegSize, yuvBuf, scaled
Width, |
| 490 » » » pad, scaledHeight, flags)); |
| 491 » » if(checkBufYUV(yuvBuf, scaledWidth, scaledHeight, subsamp, sf)) |
| 492 » » » printf("Passed.\n"); |
| 493 » » else printf("FAILED!\n"); |
| 494 |
| 495 » » printf("YUV %s -> %s %s ... ", subNameLong[subsamp], pixFormatSt
r[pf], |
| 496 » » » (flags&TJFLAG_BOTTOMUP)? "Bottom-Up":"Top-Down "); |
| 497 » » _tj(tjDecodeYUV(handle2, yuvBuf, pad, subsamp, dstBuf, scaledWid
th, 0, |
| 498 » » » scaledHeight, pf, flags)); |
| 499 » » tjDestroy(handle2); |
| 500 » } |
407 else | 501 else |
408 { | 502 { |
409 printf("JPEG -> %s %s ", pixFormatStr[pf], | 503 printf("JPEG -> %s %s ", pixFormatStr[pf], |
410 (flags&TJFLAG_BOTTOMUP)? "Bottom-Up":"Top-Down "); | 504 (flags&TJFLAG_BOTTOMUP)? "Bottom-Up":"Top-Down "); |
411 if(sf.num!=1 || sf.denom!=1) | 505 if(sf.num!=1 || sf.denom!=1) |
412 printf("%d/%d ... ", sf.num, sf.denom); | 506 printf("%d/%d ... ", sf.num, sf.denom); |
413 else printf("... "); | 507 else printf("... "); |
414 } | |
415 | |
416 _tj(tjDecompressHeader2(handle, jpegBuf, jpegSize, &_hdrw, &_hdrh, | |
417 &_hdrsubsamp)); | |
418 if(_hdrw!=w || _hdrh!=h || _hdrsubsamp!=subsamp) | |
419 _throw("Incorrect JPEG header"); | |
420 | |
421 if(yuv==YUVDECODE) dstSize=tjBufSizeYUV(w, h, subsamp); | |
422 else dstSize=scaledWidth*scaledHeight*tjPixelSize[pf]; | |
423 if((dstBuf=(unsigned char *)malloc(dstSize))==NULL) | |
424 _throw("Memory allocation failure"); | |
425 memset(dstBuf, 0, dstSize); | |
426 | |
427 t=gettime(); | |
428 if(yuv==YUVDECODE) | |
429 { | |
430 _tj(tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flags))
; | |
431 } | |
432 else | |
433 { | |
434 _tj(tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, scaledWidth
, 0, | 508 _tj(tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, scaledWidth
, 0, |
435 scaledHeight, pf, flags)); | 509 scaledHeight, pf, flags)); |
436 } | 510 } |
437 t=gettime()-t; | |
438 | 511 |
439 » if(yuv==YUVDECODE) | 512 » if(checkBuf(dstBuf, scaledWidth, scaledHeight, pf, subsamp, sf, flags)) |
440 » { | 513 » » printf("Passed."); |
441 » » if(checkBufYUV(dstBuf, w, h, subsamp)) printf("Passed."); | 514 » else printf("FAILED!"); |
442 » » else printf("FAILED!"); | 515 » printf("\n"); |
443 » } | |
444 » else | |
445 » { | |
446 » » if(checkBuf(dstBuf, scaledWidth, scaledHeight, pf, subsamp, sf,
flags)) | |
447 » » » printf("Passed."); | |
448 » » else printf("FAILED!"); | |
449 » } | |
450 » printf(" %f ms\n", t*1000.); | |
451 | 516 |
452 bailout: | 517 bailout: |
| 518 if(yuvBuf) free(yuvBuf); |
453 if(dstBuf) free(dstBuf); | 519 if(dstBuf) free(dstBuf); |
454 } | 520 } |
455 | 521 |
456 | 522 |
457 void decompTest(tjhandle handle, unsigned char *jpegBuf, | 523 void decompTest(tjhandle handle, unsigned char *jpegBuf, |
458 unsigned long jpegSize, int w, int h, int pf, char *basename, int subsam
p, | 524 unsigned long jpegSize, int w, int h, int pf, char *basename, int subsam
p, |
459 int flags) | 525 int flags) |
460 { | 526 { |
461 int i, n=0; | 527 int i, n=0; |
462 » tjscalingfactor *sf=tjGetScalingFactors(&n), sf1={1, 1}; | 528 » tjscalingfactor *sf=tjGetScalingFactors(&n); |
463 if(!sf || !n) _throwtj(); | 529 if(!sf || !n) _throwtj(); |
464 | 530 |
465 » if((subsamp==TJSAMP_444 || subsamp==TJSAMP_GRAY) && !yuv) | 531 » for(i=0; i<n; i++) |
466 { | 532 { |
467 » » for(i=0; i<n; i++) | 533 » » if(subsamp==TJSAMP_444 || subsamp==TJSAMP_GRAY || |
| 534 » » » (subsamp==TJSAMP_411 && sf[i].num==1 && |
| 535 » » » » (sf[i].denom==2 || sf[i].denom==1)) || |
| 536 » » » (subsamp!=TJSAMP_411 && sf[i].num==1 && |
| 537 » » » » (sf[i].denom==4 || sf[i].denom==2 || sf[i].denom
==1))) |
468 _decompTest(handle, jpegBuf, jpegSize, w, h, pf, basenam
e, subsamp, | 538 _decompTest(handle, jpegBuf, jpegSize, w, h, pf, basenam
e, subsamp, |
469 flags, sf[i]); | 539 flags, sf[i]); |
470 } | 540 } |
471 else | |
472 _decompTest(handle, jpegBuf, jpegSize, w, h, pf, basename, subsa
mp, flags, | |
473 sf1); | |
474 | 541 |
475 bailout: | 542 bailout: |
476 return; | 543 return; |
477 } | 544 } |
478 | 545 |
479 | 546 |
480 void doTest(int w, int h, const int *formats, int nformats, int subsamp, | 547 void doTest(int w, int h, const int *formats, int nformats, int subsamp, |
481 char *basename) | 548 char *basename) |
482 { | 549 { |
483 tjhandle chandle=NULL, dhandle=NULL; | 550 tjhandle chandle=NULL, dhandle=NULL; |
484 unsigned char *dstBuf=NULL; | 551 unsigned char *dstBuf=NULL; |
485 unsigned long size=0; int pfi, pf, i; | 552 unsigned long size=0; int pfi, pf, i; |
486 | 553 |
487 if(!alloc) | 554 if(!alloc) |
488 » { | 555 » » size=tjBufSize(w, h, subsamp); |
489 » » size=(yuv==YUVENCODE? tjBufSizeYUV(w, h, subsamp) | 556 » if(size!=0) |
490 » » » : tjBufSize(w, h, subsamp)); | |
491 if((dstBuf=(unsigned char *)tjAlloc(size))==NULL) | 557 if((dstBuf=(unsigned char *)tjAlloc(size))==NULL) |
492 _throw("Memory allocation failure."); | 558 _throw("Memory allocation failure."); |
493 } | |
494 | 559 |
495 if((chandle=tjInitCompress())==NULL || (dhandle=tjInitDecompress())==NUL
L) | 560 if((chandle=tjInitCompress())==NULL || (dhandle=tjInitDecompress())==NUL
L) |
496 _throwtj(); | 561 _throwtj(); |
497 | 562 |
498 for(pfi=0; pfi<nformats; pfi++) | 563 for(pfi=0; pfi<nformats; pfi++) |
499 { | 564 { |
500 for(i=0; i<2; i++) | 565 for(i=0; i<2; i++) |
501 { | 566 { |
502 int flags=0; | 567 int flags=0; |
503 » » » if(subsamp==TJSAMP_422 || subsamp==TJSAMP_420 || subsamp
==TJSAMP_440) | 568 » » » if(subsamp==TJSAMP_422 || subsamp==TJSAMP_420 || subsamp
==TJSAMP_440 || |
| 569 » » » » subsamp==TJSAMP_411) |
504 flags|=TJFLAG_FASTUPSAMPLE; | 570 flags|=TJFLAG_FASTUPSAMPLE; |
505 » » » if(i==1) | 571 » » » if(i==1) flags|=TJFLAG_BOTTOMUP; |
506 » » » { | |
507 » » » » if(yuv==YUVDECODE) goto bailout; | |
508 » » » » else flags|=TJFLAG_BOTTOMUP; | |
509 » » » } | |
510 pf=formats[pfi]; | 572 pf=formats[pfi]; |
511 compTest(chandle, &dstBuf, &size, w, h, pf, basename, su
bsamp, 100, | 573 compTest(chandle, &dstBuf, &size, w, h, pf, basename, su
bsamp, 100, |
512 flags); | 574 flags); |
513 decompTest(dhandle, dstBuf, size, w, h, pf, basename, su
bsamp, | 575 decompTest(dhandle, dstBuf, size, w, h, pf, basename, su
bsamp, |
514 flags); | 576 flags); |
515 if(pf>=TJPF_RGBX && pf<=TJPF_XRGB) | 577 if(pf>=TJPF_RGBX && pf<=TJPF_XRGB) |
516 { | 578 { |
517 printf("\n"); | 579 printf("\n"); |
518 decompTest(dhandle, dstBuf, size, w, h, pf+(TJPF
_RGBA-TJPF_RGBX), | 580 decompTest(dhandle, dstBuf, size, w, h, pf+(TJPF
_RGBA-TJPF_RGBX), |
519 basename, subsamp, flags); | 581 basename, subsamp, flags); |
(...skipping 24 matching lines...) Expand all Loading... |
544 for(subsamp=0; subsamp<TJ_NUMSAMP; subsamp++) | 606 for(subsamp=0; subsamp<TJ_NUMSAMP; subsamp++) |
545 { | 607 { |
546 for(w=1; w<48; w++) | 608 for(w=1; w<48; w++) |
547 { | 609 { |
548 int maxh=(w==1)? 2048:48; | 610 int maxh=(w==1)? 2048:48; |
549 for(h=1; h<maxh; h++) | 611 for(h=1; h<maxh; h++) |
550 { | 612 { |
551 if(h%100==0) printf("%.4d x %.4d\b\b\b\b\b\b\b\b
\b\b\b", w, h); | 613 if(h%100==0) printf("%.4d x %.4d\b\b\b\b\b\b\b\b
\b\b\b", w, h); |
552 if((srcBuf=(unsigned char *)malloc(w*h*4))==NULL
) | 614 if((srcBuf=(unsigned char *)malloc(w*h*4))==NULL
) |
553 _throw("Memory allocation failure"); | 615 _throw("Memory allocation failure"); |
554 » » » » if(!alloc || yuv==YUVENCODE) | 616 » » » » if(!alloc || doyuv) |
555 { | 617 { |
556 » » » » » if(yuv==YUVENCODE) dstSize=tjBufSizeYUV(
w, h, subsamp); | 618 » » » » » if(doyuv) dstSize=tjBufSizeYUV2(w, pad,
h, subsamp); |
557 else dstSize=tjBufSize(w, h, subsamp); | 619 else dstSize=tjBufSize(w, h, subsamp); |
558 if((dstBuf=(unsigned char *)tjAlloc(dstS
ize))==NULL) | 620 if((dstBuf=(unsigned char *)tjAlloc(dstS
ize))==NULL) |
559 _throw("Memory allocation failur
e"); | 621 _throw("Memory allocation failur
e"); |
560 } | 622 } |
561 | 623 |
562 for(i=0; i<w*h*4; i++) | 624 for(i=0; i<w*h*4; i++) |
563 { | 625 { |
564 if(random()<RAND_MAX/2) srcBuf[i]=0; | 626 if(random()<RAND_MAX/2) srcBuf[i]=0; |
565 else srcBuf[i]=255; | 627 else srcBuf[i]=255; |
566 } | 628 } |
567 | 629 |
568 » » » » if(yuv==YUVENCODE) | 630 » » » » if(doyuv) |
569 { | 631 { |
570 » » » » » _tj(tjEncodeYUV2(handle, srcBuf, w, 0, h
, TJPF_BGRX, dstBuf, subsamp, | 632 » » » » » _tj(tjEncodeYUV3(handle, srcBuf, w, 0, h
, TJPF_BGRX, dstBuf, pad, |
571 » » » » » » 0)); | 633 » » » » » » subsamp, 0)); |
572 } | 634 } |
573 else | 635 else |
574 { | 636 { |
575 _tj(tjCompress2(handle, srcBuf, w, 0, h,
TJPF_BGRX, &dstBuf, | 637 _tj(tjCompress2(handle, srcBuf, w, 0, h,
TJPF_BGRX, &dstBuf, |
576 &dstSize, subsamp, 100, alloc? 0
:TJFLAG_NOREALLOC)); | 638 &dstSize, subsamp, 100, alloc? 0
:TJFLAG_NOREALLOC)); |
577 } | 639 } |
578 free(srcBuf); srcBuf=NULL; | 640 free(srcBuf); srcBuf=NULL; |
579 » » » » tjFree(dstBuf); dstBuf=NULL; | 641 » » » » if(!alloc || doyuv) |
| 642 » » » » { |
| 643 » » » » » tjFree(dstBuf); dstBuf=NULL; |
| 644 » » » » } |
580 | 645 |
581 if((srcBuf=(unsigned char *)malloc(h*w*4))==NULL
) | 646 if((srcBuf=(unsigned char *)malloc(h*w*4))==NULL
) |
582 _throw("Memory allocation failure"); | 647 _throw("Memory allocation failure"); |
583 » » » » if(!alloc || yuv==YUVENCODE) | 648 » » » » if(!alloc || doyuv) |
584 { | 649 { |
585 » » » » » if(yuv==YUVENCODE) dstSize=tjBufSizeYUV(
h, w, subsamp); | 650 » » » » » if(doyuv) dstSize=tjBufSizeYUV2(h, pad,
w, subsamp); |
586 else dstSize=tjBufSize(h, w, subsamp); | 651 else dstSize=tjBufSize(h, w, subsamp); |
587 if((dstBuf=(unsigned char *)tjAlloc(dstS
ize))==NULL) | 652 if((dstBuf=(unsigned char *)tjAlloc(dstS
ize))==NULL) |
588 _throw("Memory allocation failur
e"); | 653 _throw("Memory allocation failur
e"); |
589 } | 654 } |
590 | 655 |
591 for(i=0; i<h*w*4; i++) | 656 for(i=0; i<h*w*4; i++) |
592 { | 657 { |
593 if(random()<RAND_MAX/2) srcBuf[i]=0; | 658 if(random()<RAND_MAX/2) srcBuf[i]=0; |
594 else srcBuf[i]=255; | 659 else srcBuf[i]=255; |
595 } | 660 } |
596 | 661 |
597 » » » » if(yuv==YUVENCODE) | 662 » » » » if(doyuv) |
598 { | 663 { |
599 » » » » » _tj(tjEncodeYUV2(handle, srcBuf, h, 0, w
, TJPF_BGRX, dstBuf, subsamp, | 664 » » » » » _tj(tjEncodeYUV3(handle, srcBuf, h, 0, w
, TJPF_BGRX, dstBuf, pad, |
600 » » » » » » 0)); | 665 » » » » » » subsamp, 0)); |
601 } | 666 } |
602 else | 667 else |
603 { | 668 { |
604 _tj(tjCompress2(handle, srcBuf, h, 0, w,
TJPF_BGRX, &dstBuf, | 669 _tj(tjCompress2(handle, srcBuf, h, 0, w,
TJPF_BGRX, &dstBuf, |
605 &dstSize, subsamp, 100, alloc? 0
:TJFLAG_NOREALLOC)); | 670 &dstSize, subsamp, 100, alloc? 0
:TJFLAG_NOREALLOC)); |
606 } | 671 } |
607 free(srcBuf); srcBuf=NULL; | 672 free(srcBuf); srcBuf=NULL; |
608 » » » » tjFree(dstBuf); dstBuf=NULL; | 673 » » » » if(!alloc || doyuv) |
| 674 » » » » { |
| 675 » » » » » tjFree(dstBuf); dstBuf=NULL; |
| 676 » » » » } |
609 } | 677 } |
610 } | 678 } |
611 } | 679 } |
612 printf("Done. \n"); | 680 printf("Done. \n"); |
613 | 681 |
614 bailout: | 682 bailout: |
615 if(srcBuf) free(srcBuf); | 683 if(srcBuf) free(srcBuf); |
616 » if(dstBuf) free(dstBuf); | 684 » if(dstBuf) tjFree(dstBuf); |
617 if(handle) tjDestroy(handle); | 685 if(handle) tjDestroy(handle); |
618 } | 686 } |
619 | 687 |
620 | 688 |
621 int main(int argc, char *argv[]) | 689 int main(int argc, char *argv[]) |
622 { | 690 { |
623 » int doyuv=0, i; | 691 » int i, num4bf=5; |
624 #ifdef _WIN32 | 692 #ifdef _WIN32 |
625 srand((unsigned int)time(NULL)); | 693 srand((unsigned int)time(NULL)); |
626 #endif | 694 #endif |
627 if(argc>1) | 695 if(argc>1) |
628 { | 696 { |
629 for(i=1; i<argc; i++) | 697 for(i=1; i<argc; i++) |
630 { | 698 { |
631 if(!strcasecmp(argv[i], "-yuv")) doyuv=1; | 699 if(!strcasecmp(argv[i], "-yuv")) doyuv=1; |
| 700 if(!strcasecmp(argv[i], "-noyuvpad")) pad=1; |
632 if(!strcasecmp(argv[i], "-alloc")) alloc=1; | 701 if(!strcasecmp(argv[i], "-alloc")) alloc=1; |
633 if(!strncasecmp(argv[i], "-h", 2) || !strcasecmp(argv[i]
, "-?")) | 702 if(!strncasecmp(argv[i], "-h", 2) || !strcasecmp(argv[i]
, "-?")) |
634 usage(argv[0]); | 703 usage(argv[0]); |
635 } | 704 } |
636 } | 705 } |
637 if(alloc) printf("Testing automatic buffer allocation\n"); | 706 if(alloc) printf("Testing automatic buffer allocation\n"); |
638 » if(doyuv) {yuv=YUVENCODE; alloc=0;} | 707 » if(doyuv) num4bf=4; |
639 doTest(35, 39, _3byteFormats, 2, TJSAMP_444, "test"); | 708 doTest(35, 39, _3byteFormats, 2, TJSAMP_444, "test"); |
640 » doTest(39, 41, _4byteFormats, 4, TJSAMP_444, "test"); | 709 » doTest(39, 41, _4byteFormats, num4bf, TJSAMP_444, "test"); |
641 doTest(41, 35, _3byteFormats, 2, TJSAMP_422, "test"); | 710 doTest(41, 35, _3byteFormats, 2, TJSAMP_422, "test"); |
642 » doTest(35, 39, _4byteFormats, 4, TJSAMP_422, "test"); | 711 » doTest(35, 39, _4byteFormats, num4bf, TJSAMP_422, "test"); |
643 doTest(39, 41, _3byteFormats, 2, TJSAMP_420, "test"); | 712 doTest(39, 41, _3byteFormats, 2, TJSAMP_420, "test"); |
644 » doTest(41, 35, _4byteFormats, 4, TJSAMP_420, "test"); | 713 » doTest(41, 35, _4byteFormats, num4bf, TJSAMP_420, "test"); |
645 doTest(35, 39, _3byteFormats, 2, TJSAMP_440, "test"); | 714 doTest(35, 39, _3byteFormats, 2, TJSAMP_440, "test"); |
646 » doTest(39, 41, _4byteFormats, 4, TJSAMP_440, "test"); | 715 » doTest(39, 41, _4byteFormats, num4bf, TJSAMP_440, "test"); |
647 » doTest(35, 39, _onlyGray, 1, TJSAMP_GRAY, "test"); | 716 » doTest(41, 35, _3byteFormats, 2, TJSAMP_411, "test"); |
648 » doTest(39, 41, _3byteFormats, 2, TJSAMP_GRAY, "test"); | 717 » doTest(35, 39, _4byteFormats, num4bf, TJSAMP_411, "test"); |
649 » doTest(41, 35, _4byteFormats, 4, TJSAMP_GRAY, "test"); | 718 » doTest(39, 41, _onlyGray, 1, TJSAMP_GRAY, "test"); |
| 719 » doTest(41, 35, _3byteFormats, 2, TJSAMP_GRAY, "test"); |
| 720 » doTest(35, 39, _4byteFormats, 4, TJSAMP_GRAY, "test"); |
650 bufSizeTest(); | 721 bufSizeTest(); |
651 if(doyuv) | 722 if(doyuv) |
652 { | 723 { |
653 printf("\n--------------------\n\n"); | 724 printf("\n--------------------\n\n"); |
654 yuv=YUVDECODE; | |
655 doTest(48, 48, _onlyRGB, 1, TJSAMP_444, "test_yuv0"); | 725 doTest(48, 48, _onlyRGB, 1, TJSAMP_444, "test_yuv0"); |
656 doTest(35, 39, _onlyRGB, 1, TJSAMP_444, "test_yuv1"); | |
657 doTest(48, 48, _onlyRGB, 1, TJSAMP_422, "test_yuv0"); | 726 doTest(48, 48, _onlyRGB, 1, TJSAMP_422, "test_yuv0"); |
658 doTest(39, 41, _onlyRGB, 1, TJSAMP_422, "test_yuv1"); | |
659 doTest(48, 48, _onlyRGB, 1, TJSAMP_420, "test_yuv0"); | 727 doTest(48, 48, _onlyRGB, 1, TJSAMP_420, "test_yuv0"); |
660 doTest(41, 35, _onlyRGB, 1, TJSAMP_420, "test_yuv1"); | |
661 doTest(48, 48, _onlyRGB, 1, TJSAMP_440, "test_yuv0"); | 728 doTest(48, 48, _onlyRGB, 1, TJSAMP_440, "test_yuv0"); |
662 » » doTest(35, 39, _onlyRGB, 1, TJSAMP_440, "test_yuv1"); | 729 » » doTest(48, 48, _onlyRGB, 1, TJSAMP_411, "test_yuv0"); |
663 doTest(48, 48, _onlyRGB, 1, TJSAMP_GRAY, "test_yuv0"); | 730 doTest(48, 48, _onlyRGB, 1, TJSAMP_GRAY, "test_yuv0"); |
664 doTest(35, 39, _onlyRGB, 1, TJSAMP_GRAY, "test_yuv1"); | |
665 doTest(48, 48, _onlyGray, 1, TJSAMP_GRAY, "test_yuv0"); | 731 doTest(48, 48, _onlyGray, 1, TJSAMP_GRAY, "test_yuv0"); |
666 doTest(39, 41, _onlyGray, 1, TJSAMP_GRAY, "test_yuv1"); | |
667 } | 732 } |
668 | 733 |
669 return exitStatus; | 734 return exitStatus; |
670 } | 735 } |
OLD | NEW |