aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--ChangeLog.txt9
-rw-r--r--Makefile.am1
-rw-r--r--doc/html/annotated.html4
-rw-r--r--doc/html/classes.html4
-rw-r--r--doc/html/functions.html4
-rw-r--r--doc/html/functions_vars.html4
-rw-r--r--doc/html/group___turbo_j_p_e_g.html73
-rw-r--r--doc/html/index.html4
-rw-r--r--doc/html/modules.html4
-rw-r--r--doc/html/structtjregion.html4
-rw-r--r--doc/html/structtjscalingfactor.html4
-rw-r--r--doc/html/structtjtransform.html4
-rw-r--r--doxygen.config2
-rw-r--r--tjunittest.c48
-rwxr-xr-xturbojpeg-mapfile8
-rwxr-xr-xturbojpeg-mapfile.jni8
-rw-r--r--turbojpeg.c122
-rw-r--r--turbojpeg.h86
19 files changed, 272 insertions, 123 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b1e135fb..ffffebb2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -320,6 +320,7 @@ endif()
add_test(tjunittest tjunittest)
add_test(tjunittest-alloc tjunittest -alloc)
add_test(tjunittest-yuv tjunittest -yuv)
+add_test(tjunittest-yuv-nopad tjunittest -yuv -noyuvpad)
add_test(cjpeg-int sharedlib/cjpeg -dct int -outfile testoutint.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-int-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_INT} -DFILE=testoutint.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-fast sharedlib/cjpeg -dct fast -opt -outfile testoutfst.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
@@ -375,6 +376,7 @@ add_test(jpegtran-crop-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_CROP} -DFILE=testou
add_test(tjunittest-static tjunittest-static)
add_test(tjunittest-static-alloc tjunittest-static -alloc)
add_test(tjunittest-static-yuv tjunittest-static -yuv)
+add_test(tjunittest-static-yuv-nopad tjunittest-static -yuv -noyuvpad)
add_test(cjpeg-static-int cjpeg-static -dct int -outfile testoutint.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-static-int-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_INT} -DFILE=testoutint.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-static-fast cjpeg-static -dct fast -opt -outfile testoutfst.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 780cc9e3..c8596564 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,12 @@
+1.4 pre-beta
+============
+
+[1] The TurboJPEG API can now be used to generate YUV images with an arbitrary
+line padding (previously, it only supported 4-byte padding, which was
+compatible with X Video.) Also, the decompress-to-YUV function has been
+extended to support image scaling.
+
+
1.3.0
=====
diff --git a/Makefile.am b/Makefile.am
index ade5034e..67ac7c12 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -205,6 +205,7 @@ endif
./tjunittest
./tjunittest -alloc
./tjunittest -yuv
+ ./tjunittest -yuv -noyuvpad
endif
./cjpeg -dct int -outfile testoutint.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_INT) testoutint.jpg
diff --git a/doc/html/annotated.html b/doc/html/annotated.html
index 6ad64d9f..2ab025bf 100644
--- a/doc/html/annotated.html
+++ b/doc/html/annotated.html
@@ -19,7 +19,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
- <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.2.1</span></div>
+ <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.4</span></div>
</td>
</tr>
</tbody>
@@ -81,7 +81,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
</iframe>
</div>
-<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 03:39:31 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 04:43:37 for TurboJPEG by&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.4 </small></address>
</body>
diff --git a/doc/html/classes.html b/doc/html/classes.html
index 12ff7455..c63ffd6a 100644
--- a/doc/html/classes.html
+++ b/doc/html/classes.html
@@ -19,7 +19,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
- <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.2.1</span></div>
+ <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.4</span></div>
</td>
</tr>
</tbody>
@@ -80,7 +80,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
</iframe>
</div>
-<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 03:39:31 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 04:43:37 for TurboJPEG by&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.4 </small></address>
</body>
diff --git a/doc/html/functions.html b/doc/html/functions.html
index 48575697..67bcd7a2 100644
--- a/doc/html/functions.html
+++ b/doc/html/functions.html
@@ -19,7 +19,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
- <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.2.1</span></div>
+ <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.4</span></div>
</td>
</tr>
</tbody>
@@ -113,7 +113,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
</iframe>
</div>
-<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 03:39:31 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 04:43:37 for TurboJPEG by&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.4 </small></address>
</body>
diff --git a/doc/html/functions_vars.html b/doc/html/functions_vars.html
index bdc91696..7a363e67 100644
--- a/doc/html/functions_vars.html
+++ b/doc/html/functions_vars.html
@@ -19,7 +19,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
- <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.2.1</span></div>
+ <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.4</span></div>
</td>
</tr>
</tbody>
@@ -113,7 +113,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
</iframe>
</div>
-<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 03:39:31 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 04:43:37 for TurboJPEG by&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.4 </small></address>
</body>
diff --git a/doc/html/group___turbo_j_p_e_g.html b/doc/html/group___turbo_j_p_e_g.html
index 3335c08d..918d1f3d 100644
--- a/doc/html/group___turbo_j_p_e_g.html
+++ b/doc/html/group___turbo_j_p_e_g.html
@@ -19,7 +19,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
- <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.2.1</span></div>
+ <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.4</span></div>
</td>
</tr>
</tbody>
@@ -169,10 +169,10 @@ Functions</h2></td></tr>
<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Compress an RGB or grayscale image into a JPEG image. <a href="#gaba62b7a98f960839b588579898495cf2"></a><br/></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">DLLEXPORT unsigned long DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gaccc5bca7f12fcdcc302e6e1c6d4b311b">tjBufSize</a> (int width, int height, int jpegSubsamp)</td></tr>
<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters. <a href="#gaccc5bca7f12fcdcc302e6e1c6d4b311b"></a><br/></td></tr>
-<tr><td class="memItemLeft" align="right" valign="top">DLLEXPORT unsigned long DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga9d0cb06fd5052d21b6f2b382db8b219c">tjBufSizeYUV</a> (int width, int height, int subsamp)</td></tr>
-<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">The size of the buffer (in bytes) required to hold a YUV planar image with the given parameters. <a href="#ga9d0cb06fd5052d21b6f2b382db8b219c"></a><br/></td></tr>
-<tr><td class="memItemLeft" align="right" valign="top">DLLEXPORT int DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga0fa4e7b1943687c6a0c0304529c55d35">tjEncodeYUV2</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf, int subsamp, int flags)</td></tr>
-<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Encode an RGB or grayscale image into a YUV planar image. <a href="#ga0fa4e7b1943687c6a0c0304529c55d35"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">DLLEXPORT unsigned long DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gaf451664a62c1f6c7cc5a6401f32908c9">tjBufSizeYUV2</a> (int width, int pad, int height, int subsamp)</td></tr>
+<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">The size of the buffer (in bytes) required to hold a YUV planar image with the given parameters. <a href="#gaf451664a62c1f6c7cc5a6401f32908c9"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">DLLEXPORT int DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga0a5ffbf7cb58a5b6a8201114fe889360">tjEncodeYUV3</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf, int pad, int subsamp, int flags)</td></tr>
+<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Encode an RGB or grayscale image into a YUV planar image. <a href="#ga0a5ffbf7cb58a5b6a8201114fe889360"></a><br/></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">DLLEXPORT <a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gae5408179d041e2a2f7199c8283cf649e">tjInitDecompress</a> (void)</td></tr>
<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Create a TurboJPEG decompressor instance. <a href="#gae5408179d041e2a2f7199c8283cf649e"></a><br/></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">DLLEXPORT int DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gac5675fceb7997b385516cdffdb34e6aa">tjDecompressHeader2</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, int *jpegSubsamp)</td></tr>
@@ -181,8 +181,8 @@ Functions</h2></td></tr>
<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns a list of fractional scaling factors that the JPEG decompressor in this implementation of TurboJPEG supports. <a href="#ga6449044b9af402999ccf52f401333be8"></a><br/></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">DLLEXPORT int DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gada69cc6443d1bb493b40f1626259e5e9">tjDecompress2</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, int height, int pixelFormat, int flags)</td></tr>
<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Decompress a JPEG image to an RGB or grayscale image. <a href="#gada69cc6443d1bb493b40f1626259e5e9"></a><br/></td></tr>
-<tr><td class="memItemLeft" align="right" valign="top">DLLEXPORT int DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gad7810af095624a4016e72957a50f77d8">tjDecompressToYUV</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, int flags)</td></tr>
-<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Decompress a JPEG image to a YUV planar image. <a href="#gad7810af095624a4016e72957a50f77d8"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">DLLEXPORT int DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga7c08b340ad7f8e85d407bd9e81d44d07">tjDecompressToYUV2</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, int width, int pad, int height, int flags)</td></tr>
+<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Decompress a JPEG image to a YUV planar image. <a href="#ga7c08b340ad7f8e85d407bd9e81d44d07"></a><br/></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">DLLEXPORT <a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga3155b775bfbac9dbba869b95a0367902">tjInitTransform</a> (void)</td></tr>
<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Create a new TurboJPEG transformer instance. <a href="#ga3155b775bfbac9dbba869b95a0367902"></a><br/></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">DLLEXPORT int DLLCALL&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gae403193ceb4aafb7e0f56ab587b48616">tjTransform</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, unsigned char *jpegBuf, unsigned long jpegSize, int n, unsigned char **dstBufs, unsigned long *dstSizes, <a class="el" href="structtjtransform.html">tjtransform</a> *transforms, int flags)</td></tr>
@@ -781,12 +781,12 @@ Variables</h2></td></tr>
</div>
</div>
-<a class="anchor" id="ga9d0cb06fd5052d21b6f2b382db8b219c"></a><!-- doxytag: member="turbojpeg.h::tjBufSizeYUV" ref="ga9d0cb06fd5052d21b6f2b382db8b219c" args="(int width, int height, int subsamp)" -->
+<a class="anchor" id="gaf451664a62c1f6c7cc5a6401f32908c9"></a><!-- doxytag: member="turbojpeg.h::tjBufSizeYUV2" ref="gaf451664a62c1f6c7cc5a6401f32908c9" args="(int width, int pad, int height, int subsamp)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">DLLEXPORT unsigned long DLLCALL tjBufSizeYUV </td>
+ <td class="memname">DLLEXPORT unsigned long DLLCALL tjBufSizeYUV2 </td>
<td>(</td>
<td class="paramtype">int&#160;</td>
<td class="paramname"><em>width</em>, </td>
@@ -795,6 +795,12 @@ Variables</h2></td></tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">int&#160;</td>
+ <td class="paramname"><em>pad</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&#160;</td>
<td class="paramname"><em>height</em>, </td>
</tr>
<tr>
@@ -816,6 +822,7 @@ Variables</h2></td></tr>
<dl><dt><b>Parameters:</b></dt><dd>
<table class="params">
<tr><td class="paramname">width</td><td>width of the image (in pixels) </td></tr>
+ <tr><td class="paramname">pad</td><td>the width of each line in each plane of the image is padded to the nearest multiple of this number of bytes (must be a power of 2.) </td></tr>
<tr><td class="paramname">height</td><td>height of the image (in pixels) </td></tr>
<tr><td class="paramname">subsamp</td><td>level of chrominance subsampling in the image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.)</td></tr>
</table>
@@ -1081,12 +1088,12 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
</div>
</div>
-<a class="anchor" id="gad7810af095624a4016e72957a50f77d8"></a><!-- doxytag: member="turbojpeg.h::tjDecompressToYUV" ref="gad7810af095624a4016e72957a50f77d8" args="(tjhandle handle, unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, int flags)" -->
+<a class="anchor" id="ga7c08b340ad7f8e85d407bd9e81d44d07"></a><!-- doxytag: member="turbojpeg.h::tjDecompressToYUV2" ref="ga7c08b340ad7f8e85d407bd9e81d44d07" args="(tjhandle handle, unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, int width, int pad, int height, int flags)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">DLLEXPORT int DLLCALL tjDecompressToYUV </td>
+ <td class="memname">DLLEXPORT int DLLCALL tjDecompressToYUV2 </td>
<td>(</td>
<td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
<td class="paramname"><em>handle</em>, </td>
@@ -1113,6 +1120,24 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
<td class="paramkey"></td>
<td></td>
<td class="paramtype">int&#160;</td>
+ <td class="paramname"><em>width</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&#160;</td>
+ <td class="paramname"><em>pad</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&#160;</td>
+ <td class="paramname"><em>height</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&#160;</td>
<td class="paramname"><em>flags</em>&#160;</td>
</tr>
<tr>
@@ -1125,13 +1150,16 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
<div class="memdoc">
<p>Decompress a JPEG image to a YUV planar image. </p>
-<p>This function performs JPEG decompression but leaves out the color conversion step, so a planar YUV image is generated instead of an RGB image. The padding of the planes in this image is the same as in the images generated by <a class="el" href="group___turbo_j_p_e_g.html#ga0fa4e7b1943687c6a0c0304529c55d35" title="Encode an RGB or grayscale image into a YUV planar image.">tjEncodeYUV2()</a>. Note that, if the width or height of the image is not an even multiple of the MCU block size (see <a class="el" href="group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c" title="MCU block width (in pixels) for a given level of chrominance subsampling.">tjMCUWidth</a> and <a class="el" href="group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf" title="MCU block height (in pixels) for a given level of chrominance subsampling.">tjMCUHeight</a>), then an intermediate buffer copy will be performed within TurboJPEG.</p>
+<p>This function performs JPEG decompression but leaves out the color conversion step, so a planar YUV image is generated instead of an RGB image. The structure of the planes in this image is the same as in the images generated by <a class="el" href="group___turbo_j_p_e_g.html#ga0a5ffbf7cb58a5b6a8201114fe889360" title="Encode an RGB or grayscale image into a YUV planar image.">tjEncodeYUV3()</a>. Note that, if the width or height of the JPEG image is not an even multiple of the MCU block size (see <a class="el" href="group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c" title="MCU block width (in pixels) for a given level of chrominance subsampling.">tjMCUWidth</a> and <a class="el" href="group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf" title="MCU block height (in pixels) for a given level of chrominance subsampling.">tjMCUHeight</a>), then an intermediate buffer copy will be performed within TurboJPEG.</p>
<dl><dt><b>Parameters:</b></dt><dd>
<table class="params">
<tr><td class="paramname">handle</td><td>a handle to a TurboJPEG decompressor or transformer instance </td></tr>
<tr><td class="paramname">jpegBuf</td><td>pointer to a buffer containing the JPEG image to decompress </td></tr>
<tr><td class="paramname">jpegSize</td><td>size of the JPEG image (in bytes) </td></tr>
- <tr><td class="paramname">dstBuf</td><td>pointer to an image buffer that will receive the YUV image. Use <a class="el" href="group___turbo_j_p_e_g.html#ga9d0cb06fd5052d21b6f2b382db8b219c" title="The size of the buffer (in bytes) required to hold a YUV planar image with the given parameters...">tjBufSizeYUV()</a> to determine the appropriate size for this buffer based on the image width, height, and level of subsampling. </td></tr>
+ <tr><td class="paramname">dstBuf</td><td>pointer to an image buffer that will receive the YUV image. Use <a class="el" href="group___turbo_j_p_e_g.html#gaf451664a62c1f6c7cc5a6401f32908c9" title="The size of the buffer (in bytes) required to hold a YUV planar image with the given parameters...">tjBufSizeYUV2()</a> to determine the appropriate size for this buffer based on the image width, height, padding, and level of subsampling. </td></tr>
+ <tr><td class="paramname">width</td><td>desired width (in pixels) of the YUV image. If this is different than the width of the JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG decompressor to generate the largest possible image that will fit within the desired width. If <code>width</code> is set to 0, then only the height will be considered when determining the scaled image size. </td></tr>
+ <tr><td class="paramname">pad</td><td>the width of each line in each plane of the YUV image will be padded to the nearest multiple of this number of bytes (must be a power of 2.) To generate images suitable for X Video, <code>pad</code> should be set to 4. </td></tr>
+ <tr><td class="paramname">height</td><td>desired height (in pixels) of the YUV image. If this is different than the height of the JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG decompressor to generate the largest possible image that will fit within the desired height. If <code>height</code> is set to 0, then only the width will be considered when determining the scaled image size. </td></tr>
<tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#ga72ecf4ebe6eb702d3c6f5ca27455e1ec">flags</a>.</td></tr>
</table>
</dd>
@@ -1166,12 +1194,12 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
</div>
</div>
-<a class="anchor" id="ga0fa4e7b1943687c6a0c0304529c55d35"></a><!-- doxytag: member="turbojpeg.h::tjEncodeYUV2" ref="ga0fa4e7b1943687c6a0c0304529c55d35" args="(tjhandle handle, unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf, int subsamp, int flags)" -->
+<a class="anchor" id="ga0a5ffbf7cb58a5b6a8201114fe889360"></a><!-- doxytag: member="turbojpeg.h::tjEncodeYUV3" ref="ga0a5ffbf7cb58a5b6a8201114fe889360" args="(tjhandle handle, unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf, int pad, int subsamp, int flags)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">DLLEXPORT int DLLCALL tjEncodeYUV2 </td>
+ <td class="memname">DLLEXPORT int DLLCALL tjEncodeYUV3 </td>
<td>(</td>
<td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
<td class="paramname"><em>handle</em>, </td>
@@ -1216,6 +1244,12 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
<td class="paramkey"></td>
<td></td>
<td class="paramtype">int&#160;</td>
+ <td class="paramname"><em>pad</em>, </td>
+ </tr>
+ <tr>
+ <td class="paramkey"></td>
+ <td></td>
+ <td class="paramtype">int&#160;</td>
<td class="paramname"><em>subsamp</em>, </td>
</tr>
<tr>
@@ -1234,7 +1268,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
<div class="memdoc">
<p>Encode an RGB or grayscale image into a YUV planar image. </p>
-<p>This function uses the accelerated color conversion routines in TurboJPEG's underlying codec to produce a planar YUV image that is suitable for X Video. Specifically, if the chrominance components are subsampled along the horizontal dimension, then the width of the luminance plane is padded to 2 in the output image (same goes for the height of the luminance plane, if the chrominance components are subsampled along the vertical dimension.) Also, each line of each plane in the output image is padded to 4 bytes. Although this will work with any subsampling option, it is really only useful in combination with TJ_420, which produces an image compatible with the I420 (AKA "YUV420P") format.</p>
+<p>This function uses the accelerated color conversion routines in TurboJPEG's underlying codec but does not execute any of the other steps in the JPEG compression process. The Y, U, and V image planes are stored sequentially into the destination buffer, and the size of each plane is determined by the width and height of the source image, as well as the specified padding and level of chrominance subsampling. If the chrominance components are subsampled along the horizontal dimension, then the width of the luminance plane is padded to the nearest multiple of 2 in the output image (same goes for the height of the luminance plane, if the chrominance components are subsampled along the vertical dimension.)</p>
<dl><dt><b>Parameters:</b></dt><dd>
<table class="params">
<tr><td class="paramname">handle</td><td>a handle to a TurboJPEG compressor or transformer instance </td></tr>
@@ -1243,8 +1277,9 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
<tr><td class="paramname">pitch</td><td>bytes per line of the source image. Normally, this should be <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code> if the image is unpadded, or <code><a class="el" href="group___turbo_j_p_e_g.html#ga0aba955473315e405295d978f0c16511" title="Pad the given width to the nearest 32-bit boundary.">TJPAD</a>(width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat])</code> if each line of the image is padded to the nearest 32-bit boundary, as is the case for Windows bitmaps. You can also be clever and use this parameter to skip lines, etc. Setting this parameter to 0 is the equivalent of setting it to <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code>. </td></tr>
<tr><td class="paramname">height</td><td>height (in pixels) of the source image </td></tr>
<tr><td class="paramname">pixelFormat</td><td>pixel format of the source image (see <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">Pixel formats</a>.) </td></tr>
- <tr><td class="paramname">dstBuf</td><td>pointer to an image buffer that will receive the YUV image. Use <a class="el" href="group___turbo_j_p_e_g.html#ga9d0cb06fd5052d21b6f2b382db8b219c" title="The size of the buffer (in bytes) required to hold a YUV planar image with the given parameters...">tjBufSizeYUV()</a> to determine the appropriate size for this buffer based on the image width, height, and level of chrominance subsampling. </td></tr>
- <tr><td class="paramname">subsamp</td><td>the level of chrominance subsampling to be used when generating the YUV image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.) </td></tr>
+ <tr><td class="paramname">dstBuf</td><td>pointer to an image buffer that will receive the YUV image. Use <a class="el" href="group___turbo_j_p_e_g.html#gaf451664a62c1f6c7cc5a6401f32908c9" title="The size of the buffer (in bytes) required to hold a YUV planar image with the given parameters...">tjBufSizeYUV2()</a> to determine the appropriate size for this buffer based on the image width, height, padding, and level of chrominance subsampling. </td></tr>
+ <tr><td class="paramname">pad</td><td>the width of each line in each plane of the YUV image will be padded to the nearest multiple of this number of bytes (must be a power of 2.) To generate images suitable for X Video, <code>pad</code> should be set to 4. </td></tr>
+ <tr><td class="paramname">subsamp</td><td>the level of chrominance subsampling to be used when generating the YUV image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.) To generate images suitable for X Video, <code>subsamp</code> should be set to <a class="el" href="group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a63085dbf683cfe39e513cdb6343e3737">TJSAMP_420</a>. This produces an image compatible with the I420 (AKA "YUV420P") format. </td></tr>
<tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#ga72ecf4ebe6eb702d3c6f5ca27455e1ec">flags</a>.</td></tr>
</table>
</dd>
@@ -1594,7 +1629,7 @@ If you choose option 1, <code>dstSizes[i]</code> should be set to the size of yo
</iframe>
</div>
-<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 03:39:31 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 04:43:37 for TurboJPEG by&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.4 </small></address>
</body>
diff --git a/doc/html/index.html b/doc/html/index.html
index 7c43e583..49e0d4b2 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -19,7 +19,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
- <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.2.1</span></div>
+ <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.4</span></div>
</td>
</tr>
</tbody>
@@ -69,7 +69,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
</iframe>
</div>
-<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 03:39:31 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 04:43:37 for TurboJPEG by&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.4 </small></address>
</body>
diff --git a/doc/html/modules.html b/doc/html/modules.html
index dbd8ecea..4570202f 100644
--- a/doc/html/modules.html
+++ b/doc/html/modules.html
@@ -19,7 +19,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
- <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.2.1</span></div>
+ <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.4</span></div>
</td>
</tr>
</tbody>
@@ -72,7 +72,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
</iframe>
</div>
-<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 03:39:31 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 04:43:37 for TurboJPEG by&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.4 </small></address>
</body>
diff --git a/doc/html/structtjregion.html b/doc/html/structtjregion.html
index d5cf5844..13bb812c 100644
--- a/doc/html/structtjregion.html
+++ b/doc/html/structtjregion.html
@@ -19,7 +19,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
- <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.2.1</span></div>
+ <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.4</span></div>
</td>
</tr>
</tbody>
@@ -165,7 +165,7 @@ Data Fields</h2></td></tr>
</iframe>
</div>
-<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 03:39:31 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 04:43:37 for TurboJPEG by&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.4 </small></address>
</body>
diff --git a/doc/html/structtjscalingfactor.html b/doc/html/structtjscalingfactor.html
index 5f1413bc..722221b9 100644
--- a/doc/html/structtjscalingfactor.html
+++ b/doc/html/structtjscalingfactor.html
@@ -19,7 +19,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
- <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.2.1</span></div>
+ <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.4</span></div>
</td>
</tr>
</tbody>
@@ -127,7 +127,7 @@ Data Fields</h2></td></tr>
</iframe>
</div>
-<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 03:39:31 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 04:43:37 for TurboJPEG by&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.4 </small></address>
</body>
diff --git a/doc/html/structtjtransform.html b/doc/html/structtjtransform.html
index 3e9cd551..9c5974c9 100644
--- a/doc/html/structtjtransform.html
+++ b/doc/html/structtjtransform.html
@@ -19,7 +19,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
- <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.2.1</span></div>
+ <div id="projectname">TurboJPEG&#160;<span id="projectnumber">1.4</span></div>
</td>
</tr>
</tbody>
@@ -191,7 +191,7 @@ Data Fields</h2></td></tr>
</iframe>
</div>
-<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 03:39:31 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Fri Apr 26 2013 04:43:37 for TurboJPEG by&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.4 </small></address>
</body>
diff --git a/doxygen.config b/doxygen.config
index 5a0b5a71..a293dbc9 100644
--- a/doxygen.config
+++ b/doxygen.config
@@ -1,5 +1,5 @@
PROJECT_NAME = TurboJPEG
-PROJECT_NUMBER = 1.2.1
+PROJECT_NUMBER = 1.4
OUTPUT_DIRECTORY = doc/
USE_WINDOWS_ENCODING = NO
OPTIMIZE_OUTPUT_FOR_C = YES
diff --git a/tjunittest.c b/tjunittest.c
index 89a6d1db..a1e6f334 100644
--- a/tjunittest.c
+++ b/tjunittest.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C)2009-2012 D. R. Commander. All Rights Reserved.
+ * Copyright (C)2009-2013 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:
@@ -47,6 +47,8 @@ void usage(char *progName)
printf("\nUSAGE: %s [options]\n", progName);
printf("Options:\n");
printf("-yuv = test YUV encoding/decoding support\n");
+ printf("-noyuvpad = do not pad each line of each Y, U, and V plane to the nearest\n");
+ printf(" 4-byte boundary.\n");
printf("-alloc = test automatic buffer allocation\n");
exit(1);
}
@@ -77,7 +79,7 @@ const int _onlyGray[]={TJPF_GRAY};
const int _onlyRGB[]={TJPF_RGB};
enum {YUVENCODE=1, YUVDECODE};
-int yuv=0, alloc=0;
+int yuv=0, alloc=0, pad=4;
int exitStatus=0;
#define bailout() {exitStatus=-1; goto bailout;}
@@ -236,22 +238,24 @@ int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp,
#define PAD(v, p) ((v+(p)-1)&(~((p)-1)))
-int checkBufYUV(unsigned char *buf, int w, int h, int subsamp)
+int checkBufYUV(unsigned char *buf, int w, int h, int subsamp,
+ tjscalingfactor sf)
{
int row, col;
int hsf=tjMCUWidth[subsamp]/8, vsf=tjMCUHeight[subsamp]/8;
int pw=PAD(w, hsf), ph=PAD(h, vsf);
int cw=pw/hsf, ch=ph/vsf;
- int ypitch=PAD(pw, 4), uvpitch=PAD(cw, 4);
+ int ypitch=PAD(pw, pad), uvpitch=PAD(cw, pad);
int retval=1;
- int halfway=16;
+ int halfway=16*sf.num/sf.denom;
+ int blocksize=8*sf.num/sf.denom;
for(row=0; row<ph; row++)
{
for(col=0; col<pw; col++)
{
unsigned char y=buf[ypitch*row+col];
- if(((row/8)+(col/8))%2==0)
+ if(((row/blocksize)+(col/blocksize))%2==0)
{
if(row<halfway) checkval255(y) else checkval0(y);
}
@@ -263,14 +267,14 @@ int checkBufYUV(unsigned char *buf, int w, int h, int subsamp)
}
if(subsamp!=TJSAMP_GRAY)
{
- halfway=16/vsf;
+ int halfway=16/vsf*sf.num/sf.denom;
for(row=0; row<ch; row++)
{
for(col=0; col<cw; col++)
{
unsigned char u=buf[ypitch*ph + (uvpitch*row+col)],
v=buf[ypitch*ph + uvpitch*ch + (uvpitch*row+col)];
- if(((row*vsf/8)+(col*hsf/8))%2==0)
+ if(((row*vsf/blocksize)+(col*hsf/blocksize))%2==0)
{
checkval(u, 128); checkval(v, 128);
}
@@ -356,7 +360,8 @@ void compTest(tjhandle handle, unsigned char **dstBuf,
t=gettime();
if(yuv==YUVENCODE)
{
- _tj(tjEncodeYUV2(handle, srcBuf, w, 0, h, pf, *dstBuf, subsamp, flags));
+ _tj(tjEncodeYUV3(handle, srcBuf, w, 0, h, pf, *dstBuf, pad, subsamp,
+ flags));
}
else
{
@@ -381,7 +386,8 @@ void compTest(tjhandle handle, unsigned char **dstBuf,
writeJPEG(*dstBuf, *dstSize, tempStr);
if(yuv==YUVENCODE)
{
- if(checkBufYUV(*dstBuf, w, h, subsamp)) printf("Passed.");
+ tjscalingfactor sf={1, 1};
+ if(checkBufYUV(*dstBuf, w, h, subsamp, sf)) printf("Passed.");
else printf("FAILED!");
}
else printf("Done.");
@@ -407,20 +413,19 @@ void _decompTest(tjhandle handle, unsigned char *jpegBuf,
if(yuv==YUVDECODE)
printf("JPEG -> YUV %s ... ", subName[subsamp]);
else
- {
printf("JPEG -> %s %s ", pixFormatStr[pf],
(flags&TJFLAG_BOTTOMUP)? "Bottom-Up":"Top-Down ");
- if(sf.num!=1 || sf.denom!=1)
- printf("%d/%d ... ", sf.num, sf.denom);
- else printf("... ");
- }
+ if(sf.num!=1 || sf.denom!=1)
+ printf("%d/%d ... ", sf.num, sf.denom);
+ else printf("... ");
_tj(tjDecompressHeader2(handle, jpegBuf, jpegSize, &_hdrw, &_hdrh,
&_hdrsubsamp));
if(_hdrw!=w || _hdrh!=h || _hdrsubsamp!=subsamp)
_throw("Incorrect JPEG header");
- if(yuv==YUVDECODE) dstSize=tjBufSizeYUV(w, h, subsamp);
+ if(yuv==YUVDECODE)
+ dstSize=tjBufSizeYUV2(scaledWidth, pad, scaledHeight, subsamp);
else dstSize=scaledWidth*scaledHeight*tjPixelSize[pf];
if((dstBuf=(unsigned char *)malloc(dstSize))==NULL)
_throw("Memory allocation failure");
@@ -429,7 +434,8 @@ void _decompTest(tjhandle handle, unsigned char *jpegBuf,
t=gettime();
if(yuv==YUVDECODE)
{
- _tj(tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flags));
+ _tj(tjDecompressToYUV2(handle, jpegBuf, jpegSize, dstBuf, scaledWidth,
+ pad, scaledHeight, flags));
}
else
{
@@ -440,7 +446,8 @@ void _decompTest(tjhandle handle, unsigned char *jpegBuf,
if(yuv==YUVDECODE)
{
- if(checkBufYUV(dstBuf, w, h, subsamp)) printf("Passed.");
+ if(checkBufYUV(dstBuf, scaledWidth, scaledHeight, subsamp, sf))
+ printf("Passed.");
else printf("FAILED!");
}
else
@@ -464,7 +471,7 @@ void decompTest(tjhandle handle, unsigned char *jpegBuf,
tjscalingfactor *sf=tjGetScalingFactors(&n), sf1={1, 1};
if(!sf || !n) _throwtj();
- if((subsamp==TJSAMP_444 || subsamp==TJSAMP_GRAY) && !yuv)
+ if(subsamp==TJSAMP_444 || subsamp==TJSAMP_GRAY)
{
for(i=0; i<n; i++)
_decompTest(handle, jpegBuf, jpegSize, w, h, pf, basename, subsamp,
@@ -488,7 +495,7 @@ void doTest(int w, int h, const int *formats, int nformats, int subsamp,
if(!alloc)
{
- size=(yuv==YUVENCODE? tjBufSizeYUV(w, h, subsamp)
+ size=(yuv==YUVENCODE? tjBufSizeYUV2(w, pad, h, subsamp)
: tjBufSize(w, h, subsamp));
if((dstBuf=(unsigned char *)tjAlloc(size))==NULL)
_throw("Memory allocation failure.");
@@ -610,6 +617,7 @@ int main(int argc, char *argv[])
for(i=1; i<argc; i++)
{
if(!strcasecmp(argv[i], "-yuv")) doyuv=1;
+ if(!strcasecmp(argv[i], "-noyuvpad")) pad=1;
if(!strcasecmp(argv[i], "-alloc")) alloc=1;
if(!strncasecmp(argv[i], "-h", 2) || !strcasecmp(argv[i], "-?"))
usage(argv[0]);
diff --git a/turbojpeg-mapfile b/turbojpeg-mapfile
index bd1ac715..21389b14 100755
--- a/turbojpeg-mapfile
+++ b/turbojpeg-mapfile
@@ -36,3 +36,11 @@ TURBOJPEG_1.2
tjInitTransform;
tjTransform;
} TURBOJPEG_1.1;
+
+TURBOJPEG_1.4
+{
+ global:
+ tjBufSizeYUV2;
+ tjDecompressToYUV2;
+ tjEncodeYUV3;
+} TURBOJPEG_1.2;
diff --git a/turbojpeg-mapfile.jni b/turbojpeg-mapfile.jni
index 52184a3b..59acf261 100755
--- a/turbojpeg-mapfile.jni
+++ b/turbojpeg-mapfile.jni
@@ -57,3 +57,11 @@ TURBOJPEG_1.2
Java_org_libjpegturbo_turbojpeg_TJTransformer_init;
Java_org_libjpegturbo_turbojpeg_TJTransformer_transform;
} TURBOJPEG_1.1;
+
+TURBOJPEG_1.4
+{
+ global:
+ tjBufSizeYUV2;
+ tjDecompressToYUV2;
+ tjEncodeYUV3;
+} TURBOJPEG_1.2;
diff --git a/turbojpeg.c b/turbojpeg.c
index b10de497..e5836491 100644
--- a/turbojpeg.c
+++ b/turbojpeg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C)2009-2012 D. R. Commander. All Rights Reserved.
+ * Copyright (C)2009-2013 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:
@@ -45,6 +45,7 @@ extern void jpeg_mem_dest_tj(j_compress_ptr, unsigned char **,
extern void jpeg_mem_src_tj(j_decompress_ptr, unsigned char *, unsigned long);
#define PAD(v, p) ((v+(p)-1)&(~((p)-1)))
+#define isPow2(x) (((x)&(x-1))==0)
/* Error handling (based on example in example.c) */
@@ -531,7 +532,6 @@ DLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height,
return retval;
}
-
DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height)
{
unsigned long retval=0;
@@ -548,22 +548,28 @@ DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height)
}
-DLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height,
+DLLEXPORT unsigned long DLLCALL tjBufSizeYUV2(int width, int pad, int height,
int subsamp)
{
unsigned long retval=0;
int pw, ph, cw, ch;
- if(width<1 || height<1 || subsamp<0 || subsamp>=NUMSUBOPT)
- _throw("tjBufSizeYUV(): Invalid argument");
+ if(width<1 || height<1 || pad<1 || !isPow2(pad) || subsamp<0
+ || subsamp>=NUMSUBOPT)
+ _throw("tjBufSizeYUV2(): Invalid argument");
pw=PAD(width, tjMCUWidth[subsamp]/8);
ph=PAD(height, tjMCUHeight[subsamp]/8);
cw=pw*8/tjMCUWidth[subsamp]; ch=ph*8/tjMCUHeight[subsamp];
- retval=PAD(pw, 4)*ph + (subsamp==TJSAMP_GRAY? 0:PAD(cw, 4)*ch*2);
+ retval=PAD(pw, pad)*ph + (subsamp==TJSAMP_GRAY? 0:PAD(cw, pad)*ch*2);
bailout:
return retval;
}
+DLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height,
+ int subsamp)
+{
+ return tjBufSizeYUV2(width, 4, height, subsamp);
+}
DLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height,
int subsamp)
@@ -670,9 +676,9 @@ DLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf,
}
-DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
+DLLEXPORT int DLLCALL tjEncodeYUV3(tjhandle handle, unsigned char *srcBuf,
int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf,
- int subsamp, int flags)
+ int pad, int subsamp, int flags)
{
int i, retval=0; JSAMPROW *row_pointer=NULL;
JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS];
@@ -688,7 +694,7 @@ DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
getinstance(handle);
if((this->init&COMPRESS)==0)
- _throw("tjEncodeYUV2(): Instance has not been initialized for compression");
+ _throw("tjEncodeYUV3(): Instance has not been initialized for compression");
for(i=0; i<MAX_COMPONENTS; i++)
{
@@ -697,9 +703,9 @@ DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
}
if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0
- || pixelFormat>=TJ_NUMPF || dstBuf==NULL || subsamp<0
- || subsamp>=NUMSUBOPT)
- _throw("tjEncodeYUV2(): Invalid argument");
+ || pixelFormat>=TJ_NUMPF || dstBuf==NULL || pad<0 || !isPow2(pad)
+ || subsamp<0 || subsamp>=NUMSUBOPT)
+ _throw("tjEncodeYUV3(): Invalid argument");
if(setjmp(this->jerr.setjmp_buffer))
{
@@ -714,7 +720,7 @@ DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
if(pixelFormat!=TJPF_GRAY)
{
rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE);
- if(!rgbBuf) _throw("tjEncodeYUV2(): Memory allocation failure");
+ if(!rgbBuf) _throw("tjEncodeYUV3(): Memory allocation failure");
srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf);
pitch=width*RGB_PIXELSIZE;
}
@@ -727,7 +733,7 @@ DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
- yuvsize=tjBufSizeYUV(width, height, subsamp);
+ yuvsize=tjBufSizeYUV2(width, pad, height, subsamp);
jpeg_mem_dest_tj(cinfo, &dstBuf, &yuvsize, 0);
if(setCompDefaults(cinfo, pixelFormat, subsamp, -1, flags)==-1) return -1;
@@ -736,7 +742,7 @@ DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
ph=PAD(height, cinfo->max_v_samp_factor);
if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph))==NULL)
- _throw("tjEncodeYUV2(): Memory allocation failure");
+ _throw("tjEncodeYUV3(): Memory allocation failure");
for(i=0; i<height; i++)
{
if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&srcBuf[(height-i-1)*pitch];
@@ -751,9 +757,9 @@ DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
_tmpbuf[i]=(JSAMPLE *)malloc(
PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE)
/compptr->h_samp_factor, 16) * cinfo->max_v_samp_factor + 16);
- if(!_tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure");
+ if(!_tmpbuf[i]) _throw("tjEncodeYUV3(): Memory allocation failure");
tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*cinfo->max_v_samp_factor);
- if(!tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure");
+ if(!tmpbuf[i]) _throw("tjEncodeYUV3(): Memory allocation failure");
for(row=0; row<cinfo->max_v_samp_factor; row++)
{
unsigned char *_tmpbuf_aligned=
@@ -764,9 +770,9 @@ DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
}
_tmpbuf2[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSIZE, 16)
* compptr->v_samp_factor + 16);
- if(!_tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failure");
+ if(!_tmpbuf2[i]) _throw("tjEncodeYUV3(): Memory allocation failure");
tmpbuf2[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_factor);
- if(!tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failure");
+ if(!tmpbuf2[i]) _throw("tjEncodeYUV3(): Memory allocation failure");
for(row=0; row<compptr->v_samp_factor; row++)
{
unsigned char *_tmpbuf2_aligned=
@@ -777,15 +783,15 @@ DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
cw[i]=pw*compptr->h_samp_factor/cinfo->max_h_samp_factor;
ch[i]=ph*compptr->v_samp_factor/cinfo->max_v_samp_factor;
outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]);
- if(!outbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure");
+ if(!outbuf[i]) _throw("tjEncodeYUV3(): Memory allocation failure");
for(row=0; row<ch[i]; row++)
{
outbuf[i][row]=ptr;
- ptr+=PAD(cw[i], 4);
+ ptr+=PAD(cw[i], pad);
}
}
if(yuvsize!=(unsigned long)(ptr-dstBuf))
- _throw("tjEncodeYUV2(): Generated image is not the correct size");
+ _throw("tjEncodeYUV3(): Generated image is not the correct size");
for(row=0; row<ph; row+=cinfo->max_v_samp_factor)
{
@@ -817,6 +823,14 @@ DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
return retval;
}
+DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
+ int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf,
+ int subsamp, int flags)
+{
+ return tjEncodeYUV3(handle, srcBuf, width, pitch, height, pixelFormat,
+ dstBuf, 4, subsamp, flags);
+}
+
DLLEXPORT int DLLCALL tjEncodeYUV(tjhandle handle, unsigned char *srcBuf,
int width, int pitch, int height, int pixelSize, unsigned char *dstBuf,
int subsamp, int flags)
@@ -973,7 +987,7 @@ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf,
scaledw=TJSCALED(jpegwidth, sf[i]);
scaledh=TJSCALED(jpegheight, sf[i]);
if(scaledw<=width && scaledh<=height)
- break;
+ break;
}
if(scaledw>width || scaledh>height)
_throw("tjDecompress2(): Could not scale down to desired image dimensions");
@@ -1039,26 +1053,28 @@ DLLEXPORT int DLLCALL tjDecompress(tjhandle handle, unsigned char *jpegBuf,
}
-DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle,
+DLLEXPORT int DLLCALL tjDecompressToYUV2(tjhandle handle,
unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf,
- int flags)
+ int width, int pad, int height, int flags)
{
- int i, row, retval=0; JSAMPROW *outbuf[MAX_COMPONENTS];
+ int i, sfi, row, retval=0; JSAMPROW *outbuf[MAX_COMPONENTS];
+ int jpegwidth, jpegheight, scaledw, scaledh;
int cw[MAX_COMPONENTS], ch[MAX_COMPONENTS], iw[MAX_COMPONENTS],
tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS];
JSAMPLE *_tmpbuf=NULL, *ptr=dstBuf; JSAMPROW *tmpbuf[MAX_COMPONENTS];
getinstance(handle);
if((this->init&DECOMPRESS)==0)
- _throw("tjDecompressToYUV(): Instance has not been initialized for decompression");
+ _throw("tjDecompressToYUV2(): Instance has not been initialized for decompression");
for(i=0; i<MAX_COMPONENTS; i++)
{
tmpbuf[i]=NULL; outbuf[i]=NULL;
}
- if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL)
- _throw("tjDecompressToYUV(): Invalid argument");
+ if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pad<1
+ || !isPow2(pad) || height<0)
+ _throw("tjDecompressToYUV2(): Invalid argument");
if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
@@ -1074,36 +1090,54 @@ DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle,
jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize);
jpeg_read_header(dinfo, TRUE);
+ jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height;
+ if(width==0) width=jpegwidth;
+ if(height==0) height=jpegheight;
+ for(i=0; i<NUMSF; i++)
+ {
+ scaledw=TJSCALED(jpegwidth, sf[i]);
+ scaledh=TJSCALED(jpegheight, sf[i]);
+ if(scaledw<=width && scaledh<=height)
+ break;
+ }
+ if(scaledw>width || scaledh>height)
+ _throw("tjDecompressToYUV2(): Could not scale down to desired image dimensions");
+ width=scaledw; height=scaledh;
+ dinfo->scale_num=sf[i].num;
+ dinfo->scale_denom=sf[i].denom;
+ sfi=i;
+ jpeg_calc_output_dimensions(dinfo);
+
for(i=0; i<dinfo->num_components; i++)
{
jpeg_component_info *compptr=&dinfo->comp_info[i];
int ih;
- iw[i]=compptr->width_in_blocks*DCTSIZE;
- ih=compptr->height_in_blocks*DCTSIZE;
- cw[i]=PAD(dinfo->image_width, dinfo->max_h_samp_factor)
+ iw[i]=compptr->width_in_blocks*DCTSIZE*sf[sfi].num/sf[sfi].denom;
+ ih=compptr->height_in_blocks*DCTSIZE*sf[sfi].num/sf[sfi].denom;
+ cw[i]=PAD(dinfo->output_width, dinfo->max_h_samp_factor)
*compptr->h_samp_factor/dinfo->max_h_samp_factor;
- ch[i]=PAD(dinfo->image_height, dinfo->max_v_samp_factor)
+ ch[i]=PAD(dinfo->output_height, dinfo->max_v_samp_factor)
*compptr->v_samp_factor/dinfo->max_v_samp_factor;
if(iw[i]!=cw[i] || ih!=ch[i]) usetmpbuf=1;
- th[i]=compptr->v_samp_factor*DCTSIZE;
+ th[i]=compptr->v_samp_factor*DCTSIZE*sf[sfi].num/sf[sfi].denom;
tmpbufsize+=iw[i]*th[i];
if((outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]))==NULL)
- _throw("tjDecompressToYUV(): Memory allocation failure");
+ _throw("tjDecompressToYUV2(): Memory allocation failure");
for(row=0; row<ch[i]; row++)
{
outbuf[i][row]=ptr;
- ptr+=PAD(cw[i], 4);
+ ptr+=PAD(cw[i], pad);
}
}
if(usetmpbuf)
{
if((_tmpbuf=(JSAMPLE *)malloc(sizeof(JSAMPLE)*tmpbufsize))==NULL)
- _throw("tjDecompressToYUV(): Memory allocation failure");
+ _throw("tjDecompressToYUV2(): Memory allocation failure");
ptr=_tmpbuf;
for(i=0; i<dinfo->num_components; i++)
{
if((tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*th[i]))==NULL)
- _throw("tjDecompressToYUV(): Memory allocation failure");
+ _throw("tjDecompressToYUV2(): Memory allocation failure");
for(row=0; row<th[i]; row++)
{
tmpbuf[i][row]=ptr;
@@ -1118,7 +1152,7 @@ DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle,
jpeg_start_decompress(dinfo);
for(row=0; row<(int)dinfo->output_height;
- row+=dinfo->max_v_samp_factor*DCTSIZE)
+ row+=dinfo->max_v_samp_factor*DCTSIZE*sf[sfi].num/sf[sfi].denom)
{
JSAMPARRAY yuvptr[MAX_COMPONENTS];
int crow[MAX_COMPONENTS];
@@ -1129,7 +1163,8 @@ DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle,
if(usetmpbuf) yuvptr[i]=tmpbuf[i];
else yuvptr[i]=&outbuf[i][crow[i]];
}
- jpeg_read_raw_data(dinfo, yuvptr, dinfo->max_v_samp_factor*DCTSIZE);
+ jpeg_read_raw_data(dinfo, yuvptr,
+ dinfo->max_v_samp_factor*DCTSIZE*sf[sfi].num/sf[sfi].denom);
if(usetmpbuf)
{
int j;
@@ -1155,6 +1190,13 @@ DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle,
return retval;
}
+DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle,
+ unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf,
+ int flags)
+{
+ return tjDecompressToYUV2(handle, jpegBuf, jpegSize, dstBuf, 0, 4, 0, flags);
+}
+
/* Transformer */
diff --git a/turbojpeg.h b/turbojpeg.h
index 3fc6c39d..c7a29a03 100644
--- a/turbojpeg.h
+++ b/turbojpeg.h
@@ -587,6 +587,8 @@ DLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height,
* the given parameters.
*
* @param width width of the image (in pixels)
+ * @param pad the width of each line in each plane of the image is padded to
+ * the nearest multiple of this number of bytes (must be a power of 2.)
* @param height height of the image (in pixels)
* @param subsamp level of chrominance subsampling in the image (see
* @ref TJSAMP "Chrominance subsampling options".)
@@ -594,22 +596,22 @@ DLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height,
* @return the size of the buffer (in bytes) required to hold the image, or
* -1 if the arguments are out of bounds.
*/
-DLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height,
+DLLEXPORT unsigned long DLLCALL tjBufSizeYUV2(int width, int pad, int height,
int subsamp);
/**
* Encode an RGB or grayscale image into a YUV planar image. This function
* uses the accelerated color conversion routines in TurboJPEG's underlying
- * codec to produce a planar YUV image that is suitable for X Video.
- * Specifically, if the chrominance components are subsampled along the
- * horizontal dimension, then the width of the luminance plane is padded to 2
- * in the output image (same goes for the height of the luminance plane, if the
- * chrominance components are subsampled along the vertical dimension.) Also,
- * each line of each plane in the output image is padded to 4 bytes. Although
- * this will work with any subsampling option, it is really only useful in
- * combination with TJ_420, which produces an image compatible with the I420
- * (AKA "YUV420P") format.
+ * codec but does not execute any of the other steps in the JPEG compression
+ * process. The Y, U, and V image planes are stored sequentially into the
+ * destination buffer, and the size of each plane is determined by the width
+ * and height of the source image, as well as the specified padding and level
+ * of chrominance subsampling. If the chrominance components are subsampled
+ * along the horizontal dimension, then the width of the luminance plane is
+ * padded to the nearest multiple of 2 in the output image (same goes for the
+ * height of the luminance plane, if the chrominance components are subsampled
+ * along the vertical dimension.)
*
* @param handle a handle to a TurboJPEG compressor or transformer instance
* @param srcBuf pointer to an image buffer containing RGB or grayscale pixels
@@ -626,20 +628,26 @@ DLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height,
* @param pixelFormat pixel format of the source image (see @ref TJPF
* "Pixel formats".)
* @param dstBuf pointer to an image buffer that will receive the YUV image.
- * Use #tjBufSizeYUV() to determine the appropriate size for this buffer
- * based on the image width, height, and level of chrominance
- * subsampling.
+ * Use #tjBufSizeYUV2() to determine the appropriate size for this
+ * buffer based on the image width, height, padding, and level of
+ * chrominance subsampling.
+ * @param pad the width of each line in each plane of the YUV image will be
+ * padded to the nearest multiple of this number of bytes (must be a
+ * power of 2.) To generate images suitable for X Video, <tt>pad</tt>
+ * should be set to 4.
* @param subsamp the level of chrominance subsampling to be used when
* generating the YUV image (see @ref TJSAMP
- * "Chrominance subsampling options".)
+ * "Chrominance subsampling options".) To generate images suitable for
+ * X Video, <tt>subsamp</tt> should be set to @ref TJSAMP_420. This
+ * produces an image compatible with the I420 (AKA "YUV420P") format.
* @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP
* "flags".
*
* @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().)
*/
-DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle,
+DLLEXPORT int DLLCALL tjEncodeYUV3(tjhandle handle,
unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat,
- unsigned char *dstBuf, int subsamp, int flags);
+ unsigned char *dstBuf, int pad, int subsamp, int flags);
/**
@@ -736,26 +744,43 @@ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle,
/**
* Decompress a JPEG image to a YUV planar image. This function performs JPEG
* decompression but leaves out the color conversion step, so a planar YUV
- * image is generated instead of an RGB image. The padding of the planes in
- * this image is the same as in the images generated by #tjEncodeYUV2(). Note
- * that, if the width or height of the image is not an even multiple of the MCU
- * block size (see #tjMCUWidth and #tjMCUHeight), then an intermediate buffer
- * copy will be performed within TurboJPEG.
+ * image is generated instead of an RGB image. The structure of the planes in
+ * this image is the same as in the images generated by #tjEncodeYUV3(). Note
+ * that, if the width or height of the JPEG image is not an even multiple of
+ * the MCU block size (see #tjMCUWidth and #tjMCUHeight), then an intermediate
+ * buffer copy will be performed within TurboJPEG.
*
* @param handle a handle to a TurboJPEG decompressor or transformer instance
* @param jpegBuf pointer to a buffer containing the JPEG image to decompress
* @param jpegSize size of the JPEG image (in bytes)
* @param dstBuf pointer to an image buffer that will receive the YUV image.
- * Use #tjBufSizeYUV() to determine the appropriate size for this buffer
- * based on the image width, height, and level of subsampling.
+ * Use #tjBufSizeYUV2() to determine the appropriate size for this
+ * buffer based on the image width, height, padding, and level of
+ * subsampling.
+ * @param width desired width (in pixels) of the YUV image. If this is
+ * different than the width of the JPEG image being decompressed, then
+ * TurboJPEG will use scaling in the JPEG decompressor to generate the
+ * largest possible image that will fit within the desired width. If
+ * <tt>width</tt> is set to 0, then only the height will be considered
+ * when determining the scaled image size.
+ * @param pad the width of each line in each plane of the YUV image will be
+ * padded to the nearest multiple of this number of bytes (must be a
+ * power of 2.) To generate images suitable for X Video, <tt>pad</tt>
+ * should be set to 4.
+ * @param height desired height (in pixels) of the YUV image. If this is
+ * different than the height of the JPEG image being decompressed, then
+ * TurboJPEG will use scaling in the JPEG decompressor to generate the
+ * largest possible image that will fit within the desired height. If
+ * <tt>height</tt> is set to 0, then only the width will be considered
+ * when determining the scaled image size.
* @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP
* "flags".
*
* @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().)
*/
-DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle,
+DLLEXPORT int DLLCALL tjDecompressToYUV2(tjhandle handle,
unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf,
- int flags);
+ int width, int pad, int height, int flags);
/**
@@ -892,6 +917,9 @@ DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height);
DLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height,
int jpegSubsamp);
+DLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height,
+ int subsamp);
+
DLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf,
int width, int pitch, int height, int pixelSize, unsigned char *dstBuf,
unsigned long *compressedSize, int jpegSubsamp, int jpegQual, int flags);
@@ -900,6 +928,10 @@ DLLEXPORT int DLLCALL tjEncodeYUV(tjhandle handle,
unsigned char *srcBuf, int width, int pitch, int height, int pixelSize,
unsigned char *dstBuf, int subsamp, int flags);
+DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle,
+ unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat,
+ unsigned char *dstBuf, int subsamp, int flags);
+
DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle,
unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height);
@@ -907,6 +939,10 @@ DLLEXPORT int DLLCALL tjDecompress(tjhandle handle,
unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf,
int width, int pitch, int height, int pixelSize, int flags);
+DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle,
+ unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf,
+ int flags);
+
/**
* @}