Implement custom filter callback in Java


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@707 632fc199-4ca6-4c93-a231-07263d6284db
diff --git a/doc/html/annotated.html b/doc/html/annotated.html
index c820c27..4e2ee2b 100644
--- a/doc/html/annotated.html
+++ b/doc/html/annotated.html
@@ -81,7 +81,7 @@
 </iframe>
 </div>
 
-<hr class="footer"/><address class="footer"><small>Generated on Fri Sep 16 2011 19:05:46 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Tue Sep 20 2011 00:00:45 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 25f7b49..c2d9cdc 100644
--- a/doc/html/classes.html
+++ b/doc/html/classes.html
@@ -80,7 +80,7 @@
 </iframe>
 </div>
 
-<hr class="footer"/><address class="footer"><small>Generated on Fri Sep 16 2011 19:05:46 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Tue Sep 20 2011 00:00:45 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 51ad994..a9a3dae 100644
--- a/doc/html/functions.html
+++ b/doc/html/functions.html
@@ -65,7 +65,10 @@
 <div class="contents">
 <div class="textblock">Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:</div><ul>
 <li>customFilter
-: <a class="el" href="structtjtransform.html#a3b9280f092324befdf4da07ac085d9dd">tjtransform</a>
+: <a class="el" href="structtjtransform.html#a43ee1bcdd2a8d7249a756774f78793c1">tjtransform</a>
+</li>
+<li>data
+: <a class="el" href="structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3">tjtransform</a>
 </li>
 <li>denom
 : <a class="el" href="structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3">tjscalingfactor</a>
@@ -110,7 +113,7 @@
 </iframe>
 </div>
 
-<hr class="footer"/><address class="footer"><small>Generated on Fri Sep 16 2011 19:05:46 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Tue Sep 20 2011 00:00:45 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 d2f9092..1601bec 100644
--- a/doc/html/functions_vars.html
+++ b/doc/html/functions_vars.html
@@ -65,7 +65,10 @@
 <div class="contents">
 &#160;<ul>
 <li>customFilter
-: <a class="el" href="structtjtransform.html#a3b9280f092324befdf4da07ac085d9dd">tjtransform</a>
+: <a class="el" href="structtjtransform.html#a43ee1bcdd2a8d7249a756774f78793c1">tjtransform</a>
+</li>
+<li>data
+: <a class="el" href="structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3">tjtransform</a>
 </li>
 <li>denom
 : <a class="el" href="structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3">tjscalingfactor</a>
@@ -110,7 +113,7 @@
 </iframe>
 </div>
 
-<hr class="footer"/><address class="footer"><small>Generated on Fri Sep 16 2011 19:05:46 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Tue Sep 20 2011 00:00:45 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 caf54ec..9b50306 100644
--- a/doc/html/group___turbo_j_p_e_g.html
+++ b/doc/html/group___turbo_j_p_e_g.html
@@ -111,6 +111,8 @@
 <tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Compute the scaled value of <code>dimension</code> using the given scaling factor.  <a href="#ga84878bb65404204743aa18cac02781df"></a><br/></td></tr>
 <tr><td colspan="2"><h2><a name="typedef-members"></a>
 Typedefs</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structtjtransform.html">tjtransform</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gaa29f3189c41be12ec5dee7caec318a31">tjtransform</a></td></tr>
+<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Lossless transform.  <a href="#gaa29f3189c41be12ec5dee7caec318a31"></a><br/></td></tr>
 <tr><td class="memItemLeft" align="right" valign="top">typedef void *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a></td></tr>
 <tr><td class="mdescLeft">&#160;</td><td class="mdescRight">TurboJPEG instance handle.  <a href="#ga758d2634ecb4949de7815cba621f5763"></a><br/></td></tr>
 <tr><td colspan="2"><h2><a name="enum-members"></a>
@@ -496,6 +498,21 @@
 
 </div>
 </div>
+<a class="anchor" id="gaa29f3189c41be12ec5dee7caec318a31"></a><!-- doxytag: member="turbojpeg.h::tjtransform" ref="gaa29f3189c41be12ec5dee7caec318a31" args="" -->
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">typedef struct <a class="el" href="structtjtransform.html">tjtransform</a>  <a class="el" href="structtjtransform.html">tjtransform</a></td>
+        </tr>
+      </table>
+</div>
+<div class="memdoc">
+
+<p>Lossless transform. </p>
+
+</div>
+</div>
 <hr/><h2>Enumeration Type Documentation</h2>
 <a class="anchor" id="gac916144e26c3817ac514e64ae5d12e2a"></a><!-- doxytag: member="turbojpeg.h::TJPF" ref="gac916144e26c3817ac514e64ae5d12e2a" args="" -->
 <div class="memitem">
@@ -1519,7 +1536,7 @@
 </iframe>
 </div>
 
-<hr class="footer"/><address class="footer"><small>Generated on Fri Sep 16 2011 19:05:46 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Tue Sep 20 2011 00:00:45 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 5869403..41360df 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -69,7 +69,7 @@
 </iframe>
 </div>
 
-<hr class="footer"/><address class="footer"><small>Generated on Fri Sep 16 2011 19:05:45 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Tue Sep 20 2011 00:00:45 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 b3773f4..aef313d 100644
--- a/doc/html/modules.html
+++ b/doc/html/modules.html
@@ -72,7 +72,7 @@
 </iframe>
 </div>
 
-<hr class="footer"/><address class="footer"><small>Generated on Fri Sep 16 2011 19:05:46 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Tue Sep 20 2011 00:00:45 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/search/all_64.html b/doc/html/search/all_64.html
index 5db4361..2e53b02 100644
--- a/doc/html/search/all_64.html
+++ b/doc/html/search/all_64.html
@@ -7,9 +7,15 @@
 <body class="SRPage">
 <div id="SRIndex">
 <div class="SRStatus" id="Loading">Loading...</div>
+<div class="SRResult" id="SR_data">
+ <div class="SREntry">
+  <a id="Item0" onkeydown="return searchResults.Nav(event,0)" onkeypress="return searchResults.Nav(event,0)" onkeyup="return searchResults.Nav(event,0)" class="SRSymbol" href="../structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3" target="_parent">data</a>
+  <span class="SRScope">tjtransform</span>
+ </div>
+</div>
 <div class="SRResult" id="SR_denom">
  <div class="SREntry">
-  <a id="Item0" onkeydown="return searchResults.Nav(event,0)" onkeypress="return searchResults.Nav(event,0)" onkeyup="return searchResults.Nav(event,0)" class="SRSymbol" href="../structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3" target="_parent">denom</a>
+  <a id="Item1" onkeydown="return searchResults.Nav(event,1)" onkeypress="return searchResults.Nav(event,1)" onkeyup="return searchResults.Nav(event,1)" class="SRSymbol" href="../structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3" target="_parent">denom</a>
   <span class="SRScope">tjscalingfactor</span>
  </div>
 </div>
diff --git a/doc/html/search/variables_64.html b/doc/html/search/variables_64.html
index 5db4361..2e53b02 100644
--- a/doc/html/search/variables_64.html
+++ b/doc/html/search/variables_64.html
@@ -7,9 +7,15 @@
 <body class="SRPage">
 <div id="SRIndex">
 <div class="SRStatus" id="Loading">Loading...</div>
+<div class="SRResult" id="SR_data">
+ <div class="SREntry">
+  <a id="Item0" onkeydown="return searchResults.Nav(event,0)" onkeypress="return searchResults.Nav(event,0)" onkeyup="return searchResults.Nav(event,0)" class="SRSymbol" href="../structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3" target="_parent">data</a>
+  <span class="SRScope">tjtransform</span>
+ </div>
+</div>
 <div class="SRResult" id="SR_denom">
  <div class="SREntry">
