[6] Fixed a couple of issues whereby malformed JPEG images would cause
libjpeg-turbo to use uninitialized memory during decompression.
+[7] Fixed an error ("Buffer passed to JPEG library is too small") that occurred
+when calling the TurboJPEG YUV encoding function with a very small (< 5x5)
+source image, and added a unit test to check for this error.
+
1.2.1
=====
/*
- * Copyright (C)2011-2012 D. R. Commander. All Rights Reserved.
+ * Copyright (C)2011-2012, 2014 D. R. Commander.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
private static void bufSizeTest() throws Exception {
int w, h, i, subsamp;
- byte[] srcBuf, jpegBuf;
+ byte[] srcBuf, dstBuf;
TJCompressor tjc = null;
Random r = new Random();
if(h % 100 == 0)
System.out.format("%04d x %04d\b\b\b\b\b\b\b\b\b\b\b", w, h);
srcBuf = new byte[w * h * 4];
- jpegBuf = new byte[TJ.bufSize(w, h, subsamp)];
+ if (yuv == YUVENCODE)
+ dstBuf = new byte[TJ.bufSizeYUV(w, h, subsamp)];
+ else
+ dstBuf = new byte[TJ.bufSize(w, h, subsamp)];
for(i = 0; i < w * h * 4; i++) {
srcBuf[i] = (byte)(r.nextInt(2) * 255);
}
tjc.setSourceImage(srcBuf, w, 0, h, TJ.PF_BGRX);
tjc.setSubsamp(subsamp);
tjc.setJPEGQuality(100);
- tjc.compress(jpegBuf, 0);
+ if (yuv == YUVENCODE)
+ tjc.encodeYUV(dstBuf, 0);
+ else
+ tjc.compress(dstBuf, 0);
srcBuf = new byte[h * w * 4];
- jpegBuf = new byte[TJ.bufSize(h, w, subsamp)];
+ if (yuv == YUVENCODE)
+ dstBuf = new byte[TJ.bufSizeYUV(h, w, subsamp)];
+ else
+ dstBuf = new byte[TJ.bufSize(h, w, subsamp)];
for(i = 0; i < h * w * 4; i++) {
srcBuf[i] = (byte)(r.nextInt(2) * 255);
}
tjc.setSourceImage(srcBuf, h, 0, w, TJ.PF_BGRX);
- tjc.compress(jpegBuf, 0);
+ if (yuv == YUVENCODE)
+ tjc.encodeYUV(dstBuf, 0);
+ else
+ tjc.compress(dstBuf, 0);
}
}
}
testName);
doTest(41, 35, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_GRAY,
testName);
- if(!doyuv && !bi) bufSizeTest();
- if(doyuv && !bi) {
+ if(!bi)
+ bufSizeTest();
+ if (doyuv && !bi) {
+ System.out.print("\n\n");
yuv = YUVDECODE;
doTest(48, 48, onlyRGB, TJ.SAMP_444, "javatest_yuv0");
doTest(35, 39, onlyRGB, TJ.SAMP_444, "javatest_yuv1");
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-2010, Thomas G. Lane, Guido Vollbeding.
* Modifications:
- * Copyright (C) 2010, 2012, D. R. Commander.
+ * Copyright (C) 2010, 2012-2014, D. R. Commander.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains software version identification.
#define JCOPYRIGHT "Copyright (C) 1991-2010 Thomas G. Lane, Guido Vollbeding\n" \
"Copyright (C) 1999-2006 MIYASAKA Masaru\n" \
"Copyright (C) 2009 Pierre Ossman for Cendio AB\n" \
- "Copyright (C) 2009-2012 D. R. Commander\n" \
+ "Copyright (C) 2009-2014 D. R. Commander\n" \
"Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)"
/*
- * Copyright (C)2009-2012 D. R. Commander. All Rights Reserved.
+ * Copyright (C)2009-2012, 2014 D. R. Commander. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
void bufSizeTest(void)
{
int w, h, i, subsamp;
- unsigned char *srcBuf=NULL, *jpegBuf=NULL;
+ unsigned char *srcBuf=NULL, *dstBuf=NULL;
tjhandle handle=NULL;
- unsigned long jpegSize=0;
+ unsigned long dstSize=0;
if((handle=tjInitCompress())==NULL) _throwtj();
if(h%100==0) printf("%.4d x %.4d\b\b\b\b\b\b\b\b\b\b\b", w, h);
if((srcBuf=(unsigned char *)malloc(w*h*4))==NULL)
_throw("Memory allocation failure");
- if(!alloc)
+ if(!alloc || yuv==YUVENCODE)
{
- if((jpegBuf=(unsigned char *)tjAlloc(tjBufSize(w, h, subsamp)))
- ==NULL)
+ if(yuv==YUVENCODE) dstSize=tjBufSizeYUV(w, h, subsamp);
+ else dstSize=tjBufSize(w, h, subsamp);
+ if((dstBuf=(unsigned char *)tjAlloc(dstSize))==NULL)
_throw("Memory allocation failure");
- jpegSize=tjBufSize(w, h, subsamp);
}
for(i=0; i<w*h*4; i++)
else srcBuf[i]=255;
}
- _tj(tjCompress2(handle, srcBuf, w, 0, h, TJPF_BGRX, &jpegBuf,
- &jpegSize, subsamp, 100, alloc? 0:TJFLAG_NOREALLOC));
+ if(yuv==YUVENCODE)
+ {
+ _tj(tjEncodeYUV2(handle, srcBuf, w, 0, h, TJPF_BGRX, dstBuf, subsamp,
+ 0));
+ }
+ else
+ {
+ _tj(tjCompress2(handle, srcBuf, w, 0, h, TJPF_BGRX, &dstBuf,
+ &dstSize, subsamp, 100, alloc? 0:TJFLAG_NOREALLOC));
+ }
free(srcBuf); srcBuf=NULL;
- tjFree(jpegBuf); jpegBuf=NULL;
+ tjFree(dstBuf); dstBuf=NULL;
if((srcBuf=(unsigned char *)malloc(h*w*4))==NULL)
_throw("Memory allocation failure");
- if(!alloc)
+ if(!alloc || yuv==YUVENCODE)
{
- if((jpegBuf=(unsigned char *)tjAlloc(tjBufSize(h, w, subsamp)))
- ==NULL)
+ if(yuv==YUVENCODE) dstSize=tjBufSizeYUV(h, w, subsamp);
+ else dstSize=tjBufSize(h, w, subsamp);
+ if((dstBuf=(unsigned char *)tjAlloc(dstSize))==NULL)
_throw("Memory allocation failure");
- jpegSize=tjBufSize(h, w, subsamp);
}
for(i=0; i<h*w*4; i++)
else srcBuf[i]=255;
}
- _tj(tjCompress2(handle, srcBuf, h, 0, w, TJPF_BGRX, &jpegBuf,
- &jpegSize, subsamp, 100, alloc? 0:TJFLAG_NOREALLOC));
+ if(yuv==YUVENCODE)
+ {
+ _tj(tjEncodeYUV2(handle, srcBuf, h, 0, w, TJPF_BGRX, dstBuf, subsamp,
+ 0));
+ }
+ else
+ {
+ _tj(tjCompress2(handle, srcBuf, h, 0, w, TJPF_BGRX, &dstBuf,
+ &dstSize, subsamp, 100, alloc? 0:TJFLAG_NOREALLOC));
+ }
free(srcBuf); srcBuf=NULL;
- tjFree(jpegBuf); jpegBuf=NULL;
+ tjFree(dstBuf); dstBuf=NULL;
}
}
}
bailout:
if(srcBuf) free(srcBuf);
- if(jpegBuf) free(jpegBuf);
+ if(dstBuf) free(dstBuf);
if(handle) tjDestroy(handle);
}
doTest(35, 39, _onlyGray, 1, TJSAMP_GRAY, "test");
doTest(39, 41, _3byteFormats, 2, TJSAMP_GRAY, "test");
doTest(41, 35, _4byteFormats, 4, TJSAMP_GRAY, "test");
- if(!doyuv) bufSizeTest();
+ bufSizeTest();
if(doyuv)
{
+ printf("\n\n");
yuv=YUVDECODE;
doTest(48, 48, _onlyRGB, 1, TJSAMP_444, "test_yuv0");
doTest(35, 39, _onlyRGB, 1, TJSAMP_444, "test_yuv1");
/*
- * Copyright (C)2009-2012 D. R. Commander. All Rights Reserved.
+ * Copyright (C)2009-2012, 2014 D. R. Commander. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
jpeg_mem_dest_tj(cinfo, &dstBuf, &yuvsize, 0);
if(setCompDefaults(cinfo, pixelFormat, subsamp, -1, flags)==-1) return -1;
- jpeg_start_compress(cinfo, TRUE);
+ /* Execute only the parts of jpeg_start_compress() that we need. If we
+ were to call the whole jpeg_start_compress() function, then it would try
+ to write the file headers, which could overflow the output buffer if the
+ YUV image were very small. */
+ if(cinfo->global_state!=CSTATE_START)
+ _throw("tjEncodeYUV3(): libjpeg API is in the wrong state");
+ (*cinfo->err->reset_error_mgr)((j_common_ptr)cinfo);
+ (*cinfo->dest->init_destination)(cinfo);
+ jinit_c_master_control(cinfo, FALSE);
+ jinit_color_converter(cinfo);
+ jinit_downsampler(cinfo);
+ jinit_c_prep_controller(cinfo, FALSE);
+ (*cinfo->mem->realize_virt_arrays)((j_common_ptr)cinfo);
+
pw=PAD(width, cinfo->max_h_samp_factor);
ph=PAD(height, cinfo->max_v_samp_factor);