| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C)2009-2011 D. R. Commander. All Rights Reserved. | 2 * Copyright (C)2009-2012 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 } tjinstance; | 85 } tjinstance; |
| 86 | 86 |
| 87 static const int pixelsize[TJ_NUMSAMP]={3, 3, 3, 1, 3}; | 87 static const int pixelsize[TJ_NUMSAMP]={3, 3, 3, 1, 3}; |
| 88 | 88 |
| 89 static const JXFORM_CODE xformtypes[TJ_NUMXOP]= | 89 static const JXFORM_CODE xformtypes[TJ_NUMXOP]= |
| 90 { | 90 { |
| 91 JXFORM_NONE, JXFORM_FLIP_H, JXFORM_FLIP_V, JXFORM_TRANSPOSE, | 91 JXFORM_NONE, JXFORM_FLIP_H, JXFORM_FLIP_V, JXFORM_TRANSPOSE, |
| 92 JXFORM_TRANSVERSE, JXFORM_ROT_90, JXFORM_ROT_180, JXFORM_ROT_270 | 92 JXFORM_TRANSVERSE, JXFORM_ROT_90, JXFORM_ROT_180, JXFORM_ROT_270 |
| 93 }; | 93 }; |
| 94 | 94 |
| 95 #define NUMSF 4 | 95 #define NUMSF 16 |
| 96 static const tjscalingfactor sf[NUMSF]={ | 96 static const tjscalingfactor sf[NUMSF]={ |
| 97 {2, 1}, |
| 98 {15, 8}, |
| 99 {7, 4}, |
| 100 {13, 8}, |
| 101 {3, 2}, |
| 102 {11, 8}, |
| 103 {5, 4}, |
| 104 {9, 8}, |
| 97 {1, 1}, | 105 {1, 1}, |
| 106 {7, 8}, |
| 107 {3, 4}, |
| 108 {5, 8}, |
| 98 {1, 2}, | 109 {1, 2}, |
| 110 {3, 8}, |
| 99 {1, 4}, | 111 {1, 4}, |
| 100 {1, 8} | 112 {1, 8} |
| 101 }; | 113 }; |
| 102 | 114 |
| 103 #define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \ | 115 #define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \ |
| 104 retval=-1; goto bailout;} | 116 retval=-1; goto bailout;} |
| 105 #define getinstance(handle) tjinstance *this=(tjinstance *)handle; \ | 117 #define getinstance(handle) tjinstance *this=(tjinstance *)handle; \ |
| 106 j_compress_ptr cinfo=NULL; j_decompress_ptr dinfo=NULL; \ | 118 j_compress_ptr cinfo=NULL; j_decompress_ptr dinfo=NULL; \ |
| 107 if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ | 119 if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ |
| 108 return -1;} \ | 120 return -1;} \ |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 case TJPF_BGRA: | 165 case TJPF_BGRA: |
| 154 cinfo->in_color_space=JCS_EXT_BGRX; break; | 166 cinfo->in_color_space=JCS_EXT_BGRX; break; |
| 155 case TJPF_XRGB: | 167 case TJPF_XRGB: |
| 156 case TJPF_ARGB: | 168 case TJPF_ARGB: |
| 157 cinfo->in_color_space=JCS_EXT_XRGB; break; | 169 cinfo->in_color_space=JCS_EXT_XRGB; break; |
| 158 case TJPF_XBGR: | 170 case TJPF_XBGR: |
| 159 case TJPF_ABGR: | 171 case TJPF_ABGR: |
| 160 cinfo->in_color_space=JCS_EXT_XBGR; break; | 172 cinfo->in_color_space=JCS_EXT_XBGR; break; |
| 161 #else | 173 #else |
| 162 case TJPF_RGB: | 174 case TJPF_RGB: |
| 163 » » » if(RGB_RED==0 && RGB_GREEN==1 && RGB_BLUE==2 && RGB_PIXE
LSIZE==3) | 175 » » case TJPF_BGR: |
| 164 » » » { | 176 » » case TJPF_RGBX: |
| 165 » » » » cinfo->in_color_space=JCS_RGB; break; | 177 » » case TJPF_BGRX: |
| 166 » » » } | 178 » » case TJPF_XRGB: |
| 167 » » default: | 179 » » case TJPF_XBGR: |
| 168 » » » _throw("Unsupported pixel format"); | 180 » » case TJPF_RGBA: |
| 181 » » case TJPF_BGRA: |
| 182 » » case TJPF_ARGB: |
| 183 » » case TJPF_ABGR: |
| 184 » » » cinfo->in_color_space=JCS_RGB; pixelFormat=TJPF_RGB; |
| 185 » » » break; |
| 169 #endif | 186 #endif |
| 170 } | 187 } |
| 171 | 188 |
| 172 cinfo->input_components=tjPixelSize[pixelFormat]; | 189 cinfo->input_components=tjPixelSize[pixelFormat]; |
| 173 jpeg_set_defaults(cinfo); | 190 jpeg_set_defaults(cinfo); |
| 174 if(jpegQual>=0) | 191 if(jpegQual>=0) |
| 175 { | 192 { |
| 176 jpeg_set_quality(cinfo, jpegQual, TRUE); | 193 jpeg_set_quality(cinfo, jpegQual, TRUE); |
| 177 if(jpegQual>=96) cinfo->dct_method=JDCT_ISLOW; | 194 if(jpegQual>=96) cinfo->dct_method=JDCT_ISLOW; |
| 178 else cinfo->dct_method=JDCT_FASTEST; | 195 else cinfo->dct_method=JDCT_FASTEST; |
| 179 } | 196 } |
| 180 if(subsamp==TJSAMP_GRAY) | 197 if(subsamp==TJSAMP_GRAY) |
| 181 jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); | 198 jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); |
| 182 else | 199 else |
| 183 jpeg_set_colorspace(cinfo, JCS_YCbCr); | 200 jpeg_set_colorspace(cinfo, JCS_YCbCr); |
| 184 | 201 |
| 185 cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8; | 202 cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8; |
| 186 cinfo->comp_info[1].h_samp_factor=1; | 203 cinfo->comp_info[1].h_samp_factor=1; |
| 187 cinfo->comp_info[2].h_samp_factor=1; | 204 cinfo->comp_info[2].h_samp_factor=1; |
| 188 cinfo->comp_info[0].v_samp_factor=tjMCUHeight[subsamp]/8; | 205 cinfo->comp_info[0].v_samp_factor=tjMCUHeight[subsamp]/8; |
| 189 cinfo->comp_info[1].v_samp_factor=1; | 206 cinfo->comp_info[1].v_samp_factor=1; |
| 190 cinfo->comp_info[2].v_samp_factor=1; | 207 cinfo->comp_info[2].v_samp_factor=1; |
| 191 | 208 |
| 192 #if JCS_EXTENSIONS!=1 | |
| 193 bailout: | |
| 194 #endif | |
| 195 return retval; | 209 return retval; |
| 196 } | 210 } |
| 197 | 211 |
| 198 static int setDecompDefaults(struct jpeg_decompress_struct *dinfo, | 212 static int setDecompDefaults(struct jpeg_decompress_struct *dinfo, |
| 199 int pixelFormat) | 213 int pixelFormat) |
| 200 { | 214 { |
| 201 int retval=0; | 215 int retval=0; |
| 202 | 216 |
| 203 switch(pixelFormat) | 217 switch(pixelFormat) |
| 204 { | 218 { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 222 dinfo->out_color_space=JCS_EXT_RGBA; break; | 236 dinfo->out_color_space=JCS_EXT_RGBA; break; |
| 223 case TJPF_BGRA: | 237 case TJPF_BGRA: |
| 224 dinfo->out_color_space=JCS_EXT_BGRA; break; | 238 dinfo->out_color_space=JCS_EXT_BGRA; break; |
| 225 case TJPF_ARGB: | 239 case TJPF_ARGB: |
| 226 dinfo->out_color_space=JCS_EXT_ARGB; break; | 240 dinfo->out_color_space=JCS_EXT_ARGB; break; |
| 227 case TJPF_ABGR: | 241 case TJPF_ABGR: |
| 228 dinfo->out_color_space=JCS_EXT_ABGR; break; | 242 dinfo->out_color_space=JCS_EXT_ABGR; break; |
| 229 #endif | 243 #endif |
| 230 #else | 244 #else |
| 231 case TJPF_RGB: | 245 case TJPF_RGB: |
| 232 » » » if(RGB_RED==0 && RGB_GREEN==1 && RGB_BLUE==2 && RGB_PIXE
LSIZE==3) | 246 » » case TJPF_BGR: |
| 233 » » » { | 247 » » case TJPF_RGBX: |
| 234 » » » » dinfo->out_color_space=JCS_RGB; break; | 248 » » case TJPF_BGRX: |
| 235 » » » } | 249 » » case TJPF_XRGB: |
| 250 » » case TJPF_XBGR: |
| 251 » » case TJPF_RGBA: |
| 252 » » case TJPF_BGRA: |
| 253 » » case TJPF_ARGB: |
| 254 » » case TJPF_ABGR: |
| 255 » » » dinfo->out_color_space=JCS_RGB; break; |
| 236 #endif | 256 #endif |
| 237 default: | 257 default: |
| 238 _throw("Unsupported pixel format"); | 258 _throw("Unsupported pixel format"); |
| 239 } | 259 } |
| 240 | 260 |
| 241 bailout: | 261 bailout: |
| 242 return retval; | 262 return retval; |
| 243 } | 263 } |
| 244 | 264 |
| 245 | 265 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 264 { | 284 { |
| 265 retval=i; break; | 285 retval=i; break; |
| 266 } | 286 } |
| 267 } | 287 } |
| 268 } | 288 } |
| 269 } | 289 } |
| 270 return retval; | 290 return retval; |
| 271 } | 291 } |
| 272 | 292 |
| 273 | 293 |
| 294 #ifndef JCS_EXTENSIONS |
| 295 |
| 296 /* Conversion functions to emulate the colorspace extensions. This allows the |
| 297 TurboJPEG wrapper to be used with libjpeg */ |
| 298 |
| 299 #define TORGB(PS, ROFFSET, GOFFSET, BOFFSET) { \ |
| 300 int rowPad=pitch-width*PS; \ |
| 301 while(height--) \ |
| 302 { \ |
| 303 unsigned char *endOfRow=src+width*PS; \ |
| 304 while(src<endOfRow) \ |
| 305 { \ |
| 306 dst[RGB_RED]=src[ROFFSET]; \ |
| 307 dst[RGB_GREEN]=src[GOFFSET]; \ |
| 308 dst[RGB_BLUE]=src[BOFFSET]; \ |
| 309 dst+=RGB_PIXELSIZE; src+=PS; \ |
| 310 } \ |
| 311 src+=rowPad; \ |
| 312 } \ |
| 313 } |
| 314 |
| 315 static unsigned char *toRGB(unsigned char *src, int width, int pitch, |
| 316 int height, int pixelFormat, unsigned char *dst) |
| 317 { |
| 318 unsigned char *retval=src; |
| 319 switch(pixelFormat) |
| 320 { |
| 321 case TJPF_RGB: |
| 322 #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIX
ELSIZE!=3 |
| 323 retval=dst; TORGB(3, 0, 1, 2); |
| 324 #endif |
| 325 break; |
| 326 case TJPF_BGR: |
| 327 #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIX
ELSIZE!=3 |
| 328 retval=dst; TORGB(3, 2, 1, 0); |
| 329 #endif |
| 330 break; |
| 331 case TJPF_RGBX: |
| 332 case TJPF_RGBA: |
| 333 #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIX
ELSIZE!=4 |
| 334 retval=dst; TORGB(4, 0, 1, 2); |
| 335 #endif |
| 336 break; |
| 337 case TJPF_BGRX: |
| 338 case TJPF_BGRA: |
| 339 #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIX
ELSIZE!=4 |
| 340 retval=dst; TORGB(4, 2, 1, 0); |
| 341 #endif |
| 342 break; |
| 343 case TJPF_XRGB: |
| 344 case TJPF_ARGB: |
| 345 #if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIX
ELSIZE!=4 |
| 346 retval=dst; TORGB(4, 1, 2, 3); |
| 347 #endif |
| 348 break; |
| 349 case TJPF_XBGR: |
| 350 case TJPF_ABGR: |
| 351 #if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIX
ELSIZE!=4 |
| 352 retval=dst; TORGB(4, 3, 2, 1); |
| 353 #endif |
| 354 break; |
| 355 } |
| 356 return retval; |
| 357 } |
| 358 |
| 359 #define FROMRGB(PS, ROFFSET, GOFFSET, BOFFSET, SETALPHA) { \ |
| 360 int rowPad=pitch-width*PS; \ |
| 361 while(height--) \ |
| 362 { \ |
| 363 unsigned char *endOfRow=dst+width*PS; \ |
| 364 while(dst<endOfRow) \ |
| 365 { \ |
| 366 dst[ROFFSET]=src[RGB_RED]; \ |
| 367 dst[GOFFSET]=src[RGB_GREEN]; \ |
| 368 dst[BOFFSET]=src[RGB_BLUE]; \ |
| 369 SETALPHA \ |
| 370 dst+=PS; src+=RGB_PIXELSIZE; \ |
| 371 } \ |
| 372 dst+=rowPad; \ |
| 373 } \ |
| 374 } |
| 375 |
| 376 static void fromRGB(unsigned char *src, unsigned char *dst, int width, |
| 377 int pitch, int height, int pixelFormat) |
| 378 { |
| 379 switch(pixelFormat) |
| 380 { |
| 381 case TJPF_RGB: |
| 382 #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIX
ELSIZE!=3 |
| 383 FROMRGB(3, 0, 1, 2,); |
| 384 #endif |
| 385 break; |
| 386 case TJPF_BGR: |
| 387 #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIX
ELSIZE!=3 |
| 388 FROMRGB(3, 2, 1, 0,); |
| 389 #endif |
| 390 break; |
| 391 case TJPF_RGBX: |
| 392 #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIX
ELSIZE!=4 |
| 393 FROMRGB(4, 0, 1, 2,); |
| 394 #endif |
| 395 break; |
| 396 case TJPF_RGBA: |
| 397 #if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIX
ELSIZE!=4 |
| 398 FROMRGB(4, 0, 1, 2, dst[3]=0xFF;); |
| 399 #endif |
| 400 break; |
| 401 case TJPF_BGRX: |
| 402 #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIX
ELSIZE!=4 |
| 403 FROMRGB(4, 2, 1, 0,); |
| 404 #endif |
| 405 break; |
| 406 case TJPF_BGRA: |
| 407 #if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIX
ELSIZE!=4 |
| 408 FROMRGB(4, 2, 1, 0, dst[3]=0xFF;); return; |
| 409 #endif |
| 410 break; |
| 411 case TJPF_XRGB: |
| 412 #if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIX
ELSIZE!=4 |
| 413 FROMRGB(4, 1, 2, 3,); return; |
| 414 #endif |
| 415 break; |
| 416 case TJPF_ARGB: |
| 417 #if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIX
ELSIZE!=4 |
| 418 FROMRGB(4, 1, 2, 3, dst[0]=0xFF;); return; |
| 419 #endif |
| 420 break; |
| 421 case TJPF_XBGR: |
| 422 #if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIX
ELSIZE!=4 |
| 423 FROMRGB(4, 3, 2, 1,); return; |
| 424 #endif |
| 425 break; |
| 426 case TJPF_ABGR: |
| 427 #if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIX
ELSIZE!=4 |
| 428 FROMRGB(4, 3, 2, 1, dst[0]=0xFF;); return; |
| 429 #endif |
| 430 break; |
| 431 } |
| 432 } |
| 433 |
| 434 #endif |
| 435 |
| 436 |
| 274 /* General API functions */ | 437 /* General API functions */ |
| 275 | 438 |
| 276 DLLEXPORT char* DLLCALL tjGetErrorStr(void) | 439 DLLEXPORT char* DLLCALL tjGetErrorStr(void) |
| 277 { | 440 { |
| 278 return errStr; | 441 return errStr; |
| 279 } | 442 } |
| 280 | 443 |
| 281 | 444 |
| 282 DLLEXPORT int DLLCALL tjDestroy(tjhandle handle) | 445 DLLEXPORT int DLLCALL tjDestroy(tjhandle handle) |
| 283 { | 446 { |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 { | 567 { |
| 405 return tjBufSizeYUV(width, height, subsamp); | 568 return tjBufSizeYUV(width, height, subsamp); |
| 406 } | 569 } |
| 407 | 570 |
| 408 | 571 |
| 409 DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf, | 572 DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf, |
| 410 int width, int pitch, int height, int pixelFormat, unsigned char **jpegB
uf, | 573 int width, int pitch, int height, int pixelFormat, unsigned char **jpegB
uf, |
| 411 unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) | 574 unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) |
| 412 { | 575 { |
| 413 int i, retval=0, alloc=1; JSAMPROW *row_pointer=NULL; | 576 int i, retval=0, alloc=1; JSAMPROW *row_pointer=NULL; |
| 577 #ifndef JCS_EXTENSIONS |
| 578 unsigned char *rgbBuf=NULL; |
| 579 #endif |
| 414 | 580 |
| 415 getinstance(handle) | 581 getinstance(handle) |
| 416 if((this->init&COMPRESS)==0) | 582 if((this->init&COMPRESS)==0) |
| 417 _throw("tjCompress2(): Instance has not been initialized for com
pression"); | 583 _throw("tjCompress2(): Instance has not been initialized for com
pression"); |
| 418 | 584 |
| 419 if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 | 585 if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 |
| 420 || pixelFormat>=TJ_NUMPF || jpegBuf==NULL || jpegSize==NULL | 586 || pixelFormat>=TJ_NUMPF || jpegBuf==NULL || jpegSize==NULL |
| 421 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT || jpegQual<0 || jpeg
Qual>100) | 587 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT || jpegQual<0 || jpeg
Qual>100) |
| 422 _throw("tjCompress2(): Invalid argument"); | 588 _throw("tjCompress2(): Invalid argument"); |
| 423 | 589 |
| 424 if(setjmp(this->jerr.setjmp_buffer)) | 590 if(setjmp(this->jerr.setjmp_buffer)) |
| 425 { | 591 { |
| 426 /* If we get here, the JPEG code has signaled an error. */ | 592 /* If we get here, the JPEG code has signaled an error. */ |
| 427 retval=-1; | 593 retval=-1; |
| 428 goto bailout; | 594 goto bailout; |
| 429 } | 595 } |
| 430 | 596 |
| 431 if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; | 597 if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; |
| 432 | 598 |
| 599 #ifndef JCS_EXTENSIONS |
| 600 if(pixelFormat!=TJPF_GRAY) |
| 601 { |
| 602 rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE); |
| 603 if(!rgbBuf) _throw("tjCompress2(): Memory allocation failure"); |
| 604 srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf); |
| 605 pitch=width*RGB_PIXELSIZE; |
| 606 } |
| 607 #endif |
| 608 |
| 433 cinfo->image_width=width; | 609 cinfo->image_width=width; |
| 434 cinfo->image_height=height; | 610 cinfo->image_height=height; |
| 435 | 611 |
| 436 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); | 612 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); |
| 437 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); | 613 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); |
| 438 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); | 614 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); |
| 439 | 615 |
| 440 if(flags&TJFLAG_NOREALLOC) | 616 if(flags&TJFLAG_NOREALLOC) |
| 441 { | 617 { |
| 442 alloc=0; *jpegSize=tjBufSize(width, height, jpegSubsamp); | 618 alloc=0; *jpegSize=tjBufSize(width, height, jpegSubsamp); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 455 } | 631 } |
| 456 while(cinfo->next_scanline<cinfo->image_height) | 632 while(cinfo->next_scanline<cinfo->image_height) |
| 457 { | 633 { |
| 458 jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], | 634 jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], |
| 459 cinfo->image_height-cinfo->next_scanline); | 635 cinfo->image_height-cinfo->next_scanline); |
| 460 } | 636 } |
| 461 jpeg_finish_compress(cinfo); | 637 jpeg_finish_compress(cinfo); |
| 462 | 638 |
| 463 bailout: | 639 bailout: |
| 464 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); | 640 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); |
| 641 #ifndef JCS_EXTENSIONS |
| 642 if(rgbBuf) free(rgbBuf); |
| 643 #endif |
| 465 if(row_pointer) free(row_pointer); | 644 if(row_pointer) free(row_pointer); |
| 466 return retval; | 645 return retval; |
| 467 } | 646 } |
| 468 | 647 |
| 469 DLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf, | 648 DLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf, |
| 470 int width, int pitch, int height, int pixelSize, unsigned char *jpegBuf, | 649 int width, int pitch, int height, int pixelSize, unsigned char *jpegBuf, |
| 471 unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) | 650 unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) |
| 472 { | 651 { |
| 473 int retval=0; unsigned long size; | 652 int retval=0; unsigned long size; |
| 474 if(flags&TJ_YUV) | 653 if(flags&TJ_YUV) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 491 DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf, | 670 DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf, |
| 492 int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf
, | 671 int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf
, |
| 493 int subsamp, int flags) | 672 int subsamp, int flags) |
| 494 { | 673 { |
| 495 int i, retval=0; JSAMPROW *row_pointer=NULL; | 674 int i, retval=0; JSAMPROW *row_pointer=NULL; |
| 496 JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS]; | 675 JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS]; |
| 497 JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS]; | 676 JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS]; |
| 498 JSAMPROW *outbuf[MAX_COMPONENTS]; | 677 JSAMPROW *outbuf[MAX_COMPONENTS]; |
| 499 int row, pw, ph, cw[MAX_COMPONENTS], ch[MAX_COMPONENTS]; | 678 int row, pw, ph, cw[MAX_COMPONENTS], ch[MAX_COMPONENTS]; |
| 500 JSAMPLE *ptr=dstBuf; | 679 JSAMPLE *ptr=dstBuf; |
| 501 unsigned long yuvsize=0; | 680 » unsigned long yuvsize=0; |
| 502 jpeg_component_info *compptr; | 681 jpeg_component_info *compptr; |
| 682 #ifndef JCS_EXTENSIONS |
| 683 unsigned char *rgbBuf=NULL; |
| 684 #endif |
| 503 | 685 |
| 504 getinstance(handle); | 686 getinstance(handle); |
| 505 if((this->init&COMPRESS)==0) | 687 if((this->init&COMPRESS)==0) |
| 506 _throw("tjEncodeYUV2(): Instance has not been initialized for co
mpression"); | 688 _throw("tjEncodeYUV2(): Instance has not been initialized for co
mpression"); |
| 507 | 689 |
| 508 for(i=0; i<MAX_COMPONENTS; i++) | 690 for(i=0; i<MAX_COMPONENTS; i++) |
| 509 { | 691 { |
| 510 tmpbuf[i]=NULL; _tmpbuf[i]=NULL; | 692 tmpbuf[i]=NULL; _tmpbuf[i]=NULL; |
| 511 tmpbuf2[i]=NULL; _tmpbuf2[i]=NULL; outbuf[i]=NULL; | 693 tmpbuf2[i]=NULL; _tmpbuf2[i]=NULL; outbuf[i]=NULL; |
| 512 } | 694 } |
| 513 | 695 |
| 514 if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 | 696 if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 |
| 515 || pixelFormat>=TJ_NUMPF || dstBuf==NULL || subsamp<0 | 697 || pixelFormat>=TJ_NUMPF || dstBuf==NULL || subsamp<0 |
| 516 || subsamp>=NUMSUBOPT) | 698 || subsamp>=NUMSUBOPT) |
| 517 _throw("tjEncodeYUV2(): Invalid argument"); | 699 _throw("tjEncodeYUV2(): Invalid argument"); |
| 518 | 700 |
| 519 if(setjmp(this->jerr.setjmp_buffer)) | 701 if(setjmp(this->jerr.setjmp_buffer)) |
| 520 { | 702 { |
| 521 /* If we get here, the JPEG code has signaled an error. */ | 703 /* If we get here, the JPEG code has signaled an error. */ |
| 522 retval=-1; | 704 retval=-1; |
| 523 goto bailout; | 705 goto bailout; |
| 524 } | 706 } |
| 525 | 707 |
| 526 if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; | 708 if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; |
| 527 | 709 |
| 710 #ifndef JCS_EXTENSIONS |
| 711 if(pixelFormat!=TJPF_GRAY) |
| 712 { |
| 713 rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE); |
| 714 if(!rgbBuf) _throw("tjEncodeYUV2(): Memory allocation failure"); |
| 715 srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf); |
| 716 pitch=width*RGB_PIXELSIZE; |
| 717 } |
| 718 #endif |
| 719 |
| 528 cinfo->image_width=width; | 720 cinfo->image_width=width; |
| 529 cinfo->image_height=height; | 721 cinfo->image_height=height; |
| 530 | 722 |
| 531 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); | 723 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); |
| 532 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); | 724 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); |
| 533 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); | 725 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); |
| 534 | 726 |
| 535 yuvsize=tjBufSizeYUV(width, height, subsamp); | 727 yuvsize=tjBufSizeYUV(width, height, subsamp); |
| 536 jpeg_mem_dest_tj(cinfo, &dstBuf, &yuvsize, 0); | 728 jpeg_mem_dest_tj(cinfo, &dstBuf, &yuvsize, 0); |
| 537 if(setCompDefaults(cinfo, pixelFormat, subsamp, -1)==-1) return -1; | 729 if(setCompDefaults(cinfo, pixelFormat, subsamp, -1)==-1) return -1; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 for(i=0, compptr=cinfo->comp_info; i<cinfo->num_components; i++,
compptr++) | 792 for(i=0, compptr=cinfo->comp_info; i<cinfo->num_components; i++,
compptr++) |
| 601 jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i], | 793 jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i], |
| 602 row*compptr->v_samp_factor/cinfo->max_v_samp_fac
tor, | 794 row*compptr->v_samp_factor/cinfo->max_v_samp_fac
tor, |
| 603 compptr->v_samp_factor, cw[i]); | 795 compptr->v_samp_factor, cw[i]); |
| 604 } | 796 } |
| 605 cinfo->next_scanline+=height; | 797 cinfo->next_scanline+=height; |
| 606 jpeg_abort_compress(cinfo); | 798 jpeg_abort_compress(cinfo); |
| 607 | 799 |
| 608 bailout: | 800 bailout: |
| 609 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); | 801 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); |
| 802 #ifndef JCS_EXTENSIONS |
| 803 if(rgbBuf) free(rgbBuf); |
| 804 #endif |
| 610 if(row_pointer) free(row_pointer); | 805 if(row_pointer) free(row_pointer); |
| 611 for(i=0; i<MAX_COMPONENTS; i++) | 806 for(i=0; i<MAX_COMPONENTS; i++) |
| 612 { | 807 { |
| 613 if(tmpbuf[i]!=NULL) free(tmpbuf[i]); | 808 if(tmpbuf[i]!=NULL) free(tmpbuf[i]); |
| 614 if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); | 809 if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); |
| 615 if(tmpbuf2[i]!=NULL) free(tmpbuf2[i]); | 810 if(tmpbuf2[i]!=NULL) free(tmpbuf2[i]); |
| 616 if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]); | 811 if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]); |
| 617 if(outbuf[i]!=NULL) free(outbuf[i]); | 812 if(outbuf[i]!=NULL) free(outbuf[i]); |
| 618 } | 813 } |
| 619 return retval; | 814 return retval; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 return (tjscalingfactor *)sf; | 922 return (tjscalingfactor *)sf; |
| 728 } | 923 } |
| 729 | 924 |
| 730 | 925 |
| 731 DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf, | 926 DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf, |
| 732 unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, | 927 unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, |
| 733 int height, int pixelFormat, int flags) | 928 int height, int pixelFormat, int flags) |
| 734 { | 929 { |
| 735 int i, retval=0; JSAMPROW *row_pointer=NULL; | 930 int i, retval=0; JSAMPROW *row_pointer=NULL; |
| 736 int jpegwidth, jpegheight, scaledw, scaledh; | 931 int jpegwidth, jpegheight, scaledw, scaledh; |
| 932 #ifndef JCS_EXTENSIONS |
| 933 unsigned char *rgbBuf=NULL; |
| 934 unsigned char *_dstBuf=NULL; int _pitch=0; |
| 935 #endif |
| 737 | 936 |
| 738 getinstance(handle); | 937 getinstance(handle); |
| 739 if((this->init&DECOMPRESS)==0) | 938 if((this->init&DECOMPRESS)==0) |
| 740 _throw("tjDecompress2(): Instance has not been initialized for d
ecompression"); | 939 _throw("tjDecompress2(): Instance has not been initialized for d
ecompression"); |
| 741 | 940 |
| 742 if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pitch<0 | 941 if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pitch<0 |
| 743 || height<0 || pixelFormat<0 || pixelFormat>=TJ_NUMPF) | 942 || height<0 || pixelFormat<0 || pixelFormat>=TJ_NUMPF) |
| 744 _throw("tjDecompress2(): Invalid argument"); | 943 _throw("tjDecompress2(): Invalid argument"); |
| 745 | 944 |
| 746 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); | 945 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); |
| 747 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); | 946 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); |
| 748 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); | 947 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); |
| 749 | 948 |
| 750 if(setjmp(this->jerr.setjmp_buffer)) | 949 if(setjmp(this->jerr.setjmp_buffer)) |
| 751 { | 950 { |
| 752 /* If we get here, the JPEG code has signaled an error. */ | 951 /* If we get here, the JPEG code has signaled an error. */ |
| 753 retval=-1; | 952 retval=-1; |
| 754 goto bailout; | 953 goto bailout; |
| 755 } | 954 } |
| 756 | 955 |
| 757 jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); | 956 jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); |
| 758 jpeg_read_header(dinfo, TRUE); | 957 jpeg_read_header(dinfo, TRUE); |
| 759 » if(setDecompDefaults(dinfo, pixelFormat)==-1) return -1; | 958 » if(setDecompDefaults(dinfo, pixelFormat)==-1) |
| 959 » { |
| 960 » » retval=-1; goto bailout; |
| 961 » } |
| 760 | 962 |
| 761 if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; | 963 if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; |
| 762 | 964 |
| 763 jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height; | 965 jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height; |
| 764 if(width==0) width=jpegwidth; | 966 if(width==0) width=jpegwidth; |
| 765 if(height==0) height=jpegheight; | 967 if(height==0) height=jpegheight; |
| 766 for(i=0; i<NUMSF; i++) | 968 for(i=0; i<NUMSF; i++) |
| 767 { | 969 { |
| 768 scaledw=TJSCALED(jpegwidth, sf[i]); | 970 scaledw=TJSCALED(jpegwidth, sf[i]); |
| 769 scaledh=TJSCALED(jpegheight, sf[i]); | 971 scaledh=TJSCALED(jpegheight, sf[i]); |
| 770 if(scaledw<=width && scaledh<=height) | 972 if(scaledw<=width && scaledh<=height) |
| 771 break; | 973 break; |
| 772 } | 974 } |
| 773 if(scaledw>width || scaledh>height) | 975 if(scaledw>width || scaledh>height) |
| 774 _throw("tjDecompress2(): Could not scale down to desired image d
imensions"); | 976 _throw("tjDecompress2(): Could not scale down to desired image d
imensions"); |
| 775 width=scaledw; height=scaledh; | 977 width=scaledw; height=scaledh; |
| 776 dinfo->scale_num=sf[i].num; | 978 dinfo->scale_num=sf[i].num; |
| 777 dinfo->scale_denom=sf[i].denom; | 979 dinfo->scale_denom=sf[i].denom; |
| 778 | 980 |
| 779 jpeg_start_decompress(dinfo); | 981 jpeg_start_decompress(dinfo); |
| 780 if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat]; | 982 if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat]; |
| 983 |
| 984 #ifndef JCS_EXTENSIONS |
| 985 if(pixelFormat!=TJPF_GRAY && |
| 986 (RGB_RED!=tjRedOffset[pixelFormat] || |
| 987 RGB_GREEN!=tjGreenOffset[pixelFormat] || |
| 988 RGB_BLUE!=tjBlueOffset[pixelFormat] || |
| 989 RGB_PIXELSIZE!=tjPixelSize[pixelFormat])) |
| 990 { |
| 991 rgbBuf=(unsigned char *)malloc(width*height*3); |
| 992 if(!rgbBuf) _throw("tjDecompress2(): Memory allocation failure")
; |
| 993 _pitch=pitch; pitch=width*3; |
| 994 _dstBuf=dstBuf; dstBuf=rgbBuf; |
| 995 } |
| 996 #endif |
| 997 |
| 781 if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW) | 998 if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW) |
| 782 *dinfo->output_height))==NULL) | 999 *dinfo->output_height))==NULL) |
| 783 _throw("tjDecompress2(): Memory allocation failure"); | 1000 _throw("tjDecompress2(): Memory allocation failure"); |
| 784 for(i=0; i<(int)dinfo->output_height; i++) | 1001 for(i=0; i<(int)dinfo->output_height; i++) |
| 785 { | 1002 { |
| 786 if(flags&TJFLAG_BOTTOMUP) | 1003 if(flags&TJFLAG_BOTTOMUP) |
| 787 row_pointer[i]=&dstBuf[(dinfo->output_height-i-1)*pitch]
; | 1004 row_pointer[i]=&dstBuf[(dinfo->output_height-i-1)*pitch]
; |
| 788 else row_pointer[i]=&dstBuf[i*pitch]; | 1005 else row_pointer[i]=&dstBuf[i*pitch]; |
| 789 } | 1006 } |
| 790 while(dinfo->output_scanline<dinfo->output_height) | 1007 while(dinfo->output_scanline<dinfo->output_height) |
| 791 { | 1008 { |
| 792 jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], | 1009 jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], |
| 793 dinfo->output_height-dinfo->output_scanline); | 1010 dinfo->output_height-dinfo->output_scanline); |
| 794 } | 1011 } |
| 795 jpeg_finish_decompress(dinfo); | 1012 jpeg_finish_decompress(dinfo); |
| 796 | 1013 |
| 1014 #ifndef JCS_EXTENSIONS |
| 1015 fromRGB(rgbBuf, _dstBuf, width, _pitch, height, pixelFormat); |
| 1016 #endif |
| 1017 |
| 797 bailout: | 1018 bailout: |
| 798 if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); | 1019 if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); |
| 1020 #ifndef JCS_EXTENSIONS |
| 1021 if(rgbBuf) free(rgbBuf); |
| 1022 #endif |
| 799 if(row_pointer) free(row_pointer); | 1023 if(row_pointer) free(row_pointer); |
| 800 return retval; | 1024 return retval; |
| 801 } | 1025 } |
| 802 | 1026 |
| 803 DLLEXPORT int DLLCALL tjDecompress(tjhandle handle, unsigned char *jpegBuf, | 1027 DLLEXPORT int DLLCALL tjDecompress(tjhandle handle, unsigned char *jpegBuf, |
| 804 unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, | 1028 unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, |
| 805 int height, int pixelSize, int flags) | 1029 int height, int pixelSize, int flags) |
| 806 { | 1030 { |
| 807 if(flags&TJ_YUV) | 1031 if(flags&TJ_YUV) |
| 808 return tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flag
s); | 1032 return tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flag
s); |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1058 if(!(t[i].options&TJXOPT_NOOUTPUT)) | 1282 if(!(t[i].options&TJXOPT_NOOUTPUT)) |
| 1059 { | 1283 { |
| 1060 jpeg_write_coefficients(cinfo, dstcoefs); | 1284 jpeg_write_coefficients(cinfo, dstcoefs); |
| 1061 jcopy_markers_execute(dinfo, cinfo, JCOPYOPT_ALL); | 1285 jcopy_markers_execute(dinfo, cinfo, JCOPYOPT_ALL); |
| 1062 } | 1286 } |
| 1063 else jinit_c_master_control(cinfo, TRUE); | 1287 else jinit_c_master_control(cinfo, TRUE); |
| 1064 jtransform_execute_transformation(dinfo, cinfo, srccoefs, | 1288 jtransform_execute_transformation(dinfo, cinfo, srccoefs, |
| 1065 &xinfo[i]); | 1289 &xinfo[i]); |
| 1066 if(t[i].customFilter) | 1290 if(t[i].customFilter) |
| 1067 { | 1291 { |
| 1068 » » » int ci, by, y; | 1292 » » » int ci, y; JDIMENSION by; |
| 1069 for(ci=0; ci<cinfo->num_components; ci++) | 1293 for(ci=0; ci<cinfo->num_components; ci++) |
| 1070 { | 1294 { |
| 1071 jpeg_component_info *compptr=&cinfo->comp_info[c
i]; | 1295 jpeg_component_info *compptr=&cinfo->comp_info[c
i]; |
| 1072 tjregion arrayRegion={0, 0, compptr->width_in_bl
ocks*DCTSIZE, | 1296 tjregion arrayRegion={0, 0, compptr->width_in_bl
ocks*DCTSIZE, |
| 1073 DCTSIZE}; | 1297 DCTSIZE}; |
| 1074 tjregion planeRegion={0, 0, compptr->width_in_bl
ocks*DCTSIZE, | 1298 tjregion planeRegion={0, 0, compptr->width_in_bl
ocks*DCTSIZE, |
| 1075 compptr->height_in_blocks*DCTSIZE}; | 1299 compptr->height_in_blocks*DCTSIZE}; |
| 1076 for(by=0; by<compptr->height_in_blocks; by+=comp
ptr->v_samp_factor) | 1300 for(by=0; by<compptr->height_in_blocks; by+=comp
ptr->v_samp_factor) |
| 1077 { | 1301 { |
| 1078 JBLOCKARRAY barray=(dinfo->mem->access_v
irt_barray) | 1302 JBLOCKARRAY barray=(dinfo->mem->access_v
irt_barray) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1092 } | 1316 } |
| 1093 | 1317 |
| 1094 jpeg_finish_decompress(dinfo); | 1318 jpeg_finish_decompress(dinfo); |
| 1095 | 1319 |
| 1096 bailout: | 1320 bailout: |
| 1097 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); | 1321 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); |
| 1098 if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); | 1322 if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); |
| 1099 if(xinfo) free(xinfo); | 1323 if(xinfo) free(xinfo); |
| 1100 return retval; | 1324 return retval; |
| 1101 } | 1325 } |
| OLD | NEW |