-  <a id="Item0" onkeydown="return searchResults.Nav(event,0)" onkeypress="return searchResults.Nav(event,0)" onkeyup="return searchResults.Nav(event,0)" class="SRSymbol" href="../structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3" target="_parent">denom</a>
+  <a id="Item1" onkeydown="return searchResults.Nav(event,1)" onkeypress="return searchResults.Nav(event,1)" onkeyup="return searchResults.Nav(event,1)" class="SRSymbol" href="../structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3" target="_parent">denom</a>
   <span class="SRScope">tjscalingfactor</span>
  </div>
 </div>
diff --git a/doc/html/structtjregion.html b/doc/html/structtjregion.html
index b0f1103..f56d382 100644
--- a/doc/html/structtjregion.html
+++ b/doc/html/structtjregion.html
@@ -165,7 +165,7 @@
 </iframe>
 </div>
 
-<hr class="footer"/><address class="footer"><small>Generated on Fri Sep 16 2011 19:05:46 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Tue Sep 20 2011 00:00:45 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 ac63350..4456e59 100644
--- a/doc/html/structtjscalingfactor.html
+++ b/doc/html/structtjscalingfactor.html
@@ -127,7 +127,7 @@
 </iframe>
 </div>
 
-<hr class="footer"/><address class="footer"><small>Generated on Fri Sep 16 2011 19:05:46 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Tue Sep 20 2011 00:00:45 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 348dfdc..e38ebfc 100644
--- a/doc/html/structtjtransform.html
+++ b/doc/html/structtjtransform.html
@@ -77,18 +77,20 @@
 <tr><td class="mdescLeft">&#160;</td><td class="mdescRight">One of the <a class="el" href="group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866">transform operations</a>.  <a href="#a2525aab4ba6978a1c273f74fef50e498"></a><br/></td></tr>
 <tr><td class="memItemLeft" align="right" valign="top">int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6">options</a></td></tr>
 <tr><td class="mdescLeft">&#160;</td><td class="mdescRight">The bitwise OR of one of more of the <a class="el" href="group___turbo_j_p_e_g.html#ga9c771a757fc1294add611906b89ab2d2">transform options</a>.  <a href="#ac0e74655baa4402209a21e1ae481c8f6"></a><br/></td></tr>
