Doc: "MCU block" = "iMCU" or "MCU"
The JPEG-1 spec never uses the term "MCU block". That term is rarely
used in other literature to describe the equivalent of an MCU in an
interleaved JPEG image, but the libjpeg documentation uses "iMCU" to
describe the same thing. "iMCU" is a better term, since the equivalent
of an interleaved MCU can contain multiple DCT blocks (or samples in
lossless mode) that are only grouped together if the image is
interleaved.
In the case of restart markers, "MCU block" was used in the libjpeg
documentation instead of "MCU", but "MCU" is more accurate and less
confusing. (The restart interval is literally in MCUs, where one MCU
is one data unit in a non-interleaved JPEG image and multiple data units
in a multi-component interleaved JPEG image.)
In the case of 9b704f96b2, the issue was
actually with progressive JPEG images exactly two DCT blocks wide, not
two MCU blocks wide.
This commit also defines "MCU" and "MCU row" in the description of the
various restart marker options/parameters. Although an MCU row is
technically always a row of samples in lossless mode, "sample row" was
confusing, since it is used in other places to describe a row of samples
for a single component (whereas an MCU row in a typical lossless JPEG
image consists of a row of interleaved samples for all components.)
This commit is contained in:
@@ -417,15 +417,14 @@ extends java.lang.Object</pre>
|
||||
<td class="colFirst"><code>static int</code></td>
|
||||
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#PARAM_RESTARTBLOCKS">PARAM_RESTARTBLOCKS</a></span></code></th>
|
||||
<td class="colLast">
|
||||
<div class="block">JPEG restart marker interval in MCU blocks [lossy compression only]</div>
|
||||
<div class="block">JPEG restart marker interval in MCUs [lossy compression only]</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="altColor">
|
||||
<td class="colFirst"><code>static int</code></td>
|
||||
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#PARAM_RESTARTROWS">PARAM_RESTARTROWS</a></span></code></th>
|
||||
<td class="colLast">
|
||||
<div class="block">JPEG restart marker interval in MCU rows (lossy) or sample rows (lossless)
|
||||
[compression only]</div>
|
||||
<div class="block">JPEG restart marker interval in MCU rows [compression only]</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="rowColor">
|
||||
@@ -687,16 +686,14 @@ extends java.lang.Object</pre>
|
||||
<td class="colFirst"><code>static int</code></td>
|
||||
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#getMCUHeight(int)">getMCUHeight</a></span>​(int subsamp)</code></th>
|
||||
<td class="colLast">
|
||||
<div class="block">Returns the MCU block height for the given level of chrominance
|
||||
subsampling.</div>
|
||||
<div class="block">Returns the iMCU height for the given level of chrominance subsampling.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="i6" class="altColor">
|
||||
<td class="colFirst"><code>static int</code></td>
|
||||
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#getMCUWidth(int)">getMCUWidth</a></span>​(int subsamp)</code></th>
|
||||
<td class="colLast">
|
||||
<div class="block">Returns the MCU block width for the given level of chrominance
|
||||
subsampling.</div>
|
||||
<div class="block">Returns the iMCU width for the given level of chrominance subsampling.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="i7" class="rowColor">
|
||||
@@ -1590,8 +1587,8 @@ extends java.lang.Object</pre>
|
||||
and refined with subsequent higher-quality scans containing
|
||||
higher-frequency DCT coefficients. When using Huffman entropy coding, the
|
||||
progressive JPEG format also provides an "end-of-bands (EOB) run" feature
|
||||
that allows large groups of zeroes, potentially spanning multiple MCU
|
||||
blocks, to be represented using only a few bytes.
|
||||
that allows large groups of zeroes, potentially spanning multiple MCUs, to
|
||||
be represented using only a few bytes.
|
||||
|
||||
<p><b>Value</b>
|
||||
<ul>
|
||||
@@ -1803,7 +1800,7 @@ extends java.lang.Object</pre>
|
||||
<li class="blockList">
|
||||
<h4>PARAM_RESTARTBLOCKS</h4>
|
||||
<pre>public static final int PARAM_RESTARTBLOCKS</pre>
|
||||
<div class="block">JPEG restart marker interval in MCU blocks [lossy compression only]
|
||||
<div class="block">JPEG restart marker interval in MCUs [lossy compression only]
|
||||
|
||||
<p>The nature of entropy coding is such that a corrupt JPEG image cannot
|
||||
be decompressed beyond the point of corruption unless it contains restart
|
||||
@@ -1813,9 +1810,18 @@ extends java.lang.Object</pre>
|
||||
tolerance of the JPEG image, but adding too many restart markers can
|
||||
adversely affect the compression ratio and performance.
|
||||
|
||||
<p>In typical JPEG images, an MCU (Minimum Coded Unit) is the minimum set
|
||||
of interleaved "data units" (8x8 DCT blocks if the image is lossy or
|
||||
samples if the image is lossless) necessary to represent at least one data
|
||||
unit per component. (For example, an MCU in an interleaved lossy JPEG
|
||||
image that uses 4:2:2 subsampling consists of two luminance blocks
|
||||
followed by one block for each chrominance component.) In
|
||||
single-component or non-interleaved JPEG images, an MCU is the same as a
|
||||
data unit.
|
||||
|
||||
<p><b>Value</b>
|
||||
<ul>
|
||||
<li> the number of MCU blocks between each restart marker <i>[default:
|
||||
<li> the number of MCUs between each restart marker <i>[default:
|
||||
<code>0</code> (no restart markers)]</i>
|
||||
</ul>
|
||||
|
||||
@@ -1834,15 +1840,16 @@ extends java.lang.Object</pre>
|
||||
<li class="blockList">
|
||||
<h4>PARAM_RESTARTROWS</h4>
|
||||
<pre>public static final int PARAM_RESTARTROWS</pre>
|
||||
<div class="block">JPEG restart marker interval in MCU rows (lossy) or sample rows (lossless)
|
||||
[compression only]
|
||||
<div class="block">JPEG restart marker interval in MCU rows [compression only]
|
||||
|
||||
<p>See <a href="#PARAM_RESTARTBLOCKS"><code>PARAM_RESTARTBLOCKS</code></a> for a description of restart markers.
|
||||
<p>See <a href="#PARAM_RESTARTBLOCKS"><code>PARAM_RESTARTBLOCKS</code></a> for a description of restart markers
|
||||
and MCUs. An MCU row is a row of MCUs spanning the entire width of the
|
||||
image.
|
||||
|
||||
<p><b>Value</b>
|
||||
<ul>
|
||||
<li> the number of MCU rows or sample rows between each restart marker
|
||||
<i>[default: <code>0</code> (no restart markers)]</i>
|
||||
<li> the number of MCU rows between each restart marker <i>[default:
|
||||
<code>0</code> (no restart markers)]</i>
|
||||
</ul>
|
||||
|
||||
<p>Setting this parameter to a non-zero value sets
|
||||
@@ -2186,15 +2193,25 @@ public static final int FLAG_LIMITSCANS</pre>
|
||||
<li class="blockList">
|
||||
<h4>getMCUWidth</h4>
|
||||
<pre class="methodSignature">public static int getMCUWidth​(int subsamp)</pre>
|
||||
<div class="block">Returns the MCU block width for the given level of chrominance
|
||||
subsampling.</div>
|
||||
<div class="block">Returns the iMCU width for the given level of chrominance subsampling.
|
||||
|
||||
<p>In a typical lossy JPEG image, 8x8 blocks of DCT coefficients for each
|
||||
component are interleaved in a single scan. If the image uses chrominance
|
||||
subsampling, then multiple luminance blocks are stored together, followed
|
||||
by a single block for each chrominance component. The combination of the
|
||||
full-resolution luminance block(s) and the (possibly subsampled)
|
||||
chrominance blocks corresponding to the same pixels is called a "Minimum
|
||||
Coded Unit" (MCU.) In a non-interleaved lossy JPEG image, each component
|
||||
is stored in a separate scan, and an MCU is a single DCT block, so we use
|
||||
the term "iMCU" (interleaved MCU) to refer to the equivalent of an MCU in
|
||||
an interleaved JPEG image. For the common case of interleaved JPEG
|
||||
images, an iMCU is the same as an MCU.</div>
|
||||
<dl>
|
||||
<dt><span class="paramLabel">Parameters:</span></dt>
|
||||
<dd><code>subsamp</code> - the level of chrominance subsampling (one of
|
||||
<a href="#SAMP_444"><code>SAMP_*</code></a>)</dd>
|
||||
<dt><span class="returnLabel">Returns:</span></dt>
|
||||
<dd>the MCU block width for the given level of chrominance
|
||||
subsampling.</dd>
|
||||
<dd>the iMCU width for the given level of chrominance subsampling.</dd>
|
||||
</dl>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -2205,15 +2222,25 @@ public static final int FLAG_LIMITSCANS</pre>
|
||||
<li class="blockList">
|
||||
<h4>getMCUHeight</h4>
|
||||
<pre class="methodSignature">public static int getMCUHeight​(int subsamp)</pre>
|
||||
<div class="block">Returns the MCU block height for the given level of chrominance
|
||||
subsampling.</div>
|
||||
<div class="block">Returns the iMCU height for the given level of chrominance subsampling.
|
||||
|
||||
<p>In a typical lossy JPEG image, 8x8 blocks of DCT coefficients for each
|
||||
component are interleaved in a single scan. If the image uses chrominance
|
||||
subsampling, then multiple luminance blocks are stored together, followed
|
||||
by a single block for each chrominance component. The combination of the
|
||||
full-resolution luminance block(s) and the (possibly subsampled)
|
||||
chrominance blocks corresponding to the same pixels is called a "Minimum
|
||||
Coded Unit" (MCU.) In a non-interleaved lossy JPEG image, each component
|
||||
is stored in a separate scan, and an MCU is a single DCT block, so we use
|
||||
the term "iMCU" (interleaved MCU) to refer to the equivalent of an MCU in
|
||||
an interleaved JPEG image. For the common case of interleaved JPEG
|
||||
images, an iMCU is the same as an MCU.</div>
|
||||
<dl>
|
||||
<dt><span class="paramLabel">Parameters:</span></dt>
|
||||
<dd><code>subsamp</code> - the level of chrominance subsampling (one of
|
||||
<a href="#SAMP_444"><code>SAMP_*</code></a>)</dd>
|
||||
<dt><span class="returnLabel">Returns:</span></dt>
|
||||
<dd>the MCU block height for the given level of chrominance
|
||||
subsampling.</dd>
|
||||
<dd>the iMCU height for the given level of chrominance subsampling.</dd>
|
||||
</dl>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -838,8 +838,8 @@ implements java.io.Closeable</pre>
|
||||
with the JPEG image width and height (see <a href="#getWidth()"><code>getWidth()</code></a> and
|
||||
<a href="#getHeight()"><code>getHeight()</code></a>.) When decompressing into a planar YUV image, an
|
||||
intermediate buffer copy will be performed if the width or height of the
|
||||
scaled destination image is not an even multiple of the MCU block size
|
||||
(see <a href="TJ.html#getMCUWidth(int)"><code>TJ.getMCUWidth()</code></a> and <a href="TJ.html#getMCUHeight(int)"><code>TJ.getMCUHeight()</code></a>.) Note that decompression scaling is not available
|
||||
scaled destination image is not an even multiple of the iMCU size (see
|
||||
<a href="TJ.html#getMCUWidth(int)"><code>TJ.getMCUWidth()</code></a> and <a href="TJ.html#getMCUHeight(int)"><code>TJ.getMCUHeight()</code></a>.) Note that decompression scaling is not available
|
||||
(and the specified scaling factor is ignored) when decompressing lossless
|
||||
JPEG images (see <a href="TJ.html#PARAM_LOSSLESS"><code>TJ.PARAM_LOSSLESS</code></a>), since the IDCT algorithm is
|
||||
not used with those images. Note also that <a href="TJ.html#PARAM_FASTDCT"><code>TJ.PARAM_FASTDCT</code></a> is
|
||||
@@ -862,10 +862,10 @@ implements java.io.Closeable</pre>
|
||||
<dd><code>croppingRegion</code> - <code>java.awt.Rectangle</code> instance that
|
||||
specifies a subregion of the JPEG image to decompress, or
|
||||
<a href="TJ.html#UNCROPPED"><code>TJ.UNCROPPED</code></a> for no cropping. The left boundary of the cropping
|
||||
region must be evenly divisible by the scaled MCU block width, which can
|
||||
be determined by calling <a href="TJScalingFactor.html#getScaled(int)"><code>TJScalingFactor.getScaled()</code></a> with the specified scaling factor (see
|
||||
<a href="#setScalingFactor(org.libjpegturbo.turbojpeg.TJScalingFactor)"><code>setScalingFactor()</code></a>) and the MCU block width
|
||||
(see <a href="TJ.html#getMCUWidth(int)"><code>TJ.getMCUWidth()</code></a>) for the level of chrominance
|
||||
region must be evenly divisible by the scaled iMCU width, which can be
|
||||
determined by calling <a href="TJScalingFactor.html#getScaled(int)"><code>TJScalingFactor.getScaled()</code></a> with the specified scaling factor (see
|
||||
<a href="#setScalingFactor(org.libjpegturbo.turbojpeg.TJScalingFactor)"><code>setScalingFactor()</code></a>) and the iMCU width (see
|
||||
<a href="TJ.html#getMCUWidth(int)"><code>TJ.getMCUWidth()</code></a>) for the level of chrominance
|
||||
subsampling in the JPEG image (see <a href="TJ.html#PARAM_SUBSAMP"><code>TJ.PARAM_SUBSAMP</code></a>.) The
|
||||
cropping region should be specified relative to the scaled image
|
||||
dimensions. Unless <code>croppingRegion</code> is <a href="TJ.html#UNCROPPED"><code>TJ.UNCROPPED</code></a>,
|
||||
|
||||
@@ -329,7 +329,7 @@ extends java.awt.Rectangle</pre>
|
||||
<td class="colFirst"><code>static int</code></td>
|
||||
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#OPT_TRIM">OPT_TRIM</a></span></code></th>
|
||||
<td class="colLast">
|
||||
<div class="block">Discard any partial MCU blocks that cannot be transformed.</div>
|
||||
<div class="block">Discard any partial iMCUs that cannot be transformed.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="altColor">
|
||||
@@ -496,7 +496,7 @@ extends java.awt.Rectangle</pre>
|
||||
<h4>OP_HFLIP</h4>
|
||||
<pre>public static final int OP_HFLIP</pre>
|
||||
<div class="block">Flip (mirror) image horizontally. This transform is imperfect if there
|
||||
are any partial MCU blocks on the right edge.</div>
|
||||
are any partial iMCUs on the right edge.</div>
|
||||
<dl>
|
||||
<dt><span class="seeLabel">See Also:</span></dt>
|
||||
<dd><a href="#OPT_PERFECT"><code>OPT_PERFECT</code></a>,
|
||||
@@ -512,7 +512,7 @@ extends java.awt.Rectangle</pre>
|
||||
<h4>OP_VFLIP</h4>
|
||||
<pre>public static final int OP_VFLIP</pre>
|
||||
<div class="block">Flip (mirror) image vertically. This transform is imperfect if there are
|
||||
any partial MCU blocks on the bottom edge.</div>
|
||||
any partial iMCUs on the bottom edge.</div>
|
||||
<dl>
|
||||
<dt><span class="seeLabel">See Also:</span></dt>
|
||||
<dd><a href="#OPT_PERFECT"><code>OPT_PERFECT</code></a>,
|
||||
@@ -544,8 +544,8 @@ extends java.awt.Rectangle</pre>
|
||||
<h4>OP_TRANSVERSE</h4>
|
||||
<pre>public static final int OP_TRANSVERSE</pre>
|
||||
<div class="block">Transverse transpose image (flip/mirror along upper right to lower left
|
||||
axis). This transform is imperfect if there are any partial MCU blocks in
|
||||
the image.</div>
|
||||
axis). This transform is imperfect if there are any partial iMCUs in the
|
||||
image.</div>
|
||||
<dl>
|
||||
<dt><span class="seeLabel">See Also:</span></dt>
|
||||
<dd><a href="#OPT_PERFECT"><code>OPT_PERFECT</code></a>,
|
||||
@@ -561,7 +561,7 @@ extends java.awt.Rectangle</pre>
|
||||
<h4>OP_ROT90</h4>
|
||||
<pre>public static final int OP_ROT90</pre>
|
||||
<div class="block">Rotate image clockwise by 90 degrees. This transform is imperfect if
|
||||
there are any partial MCU blocks on the bottom edge.</div>
|
||||
there are any partial iMCUs on the bottom edge.</div>
|
||||
<dl>
|
||||
<dt><span class="seeLabel">See Also:</span></dt>
|
||||
<dd><a href="#OPT_PERFECT"><code>OPT_PERFECT</code></a>,
|
||||
@@ -577,7 +577,7 @@ extends java.awt.Rectangle</pre>
|
||||
<h4>OP_ROT180</h4>
|
||||
<pre>public static final int OP_ROT180</pre>
|
||||
<div class="block">Rotate image 180 degrees. This transform is imperfect if there are any
|
||||
partial MCU blocks in the image.</div>
|
||||
partial iMCUs in the image.</div>
|
||||
<dl>
|
||||
<dt><span class="seeLabel">See Also:</span></dt>
|
||||
<dd><a href="#OPT_PERFECT"><code>OPT_PERFECT</code></a>,
|
||||
@@ -593,7 +593,7 @@ extends java.awt.Rectangle</pre>
|
||||
<h4>OP_ROT270</h4>
|
||||
<pre>public static final int OP_ROT270</pre>
|
||||
<div class="block">Rotate image counter-clockwise by 90 degrees. This transform is imperfect
|
||||
if there are any partial MCU blocks on the right edge.</div>
|
||||
if there are any partial iMCUs on the right edge.</div>
|
||||
<dl>
|
||||
<dt><span class="seeLabel">See Also:</span></dt>
|
||||
<dd><a href="#OPT_PERFECT"><code>OPT_PERFECT</code></a>,
|
||||
@@ -609,15 +609,15 @@ extends java.awt.Rectangle</pre>
|
||||
<h4>OPT_PERFECT</h4>
|
||||
<pre>public static final int OPT_PERFECT</pre>
|
||||
<div class="block">This option causes <a href="TJTransformer.html#transform(byte%5B%5D%5B%5D,org.libjpegturbo.turbojpeg.TJTransform%5B%5D)"><code>TJTransformer.transform()</code></a> to throw an exception if the transform is not
|
||||
perfect. Lossless transforms operate on MCU blocks, the size of which
|
||||
depends on the level of chrominance subsampling used. If the image's
|
||||
width or height is not evenly divisible by the MCU block size (see
|
||||
<a href="TJ.html#getMCUWidth(int)"><code>TJ.getMCUWidth()</code></a> and <a href="TJ.html#getMCUHeight(int)"><code>TJ.getMCUHeight()</code></a>), then there will be partial MCU blocks on the right
|
||||
and/or bottom edges. It is not possible to move these partial MCU blocks
|
||||
to the top or left of the image, so any transform that would require that
|
||||
is "imperfect." If this option is not specified, then any 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.</div>
|
||||
perfect. Lossless transforms operate on iMCUs, the size of which depends
|
||||
on the level of chrominance subsampling used. If the image's width or
|
||||
height is not evenly divisible by the iMCU size (see <a href="TJ.html#getMCUWidth(int)"><code>TJ.getMCUWidth()</code></a> and <a href="TJ.html#getMCUHeight(int)"><code>TJ.getMCUHeight()</code></a>), then
|
||||
there will be partial iMCUs on the right and/or bottom edges. It is not
|
||||
possible to move these partial iMCUs to the top or left of the image, so
|
||||
any transform that would require that is "imperfect." If this option is
|
||||
not specified, then any partial iMCUs that cannot be transformed will be
|
||||
left in place, which will create odd-looking strips on the right or bottom
|
||||
edge of the image.</div>
|
||||
<dl>
|
||||
<dt><span class="seeLabel">See Also:</span></dt>
|
||||
<dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OPT_PERFECT">Constant Field Values</a></dd>
|
||||
@@ -631,7 +631,7 @@ extends java.awt.Rectangle</pre>
|
||||
<li class="blockList">
|
||||
<h4>OPT_TRIM</h4>
|
||||
<pre>public static final int OPT_TRIM</pre>
|
||||
<div class="block">Discard any partial MCU blocks that cannot be transformed.</div>
|
||||
<div class="block">Discard any partial iMCUs that cannot be transformed.</div>
|
||||
<dl>
|
||||
<dt><span class="seeLabel">See Also:</span></dt>
|
||||
<dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OPT_TRIM">Constant Field Values</a></dd>
|
||||
@@ -818,9 +818,9 @@ extends java.awt.Rectangle</pre>
|
||||
<dl>
|
||||
<dt><span class="paramLabel">Parameters:</span></dt>
|
||||
<dd><code>x</code> - the left boundary of the cropping region. This must be evenly
|
||||
divisible by the MCU block width (see <a href="TJ.html#getMCUWidth(int)"><code>TJ.getMCUWidth()</code></a>)</dd>
|
||||
divisible by the iMCU width (see <a href="TJ.html#getMCUWidth(int)"><code>TJ.getMCUWidth()</code></a>)</dd>
|
||||
<dd><code>y</code> - the upper boundary of the cropping region. This must be evenly
|
||||
divisible by the MCU block height (see <a href="TJ.html#getMCUHeight(int)"><code>TJ.getMCUHeight()</code></a>)</dd>
|
||||
divisible by the iMCU height (see <a href="TJ.html#getMCUHeight(int)"><code>TJ.getMCUHeight()</code></a>)</dd>
|
||||
<dd><code>w</code> - the width of the cropping region. Setting this to 0 is the
|
||||
equivalent of setting it to (width of the source JPEG image -
|
||||
<code>x</code>).</dd>
|
||||
|
||||
Reference in New Issue
Block a user