home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / sources / misc / 4203 / architecture.A next >
Encoding:
Text File  |  1992-12-16  |  25.5 KB  |  501 lines

  1.  
  2.     JPEG SYSTEM ARCHITECTURE        1-DEC-92
  3.  
  4.  
  5. This file provides an overview of the "architecture" of the portable JPEG
  6. software; that is, the functions of the various modules in the system and the
  7. interfaces between modules.  For more precise details about any data structure
  8. or calling convention, see the header files.
  9.  
  10. Important note: when I say "module" I don't mean "a C function", which is what
  11. some people seem to think the term means.  A separate C source file is closer
  12. to the mark.  Also, it is frequently the case that several different modules
  13. present a common interface to callers; the term "object" or "method" refers to
  14. this common interface (see "Poor man's object-oriented programming", below).
  15.  
  16. JPEG-specific terminology follows the JPEG standard:
  17.   A "component" means a color channel, e.g., Red or Luminance.
  18.   A "sample" is a pixel component value (i.e., one number in the image data).
  19.   A "coefficient" is a frequency coefficient (a DCT transform output number).
  20.   The term "block" refers to an 8x8 group of samples or coefficients.
  21.   "MCU" (minimum coded unit) is the same as "MDU" of the R8 draft; i.e., an
  22.     interleaved set of blocks of size determined by the sampling factors,
  23.     or a single block in a noninterleaved scan.
  24.  
  25.  
  26. *** System requirements ***
  27.  
  28. We must support compression and decompression of both Huffman and
  29. arithmetic-coded JPEG files.  Any set of compression parameters allowed by the
  30. JPEG spec should be readable for decompression.  (We can be more restrictive
  31. about what formats we can generate.)  (Note: for legal reasons no arithmetic
  32. coding implementation is currently included in the publicly available sources.
  33. However, the architecture still supports it.)
  34.  
  35. We need to be able to handle both raw JPEG files (more specifically, the JFIF
  36. format) and JPEG-in-TIFF (C-cubed's format, and perhaps Kodak's).  Even if we
  37. don't implement TIFF ourselves, other people will want to use our code for
  38. that.  This means that generation and scanning of the file header has to be
  39. separated out.
  40.  
  41. Perhaps we should be prepared to support the JPEG lossless mode (also referred
  42. to in the spec as spatial DPCM coding).  A lot of people seem to believe they
  43. need this... whether they really do is debatable, but the customer is always
  44. right.  On the other hand, there will not be much sharable code between the
  45. lossless and lossy modes!  At best, a lossless program could be derived from
  46. parts of the lossy version.  For now we will only worry about the lossy mode.
  47.  
  48. I see no real value in supporting the JPEG progressive modes (note that
  49. spectral selection and successive approximation are two different progressive
  50. modes).  These are only of interest when painting the decompressed image in
  51. real-time, which nobody is going to do with a pure software implementation.
  52.  
  53. There is some value in supporting the hierarchical mode, which allows for
  54. successive frames of higher resolution.  This could be of use for including
  55. "thumbnail" representations.  However, this appears to add a lot more
  56. complexity than it is worth.
  57.  
  58. A variety of uncompressed image file formats and user interfaces must be
  59. supported.  These aspects therefore have to be kept separate from the rest of
  60. the system.  A particularly important issue is whether color quantization of
  61. the output is needed (i.e., whether a colormap is used).  We should be able to
  62. support both adaptive quantization (which requires two or more passes over the
  63. image) and nonadaptive (quantization to a prespecified colormap, which can be
  64. done in one pass).
  65.  
  66. Memory usage is an important concern, since we will port this code to 80x86
  67. and other limited-memory machines.  For large intermediate structures, we
  68. should be able to use either virtual memory or temporary files.
  69.  
  70. It should be possible to build programs that handle compression only,
  71. decompression only, or both, without much duplicate or unused code in any
  72. version.  (In particular, a decompression-only version should have no extra
  73. baggage.)
  74.  
  75.  
  76. *** Compression overview ***
  77.  
  78. The *logical* steps needed in (non-lossless) JPEG compression are:
  79.  
  80. 1. Conversion from incoming image format to a standardized internal form
  81.    (either RGB or grayscale).
  82.  
  83. 2. Color space conversion (e.g., RGB to YCbCr).  This is a null step for
  84.    grayscale (unless we support mapping color inputs to grayscale, which
  85.    would most easily be done here).  Gamma adjustment may also be needed here.
  86.  
  87. 3. Downsampling (reduction of number of samples in some color components).
  88.    This step operates independently on each color component.
  89.  
  90. 4. MCU extraction (creation of a single sequence of 8x8 sample blocks).
  91.    This step and the following ones are performed once for each scan
  92.    in the output JPEG file, i.e., once if making an interleaved file and more
  93.    than once for a noninterleaved file.
  94.    Note: both this step and the previous one must deal with edge conditions
  95.    for pictures that aren't a multiple of the MCU dimensions.  Alternately,
  96.    we could expand the picture to a multiple of an MCU before doing these
  97.    two steps.  (The latter seems better and has been adopted below.)
  98.  
  99. 5. DCT transformation of each 8x8 block.
  100.  
  101. 6. Quantization scaling and zigzag reordering of the elements in each 8x8
  102.    block.
  103.  
  104. 7. Huffman or arithmetic encoding of the transformed block sequence.
  105.  
  106. 8. Output of the JPEG file with whatever headers/markers are wanted.
  107.  
  108. Of course, the actual implementation will combine some of these logical steps
  109. for efficiency.  The trick is to keep these logical functions as separate as
  110. possible without losing too much performance.
  111.  
  112. In addition to these logical pipeline steps, we need various modules that
  113. aren't part of the data pipeline.  These are:
  114.  
  115. A. Overall control (sequencing of other steps & management of data passing).
  116.  
  117. B. User interface; this will determine the input and output files, and supply
  118.    values for some compression parameters.  Note that this module is highly
  119.    platform-dependent.
  120.  
  121. C. Compression parameter selection: some parameters should be chosen
  122.    automatically rather than requiring the user to find a good value.
  123.    The prototype only does this for the back-end (Huffman or arithmetic)
  124.    parameters, but further in the future, more might be done.  A
  125.    straightforward approach to selection is to try several values; this
  126.    requires being able to repeatedly apply some portion of the pipeline and
  127.    inspect the results (without actually outputting them).  Probably only
  128.    entropy encoding parameters can reasonably be done this way; optimizing
  129.    earlier steps would require too much data to be reprocessed (not to mention
  130.    the problem of interactions between parameters for different steps).
  131.    What other facilities do we need to support automatic parameter selection?
  132.  
  133. D. A memory management module to deal with small-memory machines.  This must
  134.    create the illusion of virtual memory for certain large data structures
  135.    (e.g., the downsampled image or the transformed coefficients).
  136.    The interface to this must be defined to minimize the overhead incurred,
  137.    especially on virtual-memory machines where the module won't do much.
  138.  
  139. In many cases we can arrange things so that a data stream is produced in
  140. segments by one module and consumed by another without the need to hold it all
  141. in (virtual) memory.  This is obviously not possible for any data that must be
  142. scanned more than once, so it won't work everywhere.
  143.  
  144. The major variable at this level of detail is whether the JPEG file is to be
  145. interleaved or not; that affects the order of processing so fundamentally that
  146. the central control module must know about it.  Some of the other modules may
  147. need to know it too.  It would simplify life if we didn't need to support
  148. noninterleaved images, but that is not reasonable.
  149.  
  150. Many of these steps operate independently on each color component; the
  151. knowledge of how many components there are, and how they are interleaved,
  152. ought to be confined to the central control module.  (Color space conversion
  153. and MCU extraction probably have to know it too.)
  154.  
  155.  
  156. *** Decompression overview ***
  157.  
  158. Decompression is roughly the inverse process from compression, but there are
  159. some additional steps needed to produce a good output image.
  160.  
  161. The *logical* steps needed in (non-lossless) JPEG decompression are:
  162.  
  163. 1. Scanning of the JPEG file, decoding of headers/markers etc.
  164.  
  165. 2. Huffman or arithmetic decoding of the coefficient sequence.
  166.  
  167. 3. Quantization descaling and zigzag reordering of the elements in each 8x8
  168.    block.
  169.  
  170. 4. MCU disassembly (conversion of a possibly interleaved sequence of 8x8
  171.    blocks back to separate components in pixel map order).
  172.  
  173. 5. (Optional)  Cross-block smoothing per JPEG section K.8 or a similar
  174.    algorithm.  (Steps 5-8 operate independently on each component.)
  175.  
  176. 6. Inverse DCT transformation of each 8x8 block.
  177.  
  178. 7. Upsampling.  At this point a pixel image of the original dimensions
  179.    has been recreated.
  180.  
  181. 8. Post-upsampling smoothing.  This can be combined with upsampling,
  182.    by using a convolution-like calculation to generate each output pixel
  183.    directly from one or more input pixels.
  184.  
  185. 9. Cropping to the original pixel dimensions (throwing away duplicated
  186.    pixels at the edges).  It is most convenient to do this now, as the
  187.    preceding steps are simplified by not having to worry about odd picture
  188.    sizes.
  189.  
  190. 10. Color space reconversion (e.g., YCbCr to RGB).  This is a null step for
  191.     grayscale.  (Note that mapping a color JPEG to grayscale output is most
  192.     easily done in this step.)  Gamma adjustment may also be needed here.
  193.  
  194. 11. Color quantization (only if a colormapped output format is requested).
  195.     NOTE: it is probably preferable to perform quantization in the internal
  196.     (JPEG) colorspace rather than the output colorspace.  Doing it that way,
  197.     color conversion need only be applied to the colormap entries, not to
  198.     every pixel; and quantization gets to operate in a non-gamma-corrected
  199.     space.  But the internal space may not be suitable for some algorithms.
  200.     The system design is such that only the color quantizer module knows
  201.     whether color conversion happens before or after quantization.
  202.  
  203. 12. Writing of the desired image format.
  204.  
  205. As before, some of these will be combined into single steps.  When dealing
  206. with a noninterleaved JPEG file, steps 2-9 will be performed once for each
  207. scan; the resulting data will need to be buffered up so that steps 10-12 can
  208. process all the color components together.
  209.  
  210. The same auxiliary modules are needed as before, except for compression
  211. parameter selection.  Note that rerunning a pipeline stage should never be
  212. needed during decompression.  This may allow a simpler control module.  The
  213. user interface might also be simpler since it need not supply any compression
  214. parameters.
  215.  
  216. As before, not all of these steps require the whole image to be stored.
  217. Actually, two-pass color quantization is the only step that logically requires
  218. this; everything else could be done a few raster lines at a time (at least for
  219. interleaved images).  We might want to make color quantization be a separate
  220. program because of this fact.
  221.  
  222. Again, many of the steps should be able to work on one color component in
  223. ignorance of the other components.
  224.  
  225.  
  226. *** Implications of noninterleaved formats ***
  227.  
  228. Much of the work can be done in a single pass if an interleaved JPEG file
  229. format is used.  With a noninterleaved JPEG file, separating or recombining
  230. the components will force use of virtual memory (on a small-memory machine,
  231. we probably would want one temp file per color component).
  232.  
  233. If any of the image formats we read or write are noninterleaved, the opposite
  234. condition might apply: processing a noninterleaved JPEG file would be more
  235. efficient.  Offhand, though, I can't think of any popular image formats that
  236. work that way; besides the win would only come if the same color space were
  237. used in JPEG and non-JPEG files.  It's not worth the complexity to make the
  238. system design accommodate that case efficiently.
  239.  
  240. An argument against interleaving is that it makes the decompressor need more
  241. memory for cross-block smoothing (since the minimum processable chunk of the
  242. image gets bigger).  With images more than 1000 pixels across, 80x86 machines
  243. are likely to have difficulty in handling this feature.
  244.  
  245. Another argument against interleaving is that the noninterleaved format allows
  246. a wider range of sampling factors, since the limit of ten blocks per MCU no
  247. longer applies.  We could get around this by blithely ignoring the spec's
  248. limit of ten blocks, but that seems like a bad idea (especially since it makes
  249. the above problem worse).
  250.  
  251. The upshot is that we need to support both interleaved and noninterleaved JPEG
  252. formats, since for any given machine and picture size one may be much more
  253. efficient than the other.  However, the non-JPEG format we convert to or from
  254. will be assumed to be an interleaved format (i.e., it produces or stores all
  255. the components of a pixel together).
  256.  
  257. I do not think it is necessary for the compressor to be able to output
  258. partially-interleaved formats (multiple scans, some of which interleave a
  259. subset of the components).  However, the decompressor must be able to read
  260. such files to conform to the spec.
  261.  
  262.  
  263. *** Data formats ***
  264.  
  265. Pipeline steps that work on pixel sample values will use the following data
  266. structure:
  267.  
  268.     typedef something JSAMPLE;        a pixel component value, 0..MAXJSAMPLE
  269.     typedef JSAMPLE *JSAMPROW;        ptr to a row of samples
  270.     typedef JSAMPROW *JSAMPARRAY;    ptr to a list of rows
  271.     typedef JSAMPARRAY *JSAMPIMAGE;    ptr to a list of color-component arrays
  272.  
  273. The basic element type JSAMPLE will be one of unsigned char, (signed) char, or
  274. unsigned short.  Unsigned short will be used if samples wider than 8 bits are
  275. to be supported (this is a compile-time option).  Otherwise, unsigned char is
  276. used if possible.  If the compiler only supports signed chars, then it is
  277. necessary to mask off the value when reading.  Thus, all reads of sample
  278. values should be coded as "GETJSAMPLE(value)", where the macro will be defined
  279. as "((value)&0xFF)" on signed-char machines and "(value)" elsewhere.
  280.  
  281. With these conventions, JSAMPLE values can be assumed to be >= 0.  This should
  282. simplify correct rounding during downsampling, etc.  The JPEG draft's
  283. specification that sample values run from -128..127 will be accommodated by
  284. subtracting 128 just as the sample value is copied into the source array for
  285. the DCT step (this will be an array of signed shorts or longs).  Similarly,
  286. during decompression the output of the IDCT step will be immediately shifted
  287. back to 0..255.  (NB: different values are required when 12-bit samples are in
  288. use.  The code should be written in terms of MAXJSAMPLE and CENTERJSAMPLE,
  289. which will be #defined as 255 and 128 respectively in an 8-bit implementation,
  290. and as 4095 and 2048 in a 12-bit implementation.)
  291.  
  292. On compilers that don't support "unsigned short", signed short can be used for
  293. a 12-bit implementation.  To support lossless coding (which allows up to
  294. 16-bit data precision) masking with 0xFFFF in GETJSAMPLE might be necessary.
  295. (But if "int" is 16 bits then using "unsigned int" is the best solution.)
  296.  
  297. Notice that we use a pointer per row, rather than a two-dimensional JSAMPLE
  298. array.  This choice costs only a small amount of memory and has several
  299. benefits:
  300.  
  301. * Code using the data structure doesn't need to know the allocated width of
  302. the rows.  This will simplify edge expansion/compression, since we can work
  303. in an array that's wider than the logical picture width.
  304.  
  305. * The rows forming a component array may be allocated at different times
  306. without extra copying.  This will simplify working a few scanlines at a time,
  307. especially in smoothing steps that need access to the previous and next rows.
  308.  
  309. * Indexing doesn't require multiplication; this is a performance win on many
  310. machines.
  311.  
  312. Note that each color component is stored in a separate array; we don't use the
  313. traditional structure in which the components of a pixel are stored together.
  314. This simplifies coding of steps that work on each component independently,
  315. because they don't need to know how many components there are.  Furthermore,
  316. we can read or write each component to a temp file independently, which is
  317. helpful when dealing with noninterleaved JPEG files.
  318.  
  319. A specific sample value will be accessed by code such as
  320.     GETJSAMPLE(image[colorcomponent][row][col])
  321. where col is measured from the image left edge, but row is measured from the
  322. first sample row currently in memory.  Either of the first two indexings can
  323. be precomputed by copying the relevant pointer.
  324.  
  325.  
  326. Pipeline steps that work on frequency-coefficient values will use the
  327. following data structure:
  328.  
  329.     typedef short JCOEF;        a 16-bit signed integer
  330.     typedef JCOEF JBLOCK[64];        an 8x8 block of coefficients
  331.     typedef JBLOCK *JBLOCKROW;        ptr to one horizontal row of 8x8 blocks
  332.     typedef JBLOCKROW *JBLOCKARRAY;    ptr to a list of such rows
  333.     typedef JBLOCKARRAY *JBLOCKIMAGE;    ptr to a list of color component arrays
  334.  
  335. The underlying type is always a 16-bit signed integer (this is "short" on all
  336. machines of interest, but let's use the typedef name anyway).  These are
  337. grouped into 8x8 blocks (we should use #defines DCTSIZE and DCTSIZE2 rather
  338. than "8" and "64").  The contents of a block may be either in "natural" or
  339. zigzagged order, and may be true values or divided by the quantization
  340. coefficients, depending on where the block is in the pipeline.
  341.  
  342. Notice that the allocation unit is now a row of 8x8 blocks, corresponding to
  343. eight rows of samples.  Otherwise the structure is much the same as for
  344. samples, and for the same reasons.
  345.  
  346. On machines where malloc() can't handle a request bigger than 64Kb, this data
  347. structure limits us to rows of less than 512 JBLOCKs, which would be a picture
  348. width of 4000 pixels.  This seems an acceptable restriction.
  349.  
  350.  
  351. On 80x86 machines, the bottom-level pointer types (JSAMPROW and JBLOCKROW)
  352. must be declared as "far" pointers, but the upper levels can be "near"
  353. (implying that the pointer lists are allocated in the DS segment).
  354. To simplify sharing code, we'll have a #define symbol FAR, which expands to
  355. the "far" keyword when compiling on 80x86 machines and to nothing elsewhere.
  356.  
  357.  
  358. The data arrays used as input and output of the DCT transform subroutine will
  359. be declared using a separate typedef; they could be arrays of "short", "int"
  360. or "long" independently of the above choices.  This would depend on what is
  361. needed to make the compiler generate correct and efficient multiply/add code
  362. in the DCT inner loops.  No significant speed or memory penalty will be paid
  363. to have a different representation than is used in the main image storage
  364. arrays, since some additional value-by-value processing is done at the time of
  365. creation or extraction of the DCT data anyway (e.g., add/subtract 128).
  366.  
  367.  
  368. *** Poor man's object-oriented programming ***
  369.  
  370. It should be pretty clear by now that we have a lot of quasi-independent
  371. steps, many of which have several possible behaviors.  To avoid cluttering the
  372. code with lots of switch statements, we'll use a simple form of object-style
  373. programming to separate out the different possibilities.
  374.  
  375. For example, Huffman and arithmetic coding will be implemented as two separate
  376. modules that present the same external interface; at runtime, the calling code
  377. will access the proper module indirectly through an "object".
  378.  
  379. We can get the limited features we need while staying within portable C.  The
  380. basic tool is a function pointer.  An "object" is just a struct containing one
  381. or more function pointer fields, each of which corresponds to a method name in
  382. real object-oriented languages.  During initialization we fill in the function
  383. pointers with references to whichever module we have determined we need to use
  384. in this run.  Then invocation of the module is done by indirecting through a
  385. function pointer; on most architectures this is no more expensive (and
  386. possibly cheaper) than a switch, which would be the only other way of making
  387. the required run-time choice.  The really significant benefit, of course, is
  388. keeping the source code clean and well structured.
  389.  
  390. For example, the interface for entropy decoding (Huffman or arithmetic
  391. decoding) might look like this:
  392.  
  393.     struct function_ptr_struct {
  394.         ...
  395.         /* Entropy decoding methods */
  396.         void (*prepare_for_scan) ();
  397.         void (*get_next_mcu) ();
  398.         ...
  399.         };
  400.  
  401.     typedef struct function_ptr_struct * function_ptrs;
  402.  
  403. The struct pointer is what will actually be passed around.  A call site might
  404. look like this:
  405.  
  406.     some_function (function_ptrs fptrs)
  407.         {
  408.         ...
  409.         (*fptrs->get_next_mcu) (...);
  410.         ...
  411.         }
  412.  
  413. (It might be worth inventing some specialized macros to hide the rather ugly
  414. syntax for method definition and call.)  Note that the caller doesn't know how
  415. many different get_next_mcu procedures there are, what their real names are,
  416. nor how to choose which one to call.
  417.  
  418. An important benefit of this scheme is that it is easy to provide multiple
  419. versions of any method, each tuned to a particular case.  While a lot of
  420. precalculation might be done to select an optimal implementation of a method,
  421. the cost per invocation is constant.  For example, the MCU extraction step
  422. might have a "generic" method, plus one or more "hardwired" methods for the
  423. most popular sampling factors; the hardwired methods would be faster because
  424. they'd use straight-line code instead of for-loops.  The cost to determine
  425. which method to use is paid only once, at startup, and the selection criteria
  426. are hidden from the callers of the method.
  427.  
  428. This plan differs a little bit from usual object-oriented structures, in that
  429. only one instance of each object class will exist during execution.  The
  430. reason for having the class structure is that on different runs we may create
  431. different instances (choose to execute different modules).
  432.  
  433. To minimize the number of object pointers that have to be passed around, it
  434. will be easiest to have just a few big structs containing all the method
  435. pointers.  We'll actually use two such structs, one for "system-dependent"
  436. methods (memory allocation and error handling) and one for everything else.
  437.  
  438. Because of this choice, it's best not to think of an "object" as a specific
  439. data structure.  Rather, an "object" is just a group of related methods.
  440. There would typically be one or more C modules (source files) providing
  441. concrete implementations of those methods.  You can think of the term
  442. "method" as denoting the common interface presented by some set of functions,
  443. and "object" as denoting a group of common method interfaces, or the total
  444. shared interface behavior of a group of modules.
  445.  
  446.  
  447. *** Data chunk sizes ***
  448.  
  449. To make the cost of this object-oriented style really minimal, we should make
  450. sure that each method call does a fair amount of computation.  To do that we
  451. should pass large chunks of data around; for example, the colorspace
  452. conversion method should process much more than one pixel per call.
  453.  
  454. For many steps, the most natural unit of data seems to be an "MCU row".
  455. This consists of one complete horizontal strip of the image, as high as an
  456. MCU.  In a noninterleaved scan, an MCU row is always eight samples high (when
  457. looking at samples) or one 8x8 block high (when looking at coefficients).  In
  458. an interleaved scan, an MCU row consists of all the data for one horizontal
  459. row of MCUs; this may be from one to four blocks high (eight to thirty-two
  460. samples) depending on the sampling factors.  The height and width of an MCU
  461. row may be different in each component.  (Note that the height and width of an
  462. MCU row changes at the downsampling and upsampling steps.  An unsubsampled
  463. image has the same size in each component.  The preceding statements apply to
  464. the downsampled dimensions.)
  465.  
  466. For example, consider a 1024-pixel-wide image using (2h:2v)(1h:1v)(1h:1v)
  467. subsampling.  In the noninterleaved case, an MCU row of Y would contain 8x1024
  468. samples or the same number of frequency coefficients, so it would occupy
  469. 8K bytes (samples) or 16K bytes (coefficients).  An MCU row of Cb or Cr would
  470. contain 8x512 samples and occupy half as much space.  In the interleaved case,
  471. an MCU row would contain 16x1024 Y samples, 8x512 Cb and 8x512 Cr samples, so
  472. a total of 24K (samples) or 48K (coefficients) would be needed.  This is a
  473. reasonable amount of data to expect to retain in memory at one time.  (Bear in
  474. mind that we'll usually need to have several MCU rows resident in memory at
  475. once, at the inputs and outputs to various pipeline steps.)
  476.  
  477. The worst case is probably (2h:4v)(1h:1v)(1h:1v) interleaving (this uses 10
  478. blocks per MCU, which is the maximum allowed by the spec).  An MCU will then
  479. contain 32 sample rows worth of Y, so it would occupy 40K or 80K bytes for a
  480. 1024-pixel-wide image.  The most memory-intensive step is probably cross-block
  481. smoothing, for which we'd need 3 MCU rows of coefficients as input and another
  482. one as output; that would be 320K of working storage.  Anything much larger
  483. would not fit in an 80x86 machine.  (To decompress wider pictures on an 80x86,
  484. we'll have to skip cross-block smoothing or else use temporary files.)
  485.  
  486. This unit is thus a reasonable-sized chunk for passing through the pipeline.
  487. Of course, its major advantage is that it is a natural chunk size for the MCU
  488. assembly and disassembly steps to work with.
  489.  
  490. For the entropy (Huffman or arithmetic) encoding/decoding steps, the most
  491. convenient chunk is a single MCU: one 8x8 block if not interleaved, three to
  492. ten such blocks if interleaved.  The advantage of this is that when handling
  493. interleaved data, the blocks have the same sequence of component membership on
  494. each call.  (For example, Y,Y,Y,Y,Cb,Cr when using (2h:2v)(1h:1v)(1h:1v)
  495. subsampling.)  The code needs to know component membership so that it can
  496. apply the right set of compression coefficients to each block.  A prebuilt
  497. array describing this membership can be used during each call.  This chunk
  498. size also makes it easy to handle restart intervals: just count off one MCU
  499. per call and reinitialize when the count reaches zero (restart intervals are
  500. specified in numbers of MCU).
  501.