-<tr><td class="memItemLeft" align="right" valign="top">int(*&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjtransform.html#a3b9280f092324befdf4da07ac085d9dd">customFilter</a> )(short *coeffs, <a class="el" href="structtjregion.html">tjregion</a> arrayRegion, <a class="el" href="structtjregion.html">tjregion</a> planeRegion, int componentIndex, int transformIndex)</td></tr>
-<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">A callback function that can be used to modify the DCT coefficients after they are losslessly transformed but before they are transcoded to a new JPEG file.  <a href="#a3b9280f092324befdf4da07ac085d9dd"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3">data</a></td></tr>
+<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Arbitrary data that can be accessed within the body of the callback function.  <a href="#a688fe8f1a8ecc12a538d9e561cf338e3"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int(*&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjtransform.html#a43ee1bcdd2a8d7249a756774f78793c1">customFilter</a> )(short *coeffs, <a class="el" href="structtjregion.html">tjregion</a> arrayRegion, <a class="el" href="structtjregion.html">tjregion</a> planeRegion, int componentIndex, int transformIndex, struct <a class="el" href="structtjtransform.html">tjtransform</a> *transform)</td></tr>
+<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">A callback function that can be used to modify the DCT coefficients after they are losslessly transformed but before they are transcoded to a new JPEG file.  <a href="#a43ee1bcdd2a8d7249a756774f78793c1"></a><br/></td></tr>
 </table>
 <hr/><a name="details" id="details"></a><h2>Detailed Description</h2>
 <div class="textblock"><p>Lossless transform. </p>
 </div><hr/><h2>Field Documentation</h2>
-<a class="anchor" id="a3b9280f092324befdf4da07ac085d9dd"></a><!-- doxytag: member="tjtransform::customFilter" ref="a3b9280f092324befdf4da07ac085d9dd" args=")(short *coeffs, tjregion arrayRegion, tjregion planeRegion, int componentIndex, int transformIndex)" -->
+<a class="anchor" id="a43ee1bcdd2a8d7249a756774f78793c1"></a><!-- doxytag: member="tjtransform::customFilter" ref="a43ee1bcdd2a8d7249a756774f78793c1" args=")(short *coeffs, tjregion arrayRegion, tjregion planeRegion, int componentIndex, int transformIndex, struct tjtransform *transform)" -->
 <div class="memitem">
 <div class="memproto">
       <table class="memname">
         <tr>
-          <td class="memname">int(* <a class="el" href="structtjtransform.html#a3b9280f092324befdf4da07ac085d9dd">tjtransform::customFilter</a>)(short *coeffs, <a class="el" href="structtjregion.html">tjregion</a> arrayRegion, <a class="el" href="structtjregion.html">tjregion</a> planeRegion, int componentIndex, int transformIndex)</td>
+          <td class="memname">int(* <a class="el" href="structtjtransform.html#a43ee1bcdd2a8d7249a756774f78793c1">tjtransform::customFilter</a>)(short *coeffs, <a class="el" href="structtjregion.html">tjregion</a> arrayRegion, <a class="el" href="structtjregion.html">tjregion</a> planeRegion, int componentIndex, int transformIndex, struct <a class="el" href="structtjtransform.html">tjtransform</a> *transform)</td>
         </tr>
       </table>
 </div>
@@ -98,11 +100,12 @@
 <p>This allows for custom filters or other transformations to be applied in the frequency domain.</p>
 <dl><dt><b>Parameters:</b></dt><dd>
   <table class="params">
-    <tr><td class="paramname">coeffs</td><td>pointer to an array of DCT coefficients. (NOTE: this pointer is not guaranteed to be valid once the callback returns, so applications wishing to hand off the DCT coefficients to another function or library should make a copy of them within the body of the callback.) </td></tr>
-    <tr><td class="paramname">arrayRegion</td><td>region structure containing the width and height of the DCT coefficient array as well as its offset relative to the component plane. TurboJPEG implementations may choose to split each component plane into multiple DCT coefficient arrays and call the callback function once for each array. </td></tr>
-    <tr><td class="paramname">planeRegion</td><td>region structure containing the width and height of the component plane to which this DCT coefficient array belongs </td></tr>
-    <tr><td class="paramname">componentIndex</td><td>the component plane to which this DCT coefficient array belongs (Y, Cb, and Cr are, respectively, 0, 1, and 2 in typical JPEG images.) </td></tr>
-    <tr><td class="paramname">transformIndex</td><td>the transformed image to which this DCT coefficient array belongs</td></tr>
+    <tr><td class="paramname">coeffs</td><td>pointer to an array of transformed DCT coefficients. (NOTE: this pointer is not guaranteed to be valid once the callback returns, so applications wishing to hand off the DCT coefficients to another function or library should make a copy of them within the body of the callback.) </td></tr>
+    <tr><td class="paramname">arrayRegion</td><td><a class="el" href="structtjregion.html" title="Cropping region.">tjregion</a> structure containing the width and height of <code>coeffs</code> as well as its offset relative to the component plane. TurboJPEG implementations may choose to split each component plane into multiple DCT coefficient arrays and call the callback function once for each array. </td></tr>
+    <tr><td class="paramname">planeRegion</td><td><a class="el" href="structtjregion.html" title="Cropping region.">tjregion</a> structure containing the width and height of the component plane to which <code>coeffs</code> belongs </td></tr>
+    <tr><td class="paramname">componentID</td><td>ID number of the component plane to which <code>coeffs</code> belongs (Y, Cb, and Cr have, respectively, ID's of 0, 1, and 2 in typical JPEG images.) </td></tr>
+    <tr><td class="paramname">transformID</td><td>ID number of the transformed image to which <code>coeffs</code> belongs. This is the same as the index of the transform in the transforms array that was passed to <a class="el" href="group___turbo_j_p_e_g.html#gae403193ceb4aafb7e0f56ab587b48616" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a>. </td></tr>
+    <tr><td class="paramname">transform</td><td>a pointer to a <a class="el" href="structtjtransform.html" title="Lossless transform.">tjtransform</a> structure that specifies the parameters and/or cropping region for this transform</td></tr>
   </table>
   </dd>
 </dl>
@@ -110,6 +113,21 @@
 
 </div>
 </div>
+<a class="anchor" id="a688fe8f1a8ecc12a538d9e561cf338e3"></a><!-- doxytag: member="tjtransform::data" ref="a688fe8f1a8ecc12a538d9e561cf338e3" args="" -->
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">void* <a class="el" href="structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3">tjtransform::data</a></td>
+        </tr>
+      </table>
+</div>
+<div class="memdoc">
+
+<p>Arbitrary data that can be accessed within the body of the callback function. </p>
+
+</div>
+</div>
 <a class="anchor" id="a2525aab4ba6978a1c273f74fef50e498"></a><!-- doxytag: member="tjtransform::op" ref="a2525aab4ba6978a1c273f74fef50e498" args="" -->
 <div class="memitem">
 <div class="memproto">
@@ -173,7 +191,7 @@
 </iframe>
 </div>
 
-<hr class="footer"/><address class="footer"><small>Generated on Fri Sep 16 2011 19:05:46 for TurboJPEG by&#160;
+<hr class="footer"/><address class="footer"><small>Generated on Tue Sep 20 2011 00:00:45 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/java/Makefile.am b/java/Makefile.am
index 82e9c13..4a1b34e 100644
--- a/java/Makefile.am
+++ b/java/Makefile.am
@@ -2,6 +2,7 @@
 
 JAVASOURCES = org/libjpegturbo/turbojpeg/TJ.java \
 	org/libjpegturbo/turbojpeg/TJCompressor.java \
+	org/libjpegturbo/turbojpeg/TJCustomFilter.java \
 	org/libjpegturbo/turbojpeg/TJDecompressor.java \
 	org/libjpegturbo/turbojpeg/TJLoader.java \
 	org/libjpegturbo/turbojpeg/TJScalingFactor.java \
@@ -21,6 +22,7 @@
 
 JAVA_CLASSES = org/libjpegturbo/turbojpeg/TJ.class \
 	org/libjpegturbo/turbojpeg/TJCompressor.class \
+	org/libjpegturbo/turbojpeg/TJCustomFilter.class \
 	org/libjpegturbo/turbojpeg/TJDecompressor.class \
 	org/libjpegturbo/turbojpeg/TJLoader.class \
 	org/libjpegturbo/turbojpeg/TJScalingFactor.class \
diff --git a/java/TJExample.java b/java/TJExample.java
index a326c71..36c1a8f 100644
--- a/java/TJExample.java
+++ b/java/TJExample.java
@@ -32,12 +32,14 @@
  */
 
 import java.io.*;
+import java.awt.*;
 import java.awt.image.*;
+import java.nio.*;
 import javax.imageio.*;
 import javax.swing.*;
 import org.libjpegturbo.turbojpeg.*;
 
-public class TJExample {
+public class TJExample implements TJCustomFilter {
 
   public static final String classname = new TJExample().getClass().getName();
 
@@ -165,7 +167,9 @@
             xform.op = TJTransform.OP_ROT180;
           if(argv[i].equalsIgnoreCase("-rot270"))
             xform.op = TJTransform.OP_ROT270;
-          if(argv[i].length() > 2
+          if(argv[i].equalsIgnoreCase("-custom"))
+            xform.cf = new TJExample();
+          else if(argv[i].length() > 2
             && argv[i].substring(0, 2).equalsIgnoreCase("-c")) {
             if(i >= argv.length - 1) usage();
             String[] cropArg = argv[++i].split(",");
@@ -211,7 +215,8 @@
         fis.close();
 
         TJDecompressor tjd;
-        if(xform.op != TJTransform.OP_NONE || xform.options != 0) {
+        if(xform.op != TJTransform.OP_NONE || xform.options != 0
+          || xform.cf != null) {
           TJTransformer tjt = new TJTransformer(inputBuf);
           TJTransform t[] = new TJTransform[1];
           t[0] = xform;
@@ -303,5 +308,13 @@
     }
   }
 
+  public void customFilter(ShortBuffer coeffBuffer, Rectangle bufferRegion,
+    Rectangle planeRegion, int componentIndex, int transformIndex,
+    TJTransform transform) throws Exception {
+    for(int i=0; i<bufferRegion.width*bufferRegion.height; i++) {
+	    coeffBuffer.put(i, (short)(-coeffBuffer.get(i)));
+    }
+  }
+
   static TJScalingFactor sf [] = null;
 };
diff --git a/java/doc/allclasses-frame.html b/java/doc/allclasses-frame.html
index 1ed402a..071e3a2 100644
--- a/java/doc/allclasses-frame.html
+++ b/java/doc/allclasses-frame.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 All Classes
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
 
@@ -25,6 +25,8 @@
 <BR>
 <A HREF="org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJCompressor</A>
 <BR>
+<A HREF="org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg" target="classFrame"><I>TJCustomFilter</I></A>
+<BR>
 <A HREF="org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJDecompressor</A>
 <BR>
 <A HREF="org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJScalingFactor</A>
diff --git a/java/doc/allclasses-noframe.html b/java/doc/allclasses-noframe.html
index dd2f4f1..148fac6 100644
--- a/java/doc/allclasses-noframe.html
+++ b/java/doc/allclasses-noframe.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 All Classes
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
 
@@ -25,6 +25,8 @@
 <BR>
 <A HREF="org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</A>
 <BR>
+<A HREF="org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><I>TJCustomFilter</I></A>
+<BR>
 <A HREF="org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</A>
 <BR>
 <A HREF="org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</A>
diff --git a/java/doc/constant-values.html b/java/doc/constant-values.html
index abfbf15..8a6d8d9 100644
--- a/java/doc/constant-values.html
+++ b/java/doc/constant-values.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 Constant Field Values
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
 
@@ -299,6 +299,12 @@
 <TD ALIGN="right"><CODE>8</CODE></TD>
 </TR>
 <TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.libjpegturbo.turbojpeg.TJTransform.OPT_NOOUTPUT"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/libjpegturbo/turbojpeg/TJTransform.html#OPT_NOOUTPUT">OPT_NOOUTPUT</A></CODE></TD>
+<TD ALIGN="right"><CODE>16</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
 <A NAME="org.libjpegturbo.turbojpeg.TJTransform.OPT_PERFECT"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
 <CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
 <TD ALIGN="left"><CODE><A HREF="org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PERFECT">OPT_PERFECT</A></CODE></TD>
diff --git a/java/doc/deprecated-list.html b/java/doc/deprecated-list.html
index f8ea290..0e1178d 100644
--- a/java/doc/deprecated-list.html
+++ b/java/doc/deprecated-list.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 Deprecated List
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
 
diff --git a/java/doc/help-doc.html b/java/doc/help-doc.html
index 1733e1f..4c4b064 100644
--- a/java/doc/help-doc.html
+++ b/java/doc/help-doc.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 API Help
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
 
diff --git a/java/doc/index-all.html b/java/doc/index-all.html
index 8940402..0b45436 100644
--- a/java/doc/index-all.html
+++ b/java/doc/index-all.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 Index
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="./stylesheet.css" TITLE="Style">
 
@@ -94,6 +94,9 @@
 <A NAME="_C_"><!-- --></A><H2>
 <B>C</B></H2>
 <DL>
+<DT><A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html#cf"><B>cf</B></A> - 
+Variable in class org.libjpegturbo.turbojpeg.<A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</A>
+<DD>Custom filter instance
 <DT><A HREF="./org/libjpegturbo/turbojpeg/TJCompressor.html#close()"><B>close()</B></A> - 
 Method in class org.libjpegturbo.turbojpeg.<A HREF="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</A>
 <DD>Free the native structures associated with this compressor instance.
@@ -116,6 +119,11 @@
 Method in class org.libjpegturbo.turbojpeg.<A HREF="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</A>
 <DD>Compress the uncompressed source image stored in <code>srcImage</code>
  and return a buffer containing a JPEG image.
+<DT><A HREF="./org/libjpegturbo/turbojpeg/TJCustomFilter.html#customFilter(java.nio.ShortBuffer, java.awt.Rectangle, java.awt.Rectangle, int, int, org.libjpegturbo.turbojpeg.TJTransform)"><B>customFilter(ShortBuffer, Rectangle, Rectangle, int, int, TJTransform)</B></A> - 
+Method in interface org.libjpegturbo.turbojpeg.<A HREF="./org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</A>
+<DD>A callback function that can be used to modify the DCT coefficients after
+ they are losslessly transformed but before they are transcoded to a new
+ JPEG file.
 </DL>
 <HR>
 <A NAME="_D_"><!-- --></A><H2>
@@ -376,6 +384,10 @@
 Static variable in class org.libjpegturbo.turbojpeg.<A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</A>
 <DD>This option will discard the color data in the input image and produce
  a grayscale output image.
+<DT><A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html#OPT_NOOUTPUT"><B>OPT_NOOUTPUT</B></A> - 
+Static variable in class org.libjpegturbo.turbojpeg.<A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</A>
+<DD>This option will prevent <A HREF="./org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][], org.libjpegturbo.turbojpeg.TJTransform[], int)"><CODE>TJTransformer.transform()</CODE></A> from outputting a JPEG image for this
+ particular transform.
 <DT><A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PERFECT"><B>OPT_PERFECT</B></A> - 
 Static variable in class org.libjpegturbo.turbojpeg.<A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</A>
 <DD>This option will cause <A HREF="./org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][], org.libjpegturbo.turbojpeg.TJTransform[], int)"><CODE>TJTransformer.transform()</CODE></A> to throw an exception if the transform is not
@@ -463,7 +475,7 @@
 <DD>Create a TurboJPEG compressor instance and associate the uncompressed
  source image stored in <code>srcImage</code> with the newly-created
  instance.
-<DT><A HREF="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><B>TJDecompressor</B></A> - Class in <A HREF="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</A><DD>TurboJPEG decompressor<DT><A HREF="./org/libjpegturbo/turbojpeg/TJDecompressor.html#TJDecompressor()"><B>TJDecompressor()</B></A> - 
+<DT><A HREF="./org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><B>TJCustomFilter</B></A> - Interface in <A HREF="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</A><DD>Custom filter callback interface<DT><A HREF="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><B>TJDecompressor</B></A> - Class in <A HREF="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</A><DD>TurboJPEG decompressor<DT><A HREF="./org/libjpegturbo/turbojpeg/TJDecompressor.html#TJDecompressor()"><B>TJDecompressor()</B></A> - 
 Constructor for class org.libjpegturbo.turbojpeg.<A HREF="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</A>
 <DD>Create a TurboJPEG decompresssor instance.
 <DT><A HREF="./org/libjpegturbo/turbojpeg/TJDecompressor.html#TJDecompressor(byte[])"><B>TJDecompressor(byte[])</B></A> - 
@@ -481,10 +493,10 @@
 <DT><A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg"><B>TJTransform</B></A> - Class in <A HREF="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</A><DD>Lossless transform parameters<DT><A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform()"><B>TJTransform()</B></A> - 
 Constructor for class org.libjpegturbo.turbojpeg.<A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</A>
 <DD>Create a new lossless transform instance.
-<DT><A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(int, int, int, int, int, int)"><B>TJTransform(int, int, int, int, int, int)</B></A> - 
+<DT><A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(int, int, int, int, int, int, org.libjpegturbo.turbojpeg.TJCustomFilter)"><B>TJTransform(int, int, int, int, int, int, TJCustomFilter)</B></A> - 
 Constructor for class org.libjpegturbo.turbojpeg.<A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</A>
 <DD>Create a new lossless transform instance with the given parameters.
-<DT><A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(java.awt.Rectangle, int, int)"><B>TJTransform(Rectangle, int, int)</B></A> - 
+<DT><A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(java.awt.Rectangle, int, int, org.libjpegturbo.turbojpeg.TJCustomFilter)"><B>TJTransform(Rectangle, int, int, TJCustomFilter)</B></A> - 
 Constructor for class org.libjpegturbo.turbojpeg.<A HREF="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</A>
 <DD>Create a new lossless transform instance with the given parameters.
 <DT><A HREF="./org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg"><B>TJTransformer</B></A> - Class in <A HREF="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</A><DD>TurboJPEG lossless transformer<DT><A HREF="./org/libjpegturbo/turbojpeg/TJTransformer.html#TJTransformer()"><B>TJTransformer()</B></A> - 
diff --git a/java/doc/index.html b/java/doc/index.html
index 64965ea..a96eb27 100644
--- a/java/doc/index.html
+++ b/java/doc/index.html
@@ -2,7 +2,7 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc on Mon Jul 11 21:40:35 CDT 2011-->
+<!-- Generated by javadoc on Mon Sep 19 23:46:08 CDT 2011-->
 <TITLE>
 Generated Documentation (Untitled)
 </TITLE>
diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJ.html b/java/doc/org/libjpegturbo/turbojpeg/TJ.html
index 6c07d32..1119f02 100644
--- a/java/doc/org/libjpegturbo/turbojpeg/TJ.html
+++ b/java/doc/org/libjpegturbo/turbojpeg/TJ.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 TJ
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
 
diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html b/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html
index 566c877..9c3479a 100644
--- a/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html
+++ b/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 TJCompressor
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
 
@@ -54,7 +54,7 @@
 <TR>
 <TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
 &nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><B>NEXT CLASS</B></A></FONT></TD>
 <TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
   <A HREF="../../../index.html?org/libjpegturbo/turbojpeg/TJCompressor.html" target="_top"><B>FRAMES</B></A>  &nbsp;
 &nbsp;<A HREF="TJCompressor.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
@@ -662,7 +662,7 @@
 <TR>
 <TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
 &nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><B>PREV CLASS</B></A>&nbsp;
-&nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><B>NEXT CLASS</B></A></FONT></TD>
+&nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><B>NEXT CLASS</B></A></FONT></TD>
 <TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
   <A HREF="../../../index.html?org/libjpegturbo/turbojpeg/TJCompressor.html" target="_top"><B>FRAMES</B></A>  &nbsp;
 &nbsp;<A HREF="TJCompressor.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJCustomFilter.html b/java/doc/org/libjpegturbo/turbojpeg/TJCustomFilter.html
new file mode 100644
index 0000000..d88fcc6
--- /dev/null
+++ b/java/doc/org/libjpegturbo/turbojpeg/TJCustomFilter.html
@@ -0,0 +1,240 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
+<TITLE>
+TJCustomFilter
+</TITLE>
+
+<META NAME="date" CONTENT="2011-09-19">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+    if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title="TJCustomFilter";
+    }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../org/libjpegturbo/turbojpeg/package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/libjpegturbo/turbojpeg/TJCustomFilter.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="TJCustomFilter.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.libjpegturbo.turbojpeg</FONT>
+<BR>
+Interface TJCustomFilter</H2>
+<HR>
+<DL>
+<DT><PRE>public interface <B>TJCustomFilter</B></DL>
+</PRE>
+
+<P>
+Custom filter callback interface
+<P>
+
+<P>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html#customFilter(java.nio.ShortBuffer, java.awt.Rectangle, java.awt.Rectangle, int, int, org.libjpegturbo.turbojpeg.TJTransform)">customFilter</A></B>(java.nio.ShortBuffer&nbsp;coeffBuffer,
+             java.awt.Rectangle&nbsp;bufferRegion,
+             java.awt.Rectangle&nbsp;planeRegion,
+             int&nbsp;componentID,
+             int&nbsp;transformID,
+             <A HREF="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</A>&nbsp;transform)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A callback function that can be used to modify the DCT coefficients after
+ they are losslessly transformed but before they are transcoded to a new
+ JPEG file.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="customFilter(java.nio.ShortBuffer, java.awt.Rectangle, java.awt.Rectangle, int, int, org.libjpegturbo.turbojpeg.TJTransform)"><!-- --></A><H3>
+customFilter</H3>
+<PRE>
+void <B>customFilter</B>(java.nio.ShortBuffer&nbsp;coeffBuffer,
+                  java.awt.Rectangle&nbsp;bufferRegion,
+                  java.awt.Rectangle&nbsp;planeRegion,
+                  int&nbsp;componentID,
+                  int&nbsp;transformID,
+                  <A HREF="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</A>&nbsp;transform)
+                  throws java.lang.Exception</PRE>
+<DL>
+<DD>A callback function that can be used to modify the DCT coefficients after
+ they are losslessly transformed but before they are transcoded to a new
+ JPEG file.  This allows for custom filters or other transformations to be
+ applied in the frequency domain.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>coeffBuffer</CODE> - a buffer containing transformed DCT coefficients.
+ (NOTE: this buffer is not guaranteed to be valid once the callback
+ returns, so applications wishing to hand off the DCT coefficients to
+ another function or library should make a copy of them within the body of
+ the callback.)<DD><CODE>bufferRegion</CODE> - rectangle containing the width and height of
+ <code>coeffBuffer</code> as well as its offset relative to the component
+ plane.  TurboJPEG implementations may choose to split each component plane
+ into multiple DCT coefficient buffers and call the callback function once
+ for each buffer.<DD><CODE>planeRegion</CODE> - rectangle containing the width and height of the
+ component plane to which <code>coeffBuffer</code> belongs<DD><CODE>componentID</CODE> - ID number of the component plane to which
+ <code>coeffBuffer</code>belongs (Y, Cb, and Cr have, respectively, ID's of
+ 0, 1, and 2 in typical JPEG images.)<DD><CODE>transformID</CODE> - ID number of the transformed image to which
+ <code>coeffBuffer</code> belongs.  This is the same as the index of the
+ transform in the transforms array that was passed to <A HREF="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][], org.libjpegturbo.turbojpeg.TJTransform[], int)"><CODE>TJTransformer.transform()</CODE></A>.<DD><CODE>transform</CODE> - a <A HREF="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg"><CODE>TJTransform</CODE></A> instance that specifies the
+ parameters and/or cropping region for this transform
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.Exception</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../org/libjpegturbo/turbojpeg/package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="../../../index.html?org/libjpegturbo/turbojpeg/TJCustomFilter.html" target="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="TJCustomFilter.html" target="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+  <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html b/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html
index 4d37d71..d8ede5e 100644
--- a/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html
+++ b/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 TJDecompressor
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
 
@@ -53,7 +53,7 @@
 
 <TR>
 <TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><B>PREV CLASS</B></A>&nbsp;
 &nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg"><B>NEXT CLASS</B></A></FONT></TD>
 <TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
   <A HREF="../../../index.html?org/libjpegturbo/turbojpeg/TJDecompressor.html" target="_top"><B>FRAMES</B></A>  &nbsp;
@@ -913,7 +913,7 @@
 
 <TR>
 <TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
-&nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><B>PREV CLASS</B></A>&nbsp;
 &nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg"><B>NEXT CLASS</B></A></FONT></TD>
 <TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
   <A HREF="../../../index.html?org/libjpegturbo/turbojpeg/TJDecompressor.html" target="_top"><B>FRAMES</B></A>  &nbsp;
diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html b/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html
index 166acfb..5d9682a 100644
--- a/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html
+++ b/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 TJScalingFactor
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
 
diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJTransform.html b/java/doc/org/libjpegturbo/turbojpeg/TJTransform.html
index bb64cc3..e10ace5 100644
--- a/java/doc/org/libjpegturbo/turbojpeg/TJTransform.html
+++ b/java/doc/org/libjpegturbo/turbojpeg/TJTransform.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 TJTransform
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
 
@@ -143,6 +143,14 @@
 </TR>
 <TR BGCOLOR="white" CLASS="TableRowColor">
 <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/libjpegturbo/turbojpeg/TJTransform.html#cf">cf</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Custom filter instance</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
 <CODE>static&nbsp;int</CODE></FONT></TD>
 <TD><CODE><B><A HREF="../../../org/libjpegturbo/turbojpeg/TJTransform.html#NUMOP">NUMOP</A></B></CODE>
 
@@ -242,6 +250,15 @@
 <TR BGCOLOR="white" CLASS="TableRowColor">
 <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
 <CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_NOOUTPUT">OPT_NOOUTPUT</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This option will prevent <A HREF="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][], org.libjpegturbo.turbojpeg.TJTransform[], int)"><CODE>TJTransformer.transform()</CODE></A> from outputting a JPEG image for this
+ particular transform.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
 <TD><CODE><B><A HREF="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PERFECT">OPT_PERFECT</A></B></CODE>
 
 <BR>
@@ -300,20 +317,22 @@
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create a new lossless transform instance.</TD>
 </TR>
 <TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../../org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(int, int, int, int, int, int)">TJTransform</A></B>(int&nbsp;x,
+<TD><CODE><B><A HREF="../../../org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(int, int, int, int, int, int, org.libjpegturbo.turbojpeg.TJCustomFilter)">TJTransform</A></B>(int&nbsp;x,
             int&nbsp;y,
             int&nbsp;w,
             int&nbsp;h,
             int&nbsp;op,
-            int&nbsp;options)</CODE>
+            int&nbsp;options,
+            <A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</A>&nbsp;cf)</CODE>
 
 <BR>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create a new lossless transform instance with the given parameters.</TD>
 </TR>
 <TR BGCOLOR="white" CLASS="TableRowColor">
-<TD><CODE><B><A HREF="../../../org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(java.awt.Rectangle, int, int)">TJTransform</A></B>(java.awt.Rectangle&nbsp;r,
+<TD><CODE><B><A HREF="../../../org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(java.awt.Rectangle, int, int, org.libjpegturbo.turbojpeg.TJCustomFilter)">TJTransform</A></B>(java.awt.Rectangle&nbsp;r,
             int&nbsp;op,
-            int&nbsp;options)</CODE>
+            int&nbsp;options,
+            <A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</A>&nbsp;cf)</CODE>
 
 <BR>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create a new lossless transform instance with the given parameters.</TD>
@@ -569,6 +588,21 @@
 </DL>
 <HR>
 
+<A NAME="OPT_NOOUTPUT"><!-- --></A><H3>
+OPT_NOOUTPUT</H3>
+<PRE>
+public static final int <B>OPT_NOOUTPUT</B></PRE>
+<DL>
+<DD>This option will prevent <A HREF="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][], org.libjpegturbo.turbojpeg.TJTransform[], int)"><CODE>TJTransformer.transform()</CODE></A> from outputting a JPEG image for this
+ particular transform.  This can be used in conjunction with a custom
+ filter to capture the transformed DCT coefficients without transcoding
+ them.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OPT_NOOUTPUT">Constant Field Values</A></DL>
+</DL>
+<HR>
+
 <A NAME="op"><!-- --></A><H3>
 op</H3>
 <PRE>
@@ -591,6 +625,18 @@
 <DL>
 </DL>
 </DL>
+<HR>
+
+<A NAME="cf"><!-- --></A><H3>
+cf</H3>
+<PRE>
+public <A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</A> <B>cf</B></PRE>
+<DL>
+<DD>Custom filter instance
+<P>
+<DL>
+</DL>
+</DL>
 
 <!-- ========= CONSTRUCTOR DETAIL ======== -->
 
@@ -612,7 +658,7 @@
 </DL>
 <HR>
 
-<A NAME="TJTransform(int, int, int, int, int, int)"><!-- --></A><H3>
+<A NAME="TJTransform(int, int, int, int, int, int, org.libjpegturbo.turbojpeg.TJCustomFilter)"><!-- --></A><H3>
 TJTransform</H3>
 <PRE>
 public <B>TJTransform</B>(int&nbsp;x,
@@ -620,7 +666,8 @@
                    int&nbsp;w,
                    int&nbsp;h,
                    int&nbsp;op,
-                   int&nbsp;options)
+                   int&nbsp;options,
+                   <A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</A>&nbsp;cf)
             throws java.lang.Exception</PRE>
 <DL>
 <DD>Create a new lossless transform instance with the given parameters.
@@ -631,27 +678,28 @@
  divisible by the MCU block height (see <A HREF="../../../org/libjpegturbo/turbojpeg/TJ.html#getMCUHeight(int)"><CODE>TJ.getMCUHeight(int)</CODE></A>)<DD><CODE>w</CODE> - the width of the cropping region.  Setting this to 0 is the
  equivalent of setting it to the width of the source JPEG image - x.<DD><CODE>h</CODE> - the height of the cropping region.  Setting this to 0 is the
  equivalent of setting it to the height of the source JPEG image - y.<DD><CODE>op</CODE> - one of the transform operations (<code>OP_*</code>)<DD><CODE>options</CODE> - the bitwise OR of one or more of the transform options
- (<code>OPT_*</code>)
+ (<code>OPT_*</code>)<DD><CODE>cf</CODE> - an instance of an object that implements the <A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><CODE>TJCustomFilter</CODE></A> interface, or null if no custom filter is needed
 <DT><B>Throws:</B>
 <DD><CODE>java.lang.Exception</CODE></DL>
 </DL>
 <HR>
 
-<A NAME="TJTransform(java.awt.Rectangle, int, int)"><!-- --></A><H3>
+<A NAME="TJTransform(java.awt.Rectangle, int, int, org.libjpegturbo.turbojpeg.TJCustomFilter)"><!-- --></A><H3>
 TJTransform</H3>
 <PRE>
 public <B>TJTransform</B>(java.awt.Rectangle&nbsp;r,
                    int&nbsp;op,
-                   int&nbsp;options)
+                   int&nbsp;options,
+                   <A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</A>&nbsp;cf)
             throws java.lang.Exception</PRE>
 <DL>
 <DD>Create a new lossless transform instance with the given parameters.
 <P>
 <DL>
 <DT><B>Parameters:</B><DD><CODE>r</CODE> - a <code>Rectangle</code> instance which specifies the cropping
- region.  See <A HREF="../../../org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(int, int, int, int, int, int)"><CODE>TJTransform(int, int, int, int, int, int)</CODE></A> for more
+ region.  See <A HREF="../../../org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(int, int, int, int, int, int, org.libjpegturbo.turbojpeg.TJCustomFilter)"><CODE>TJTransform(int, int, int, int, int, int, TJCustomFilter)</CODE></A> for more
  detail.<DD><CODE>op</CODE> - one of the transform operations (<code>OP_*</code>)<DD><CODE>options</CODE> - the bitwise OR of one or more of the transform options
- (<code>OPT_*</code>)
+ (<code>OPT_*</code>)<DD><CODE>cf</CODE> - an instance of an object that implements the <A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><CODE>TJCustomFilter</CODE></A> interface, or null if no custom filter is needed
 <DT><B>Throws:</B>
 <DD><CODE>java.lang.Exception</CODE></DL>
 </DL>
diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJTransformer.html b/java/doc/org/libjpegturbo/turbojpeg/TJTransformer.html
index 280b82f..c61c8f2 100644
--- a/java/doc/org/libjpegturbo/turbojpeg/TJTransformer.html
+++ b/java/doc/org/libjpegturbo/turbojpeg/TJTransformer.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 TJTransformer
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
 
diff --git a/java/doc/org/libjpegturbo/turbojpeg/package-frame.html b/java/doc/org/libjpegturbo/turbojpeg/package-frame.html
index cb1e2b8..0fd2512 100644
--- a/java/doc/org/libjpegturbo/turbojpeg/package-frame.html
+++ b/java/doc/org/libjpegturbo/turbojpeg/package-frame.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 org.libjpegturbo.turbojpeg
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
 
@@ -20,6 +20,17 @@
 <TABLE BORDER="0" WIDTH="100%" SUMMARY="">
 <TR>
 <TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Interfaces</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg" target="classFrame"><I>TJCustomFilter</I></A></FONT></TD>
+</TR>
+</TABLE>
+
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
 Classes</FONT>&nbsp;
 <FONT CLASS="FrameItemFont">
 <BR>
diff --git a/java/doc/org/libjpegturbo/turbojpeg/package-summary.html b/java/doc/org/libjpegturbo/turbojpeg/package-summary.html
index caf1b95..52b963b 100644
--- a/java/doc/org/libjpegturbo/turbojpeg/package-summary.html
+++ b/java/doc/org/libjpegturbo/turbojpeg/package-summary.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 org.libjpegturbo.turbojpeg
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
 
@@ -84,6 +84,20 @@
 <TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
 <TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
 <TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Interface Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</A></B></TD>
+<TD>Custom filter callback interface</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
 <B>Class Summary</B></FONT></TH>
 </TR>
 <TR BGCOLOR="white" CLASS="TableRowColor">
diff --git a/java/doc/org/libjpegturbo/turbojpeg/package-tree.html b/java/doc/org/libjpegturbo/turbojpeg/package-tree.html
index 58d8672..ecb8596 100644
--- a/java/doc/org/libjpegturbo/turbojpeg/package-tree.html
+++ b/java/doc/org/libjpegturbo/turbojpeg/package-tree.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 org.libjpegturbo.turbojpeg Class Hierarchy
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
 
@@ -99,6 +99,11 @@
 <LI TYPE="circle">org.libjpegturbo.turbojpeg.<A HREF="../../../org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg"><B>TJTransformer</B></A></UL>
 <LI TYPE="circle">org.libjpegturbo.turbojpeg.<A HREF="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg"><B>TJScalingFactor</B></A></UL>
 </UL>
+<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">org.libjpegturbo.turbojpeg.<A HREF="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><B>TJCustomFilter</B></A></UL>
 <HR>
 
 
diff --git a/java/doc/overview-tree.html b/java/doc/overview-tree.html
index 6ba3d6d..6f1e784 100644
--- a/java/doc/overview-tree.html
+++ b/java/doc/overview-tree.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 Class Hierarchy
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
 
@@ -101,6 +101,11 @@
 <LI TYPE="circle">org.libjpegturbo.turbojpeg.<A HREF="org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg"><B>TJTransformer</B></A></UL>
 <LI TYPE="circle">org.libjpegturbo.turbojpeg.<A HREF="org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg"><B>TJScalingFactor</B></A></UL>
 </UL>
+<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">org.libjpegturbo.turbojpeg.<A HREF="org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><B>TJCustomFilter</B></A></UL>
 <HR>
 
 
diff --git a/java/doc/serialized-form.html b/java/doc/serialized-form.html
index 3f08701..c1a0b75 100644
--- a/java/doc/serialized-form.html
+++ b/java/doc/serialized-form.html
@@ -2,12 +2,12 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 11 21:40:35 CDT 2011 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Sep 19 23:46:08 CDT 2011 -->
 <TITLE>
 Serialized Form
 </TITLE>
 
-<META NAME="date" CONTENT="2011-07-11">
+<META NAME="date" CONTENT="2011-09-19">
 
 <LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
 
@@ -132,6 +132,17 @@
 <DL>
 </DL>
 </DL>
+<HR>
+<H3>
+cf</H3>
+<PRE>
+<A HREF="org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</A> <B>cf</B></PRE>
+<DL>
+<DD>Custom filter instance
+<P>
+<DL>
+</DL>
+</DL>
 
 <P>
 <HR>
diff --git a/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java b/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java
new file mode 100644
index 0000000..711225b
--- /dev/null
+++ b/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C)2011 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:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of the libjpeg-turbo Project nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.libjpegturbo.turbojpeg;
+
+import java.awt.*;
+import java.nio.*;
+
+/**
+ * Custom filter callback interface
+ */
+public interface TJCustomFilter {
+
+  /**
+   * A callback function that can be used to modify the DCT coefficients after
+   * they are losslessly transformed but before they are transcoded to a new
+   * JPEG file.  This allows for custom filters or other transformations to be
+   * applied in the frequency domain.
+   *
+   * @param coeffBuffer a buffer containing transformed DCT coefficients.
+   * (NOTE: this buffer is not guaranteed to be valid once the callback
+   * returns, so applications wishing to hand off the DCT coefficients to
+   * another function or library should make a copy of them within the body of
+   * the callback.)
+   *
+   * @param bufferRegion rectangle containing the width and height of
+   * <code>coeffBuffer</code> as well as its offset relative to the component
+   * plane.  TurboJPEG implementations may choose to split each component plane
+   * into multiple DCT coefficient buffers and call the callback function once
+   * for each buffer.
+   *
+   * @param planeRegion rectangle containing the width and height of the
+   * component plane to which <code>coeffBuffer</code> belongs
+   *
+   * @param componentID ID number of the component plane to which
+   * <code>coeffBuffer</code>belongs (Y, Cb, and Cr have, respectively, ID's of
+   * 0, 1, and 2 in typical JPEG images.)
+   *
+   * @param transformID ID number of the transformed image to which
+   * <code>coeffBuffer</code> belongs.  This is the same as the index of the
+   * transform in the transforms array that was passed to {@link
+   * TJTransformer#transform TJTransformer.transform()}.
+   *
+   * @param transform a {@link TJTransform} instance that specifies the
+   * parameters and/or cropping region for this transform
+   */
+  public void customFilter(ShortBuffer coeffBuffer, Rectangle bufferRegion,
+    Rectangle planeRegion, int componentID, int transformID,
+    TJTransform transform)
+    throws Exception;
+}
diff --git a/java/org/libjpegturbo/turbojpeg/TJTransform.java b/java/org/libjpegturbo/turbojpeg/TJTransform.java
index 3f4eb38..b9fbad5 100644
--- a/java/org/libjpegturbo/turbojpeg/TJTransform.java
+++ b/java/org/libjpegturbo/turbojpeg/TJTransform.java
@@ -37,7 +37,6 @@
 
   private static final long serialVersionUID = -127367705761430371L;
 
-
   /**
    * The number of lossless transform operations
    */
@@ -104,21 +103,29 @@
    * partial MCU blocks that cannot be transformed will be left in place, which
    * will create odd-looking strips on the right or bottom edge of the image.
    */
-  final public static int OPT_PERFECT = 1;
+  final public static int OPT_PERFECT  = 1;
   /**
    * This option will discard any partial MCU blocks that cannot be
    * transformed.
    */
-  final public static int OPT_TRIM    = 2;
+  final public static int OPT_TRIM     = 2;
   /**
    * This option will enable lossless cropping.
    */
-  final public static int OPT_CROP    = 4;
+  final public static int OPT_CROP     = 4;
   /**
    * This option will discard the color data in the input image and produce
    * a grayscale output image.
    */
-  final public static int OPT_GRAY    = 8;
+  final public static int OPT_GRAY     = 8;
+  /**
+   * This option will prevent {@link TJTransformer#transform
+   * TJTransformer.transform()} from outputting a JPEG image for this
+   * particular transform.  This can be used in conjunction with a custom
+   * filter to capture the transformed DCT coefficients without transcoding
+   * them.
+   */
+  final public static int OPT_NOOUTPUT = 16;
 
   
   /**
@@ -146,28 +153,36 @@
    *
    * @param options the bitwise OR of one or more of the transform options
    * (<code>OPT_*</code>)
+   *
+   * @param cf an instance of an object that implements the {@link
+   * TJCustomFilter} interface, or null if no custom filter is needed
    */
-  public TJTransform(int x, int y, int w, int h, int op, int options)
-    throws Exception {
+  public TJTransform(int x, int y, int w, int h, int op, int options,
+    TJCustomFilter cf) throws Exception {
     super(x, y, w, h);
-    this.op = op;  this.options = options;
+    this.op = op;  this.options = options;  this.cf = cf;
   }
 
   /**
    * Create a new lossless transform instance with the given parameters.
    *
    * @param r a <code>Rectangle</code> instance which specifies the cropping
-   * region.  See {@link #TJTransform(int, int, int, int, int, int)} for more
+   * region.  See {@link
+   * #TJTransform(int, int, int, int, int, int, TJCustomFilter)} for more
    * detail.
    *
    * @param op one of the transform operations (<code>OP_*</code>)
    *
    * @param options the bitwise OR of one or more of the transform options
    * (<code>OPT_*</code>)
+   *
+   * @param cf an instance of an object that implements the {@link
+   * TJCustomFilter} interface, or null if no custom filter is needed
    */
-  public TJTransform(Rectangle r, int op, int options) throws Exception {
+  public TJTransform(Rectangle r, int op, int options,
+    TJCustomFilter cf) throws Exception {
     super(r);
-    this.op = op;  this.options = options;
+    this.op = op;  this.options = options;  this.cf = cf;
   }
 
   /**
@@ -179,4 +194,9 @@
    * Transform options (bitwise OR of one or more of <code>OPT_*</code>)
    */
   public int options = 0;
+
+  /**
+   * Custom filter instance
+   */
+  public TJCustomFilter cf = null;
 }
diff --git a/tjbench.c b/tjbench.c
index 081f708..27fc856 100644
--- a/tjbench.c
+++ b/tjbench.c
@@ -59,7 +59,7 @@
 const char *subName[NUMSUBOPT]={"444", "422", "420", "GRAY", "440"};
 tjscalingfactor *scalingfactors=NULL, sf={1, 1};  int nsf=0;
 int xformop=TJXOP_NONE, xformopt=0;
-int (*customFilter)(short *, tjregion, tjregion, int, int);
+int (*customFilter)(short *, tjregion, tjregion, int, int, tjtransform *);
 double benchtime=5.0;
 
 
@@ -76,7 +76,7 @@
 
 /* Custom DCT filter which produces a negative of the image */
 int dummyDCTFilter(short *coeffs, tjregion arrayRegion, tjregion planeRegion,
-	int componentIndex, int transformIndex)
+	int componentIndex, int transformIndex, tjtransform *transform)
 {
 	int i;
 	for(i=0; i<arrayRegion.w*arrayRegion.h; i++) coeffs[i]=-coeffs[i];
diff --git a/turbojpeg-jni.c b/turbojpeg-jni.c
index 75123b5..570da68 100644
--- a/turbojpeg-jni.c
+++ b/turbojpeg-jni.c
@@ -487,6 +487,70 @@
 	return;
 }
 
+typedef struct _JNICustomFilterParams
+{
+	JNIEnv *env;
+	jobject tobj;
+	jobject cfobj;
+} JNICustomFilterParams;
+
+static int JNICustomFilter(short *coeffs, tjregion arrayRegion,
+	tjregion planeRegion, int componentIndex, int transformIndex,
+	tjtransform *transform)
+{
+	JNICustomFilterParams *params=(JNICustomFilterParams *)transform->data;
+	JNIEnv *env=params->env;
+	jobject tobj=params->tobj, cfobj=params->cfobj;
+  jobject arrayRegionObj, planeRegionObj, bufobj, borobj;
+	jclass cls;  jmethodID mid;  jfieldID fid;
+
+	bailif0(bufobj=(*env)->NewDirectByteBuffer(env, coeffs,
+		sizeof(short)*arrayRegion.w*arrayRegion.h));
+	bailif0(cls=(*env)->FindClass(env, "java/nio/ByteOrder"));
+  bailif0(mid=(*env)->GetStaticMethodID(env, cls, "nativeOrder",
+		"()Ljava/nio/ByteOrder;"));
+	bailif0(borobj=(*env)->CallStaticObjectMethod(env, cls, mid));
+	bailif0(cls=(*env)->GetObjectClass(env, bufobj));
+	bailif0(mid=(*env)->GetMethodID(env, cls, "order",
+		"(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"));
+	(*env)->CallObjectMethod(env, bufobj, mid, borobj);
+  bailif0(mid=(*env)->GetMethodID(env, cls, "asShortBuffer",
+		"()Ljava/nio/ShortBuffer;"));
+	bailif0(bufobj=(*env)->CallObjectMethod(env, bufobj, mid));
+
+	bailif0(cls=(*env)->FindClass(env, "java/awt/Rectangle"));
+	bailif0(arrayRegionObj=(*env)->AllocObject(env, cls));
+	bailif0(fid=(*env)->GetFieldID(env, cls, "x", "I"));
+	(*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.x);
+	bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I"));
+	(*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.y);
+	bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I"));
+	(*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.w);
+	bailif0(fid=(*env)->GetFieldID(env, cls, "height", "I"));
+	(*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.h);
+
+	bailif0(planeRegionObj=(*env)->AllocObject(env, cls));
+	bailif0(fid=(*env)->GetFieldID(env, cls, "x", "I"));
+	(*env)->SetIntField(env, planeRegionObj, fid, planeRegion.x);
+	bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I"));
+	(*env)->SetIntField(env, planeRegionObj, fid, planeRegion.y);
+	bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I"));
+	(*env)->SetIntField(env, planeRegionObj, fid, planeRegion.w);
+	bailif0(fid=(*env)->GetFieldID(env, cls, "height", "I"));
+	(*env)->SetIntField(env, planeRegionObj, fid, planeRegion.h);
+
+	bailif0(cls=(*env)->GetObjectClass(env, cfobj));
+	bailif0(mid=(*env)->GetMethodID(env, cls, "customFilter",
+		"(Ljava/nio/ShortBuffer;Ljava/awt/Rectangle;Ljava/awt/Rectangle;IILorg/libjpegturbo/turbojpeg/TJTransform;)V"));
+	(*env)->CallVoidMethod(env, cfobj, mid, bufobj, arrayRegionObj,
+		planeRegionObj, componentIndex, transformIndex, tobj);
+
+	return 0;
+
+	bailout:
+	return -1;
+}
+
 JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transform
 	(JNIEnv *env, jobject obj, jbyteArray jsrcBuf, jint jpegSize,
 		jobjectArray dstobjs, jobjectArray tobjs, jint flags)
@@ -497,6 +561,7 @@
 	jbyteArray *jdstBufs=NULL;
 	int jpegWidth=0, jpegHeight=0, jpegSubsamp;
 	jintArray jdstSizes=0;  jint *dstSizesi=NULL;
+	JNICustomFilterParams *params=NULL;
 
 	gethandle();
 
@@ -521,15 +586,19 @@
 		_throw("Memory allocation failure");
 	if((t=(tjtransform *)malloc(sizeof(tjtransform)*n))==NULL)
 		_throw("Memory allocation failure");
+	if((params=(JNICustomFilterParams *)malloc(sizeof(JNICustomFilterParams)*n))
+		==NULL)
+		_throw("Memory allocation failure");
 	for(i=0; i<n; i++)
 	{
 		dstBufs[i]=NULL;  jdstBufs[i]=NULL;  dstSizes[i]=0;
 		memset(&t[i], 0, sizeof(tjtransform));
+		memset(&params[i], 0, sizeof(JNICustomFilterParams));
 	}
 
 	for(i=0; i<n; i++)
 	{
-		jobject tobj;
+		jobject tobj, cfobj;
 
 		bailif0(tobj=(*env)->GetObjectArrayElement(env, tobjs, i));
 		bailif0(_cls=(*env)->GetObjectClass(env, tobj));
@@ -545,6 +614,15 @@
 		t[i].r.w=(*env)->GetIntField(env, tobj, _fid);
 		bailif0(_fid=(*env)->GetFieldID(env, _cls, "height", "I"));
 		t[i].r.h=(*env)->GetIntField(env, tobj, _fid);
+
+		t[i].customFilter=JNICustomFilter;
+		bailif0(_fid=(*env)->GetFieldID(env, _cls, "cf",
+			"Lorg/libjpegturbo/turbojpeg/TJCustomFilter;"));
+		bailif0(cfobj=(*env)->GetObjectField(env, tobj, _fid));
+		params[i].env=env;
+		params[i].tobj=tobj;
+		params[i].cfobj=cfobj;
+		t[i].data=(void *)&params[i];
 	}
 
 	bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0));
diff --git a/turbojpeg.c b/turbojpeg.c
index 60d6ee9..9fc60ce 100644
--- a/turbojpeg.c
+++ b/turbojpeg.c
@@ -1069,7 +1069,7 @@
 					for(y=0; y<compptr->v_samp_factor; y++)
 					{
 						if(t[i].customFilter(barray[y][0], arrayRegion, planeRegion,
-							ci, i)==-1)
+							ci, i, &t[i])==-1)
 							_throw("tjTransform(): Error in custom filter");
 						arrayRegion.y+=DCTSIZE;
 					}
diff --git a/turbojpeg.h b/turbojpeg.h
index f0c542c..70dcfc9 100644
--- a/turbojpeg.h
+++ b/turbojpeg.h
@@ -369,7 +369,7 @@
 /**
  * Lossless transform
  */
-typedef struct
+typedef struct tjtransform
 {
   /**
    * Cropping region
@@ -384,33 +384,43 @@
    */
   int options;
   /**
+   * Arbitrary data that can be accessed within the body of the callback
+   * function
+   */
+  void *data;
+  /**
    * A callback function that can be used to modify the DCT coefficients
    * after they are losslessly transformed but before they are transcoded to a
    * new JPEG file.  This allows for custom filters or other transformations to
    * be applied in the frequency domain.
    *
-   * @param coeffs pointer to an array of DCT coefficients.  (NOTE: this
-   *        pointer is not guaranteed to be valid once the callback returns, so
-   *        applications wishing to hand off the DCT coefficients to another
-   *        function or library should make a copy of them within the body of
-   *        the callback.)
-   * @param arrayRegion region structure containing the width and height of the
-   *        DCT coefficient array as well as its offset relative to the
-   *        component plane.  TurboJPEG implementations may choose to split
-   *        each component plane into multiple DCT coefficient arrays and call
-   *        the callback function once for each array.
-   * @param planeRegion region structure containing the width and height of the
-   *        component plane to which this DCT coefficient array belongs
-   * @param componentIndex the component plane to which this DCT coefficient
-   *        array belongs (Y, Cb, and Cr are, respectively, 0, 1, and 2 in
-   *        typical JPEG images.)
-   * @param transformIndex the transformed image to which this DCT coefficient
-   *        array belongs
+   * @param coeffs pointer to an array of transformed DCT coefficients.  (NOTE:
+   *        this pointer is not guaranteed to be valid once the callback
+   *        returns, so applications wishing to hand off the DCT coefficients
+   *        to another function or library should make a copy of them within
+   *        the body of the callback.)
+   * @param arrayRegion #tjregion structure containing the width and height of
+   *        <tt>coeffs</tt> as well as its offset relative to the component
+   *        plane.  TurboJPEG implementations may choose to split each
+   *        component plane into multiple DCT coefficient arrays and call the
+   *        callback function once for each array.
+   * @param planeRegion #tjregion structure containing the width and height of
+   *        the component plane to which <tt>coeffs</tt> belongs
+   * @param componentID ID number of the component plane to which
+   *        <tt>coeffs</tt> belongs (Y, Cb, and Cr have, respectively, ID's of
+   *        0, 1, and 2 in typical JPEG images.)
+   * @param transformID ID number of the transformed image to which
+   *        <tt>coeffs</tt> belongs.  This is the same as the index of the
+   *        transform in the transforms array that was passed to
+   *        #tjTransform().
+   * @param transform a pointer to a #tjtransform structure that specifies the
+   *        parameters and/or cropping region for this transform
    *
    * @return 0 if the callback was successful, or -1 if an error occurred.
    */
   int (*customFilter)(short *coeffs, tjregion arrayRegion,
-    tjregion planeRegion, int componentIndex, int transformIndex);
+    tjregion planeRegion, int componentIndex, int transformIndex,
+    struct tjtransform *transform);
 } tjtransform;
 
 /**