home *** CD-ROM | disk | FTP | other *** search
/ Compressed Image File Formats / CompressedImageFileFormatsJohnMiano.iso / pc / Library / source / jpencomp.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-17  |  30.8 KB  |  1,068 lines

  1. //
  2. // Copyright (c) 1997,1998 Colosseum Builders, Inc.
  3. // All rights reserved.
  4. //
  5. // Colosseum Builders, Inc. makes no warranty, expressed or implied
  6. // with regards to this software. It is provided as is.
  7. //
  8. // See the README.TXT file that came with this software for restrictions
  9. // on the use and redistribution of this file or send E-mail to
  10. // info@colosseumbuilders.com
  11. //
  12.  
  13. //
  14. // JPEG Encoder Library.
  15. //
  16. // Title:   JpegEncoderComponent Class Implementation
  17. //
  18. // Author: John M. Miano  miano@colosseumbuilders.com
  19. //
  20. //
  21.  
  22. #include "jpegenco.h"
  23. #include "jpencomp.h"
  24. #include "jfif.h"
  25. #include "jpencobk.h"
  26. #include "jpendu.h"
  27. #include "jpenhuff.h"
  28.  
  29. //
  30. //  Description:
  31. //
  32. //    Class Default Constructor
  33. //
  34.  
  35. JpegEncoderComponent::JpegEncoderComponent ()
  36. {
  37.  
  38.   jpeg_encoder = NULL ;
  39.   dct_coefficients = NULL ;
  40.  
  41.   du_rows = 0 ;
  42.   du_cols = 0 ;
  43.  
  44.   eob_run = 0 ;
  45.   eob_start_du_row = 0 ;
  46.   eob_start_du_col = 0 ;
  47.   eob_start_position = 0 ;
  48.  
  49.   v_frequency = 1 ;
  50.   h_frequency = 1 ;
  51.  
  52.   ac_table = NULL ;
  53.   dc_table = NULL ;
  54.  
  55.   return ;
  56. }
  57.  
  58. //
  59. //  Description:
  60. //
  61. //    Class Destructor
  62. //
  63. JpegEncoderComponent::~JpegEncoderComponent ()
  64. {
  65.   FreeDynamicStorage () ;
  66.   return ;
  67. }
  68.  
  69. //
  70. //  Description:
  71. //
  72. //    This function gets rid of all the memory allocated by the component.
  73. //    This allows the encoder to free memory after each image is written
  74. //    rather than waiting until the decoder is deleted.
  75. //
  76. void JpegEncoderComponent::FreeDynamicStorage ()
  77. {
  78.   delete [] dct_coefficients ; dct_coefficients = NULL ;
  79.   return ;
  80. }
  81.  
  82. //
  83. //  Description:
  84. //
  85. //    This function allocates the buffer used to hold DCT coefficients.
  86. //
  87. //  Parameters:
  88. //    image: The image being output
  89. //    maxhf: The maximum horizontal frequency for all components.
  90. //    maxvf: The maximum vertical frequency for all components.
  91. //
  92. void JpegEncoderComponent::CalculateDuDimensions (const BitmapImage &image,
  93.                                                   unsigned int maxhf,
  94.                                                   unsigned int maxvf)
  95. {
  96.   du_cols = (image.Width () * h_frequency + (JpegSampleWidth * maxhf - 1))
  97.           / (JpegSampleWidth * maxhf) ;
  98.   du_rows = (image.Height () * v_frequency + (JpegSampleWidth * maxvf - 1))
  99.           / (JpegSampleWidth * maxvf) ;
  100.  
  101.   v_period = maxvf / v_frequency ;
  102.   h_period = maxhf / h_frequency ;
  103.  
  104.   dct_coefficients = new JpegEncoderCoefficientBlock [du_cols * du_rows] ;
  105.   return ;
  106. }
  107.  
  108. //
  109. //  Description:
  110. //
  111. //    This function samples a component where the horizontal and
  112. //    vertical sampling frequencies are equal to the maximum values
  113. //    for all components.
  114. //
  115. //  Parameters:
  116. //    image:  The image to sample
  117. //    function:  A color conversion function
  118. //
  119.  
  120. void JpegEncoderComponent::Sample1to1Component (const BitmapImage &image,
  121.                                                 RGBTOYCBCRFUNCTION function)
  122. {
  123.   const int progressscale = 8 ;
  124.   unsigned int progress = 0 ;
  125.   unsigned int progressincrement = (100 << progressscale) / (du_rows) ;
  126.  
  127.   UBYTE1 red ;
  128.   UBYTE1 green ;
  129.   UBYTE1 blue ;
  130.  
  131.   JpegEncoderDataUnit data ;
  132.  
  133.   unsigned int index = 0 ;
  134.   for (unsigned int ii = 0 ; ii < du_rows ; ++ ii)
  135.   {
  136.     for (unsigned int jj = 0 ; jj < du_cols ; ++ jj, ++ index)
  137.     {
  138.       unsigned int row = ii * JpegSampleWidth ;
  139.       for (unsigned int dr = 0 ; dr < JpegSampleWidth ; ++ dr, ++ row)
  140.       {
  141.         unsigned int col = jj * JpegSampleWidth ;
  142.         for (unsigned int dc = 0 ; dc < JpegSampleWidth ; ++ dc, ++ col)
  143.         {
  144.           if (row < image.Height ())
  145.           {
  146.              if (col < image.Width ())
  147.              {
  148.                  image.GetRGB (row, col, red, green, blue) ;
  149.                  data [dr][dc] = function (red, green, blue) ;
  150.              }
  151.              else if (dc != 0)
  152.              {
  153.                // Extend the rightmost column
  154.                data [dr][dc] = data [dr][dc-1] ;
  155.              }
  156.              else
  157.              {
  158.                // This data unit is completely off the edge of the image.
  159.                data [dr][dc] = JpegMidpointSampleValue ;
  160.              }
  161.           }
  162.           else if (dr != 0)
  163.           {
  164.             // Extend the last row of the image.
  165.             data [dr][dc] = data [dr-1][dc] ;
  166.           }
  167.           else
  168.           {
  169.             // This data unit is completely off the edge of the image.
  170.             data [dr][dc] = JpegMidpointSampleValue ;
  171.           }
  172.         } // Data Unit Columns
  173.       } // Data Unit Rows
  174.  
  175.       data.ForwardDct (*quantization_table, dct_coefficients [index]) ;
  176.     } // Columns of Data Units
  177.     progress += progressincrement ;
  178.     jpeg_encoder->CallProgressFunction (progress >> progressscale) ;
  179.   } // Rows of Data Units
  180.   return ;
  181. }
  182.  
  183. //
  184. //  Description:
  185. //
  186. //    This function downsamples a component where the horizontal and
  187. //    vertical sampling frequencies are not equal to the maximum values
  188. //    for all components. 
  189. //
  190. //  Parameters:
  191. //    image:  The image to sample
  192. //    function:  A color conversion function
  193. //
  194. void JpegEncoderComponent::SampleNtoNComponent (const BitmapImage &image,
  195.                                                 RGBTOYCBCRFUNCTION function)
  196. {
  197.   const int progressscale = 8 ;
  198.   unsigned int progress = 0 ;
  199.   unsigned int progressincrement = (100 << progressscale) / (du_rows) ;
  200.  
  201.   JpegEncoderDataUnit data ;
  202.  
  203.   // Sample the image.
  204.   unsigned int index = 0 ;
  205.   unsigned int imagerow = 0 ;
  206.   for (unsigned int yy = 0 ;
  207.        yy < du_rows ;
  208.        ++ yy, imagerow += JpegSampleWidth * v_period)
  209.   {
  210.     unsigned int imagecol = 0 ;
  211.     for (unsigned int xx = 0 ;
  212.          xx < du_cols ;
  213.          ++ xx, ++ index, imagecol += JpegSampleWidth * h_period)
  214.     {
  215.       // Loop for each row in the data unit.
  216.       for (unsigned int outrow = 0 ; outrow < JpegSampleWidth  ; ++ outrow)
  217.       {
  218.         // Loop for each column in the data unit.
  219.         for (unsigned int outcol = 0 ; outcol < JpegSampleWidth ; ++ outcol)
  220.         {
  221.           // The nested loops handle sampling.
  222.  
  223.           int value = 0 ;   // Sum of all sample values
  224.           unsigned int count = 0 ;  // Number of sample values.
  225.           // Vertical sampling loop.
  226.           for (unsigned int srcrow = 0 ; srcrow < v_period ; ++ srcrow)
  227.           {
  228.             // Horizontal sampling loop.
  229.             unsigned int row = imagerow + srcrow + outrow * v_period ;
  230.             for (unsigned int srccol = 0 ; srccol < h_period ; ++ srccol)
  231.             {
  232.               // Extract the values from the image.
  233.               unsigned int col = imagecol + srccol + outcol * h_period ;
  234.               if (row < image.Height () && col < image.Width ())
  235.               {
  236.                 ++ count ;
  237.                 UBYTE1 red, green, blue ;
  238.                 image.GetRGB (row, col, red, green, blue) ;
  239.                 value += function (red, green, blue) ;
  240.               }
  241.             }
  242.           }
  243.           // Convert the total sample value to an average.
  244.           if (count != 0)
  245.           {
  246.              data [outrow][outcol] = (value + count - 1) / count ;
  247.           }
  248.           else
  249.           {
  250.             // If we get here that means the data unit goes past the edge of
  251.             // the input image. We attempt to duplicate the last column and if
  252.             // we can't to that we copy the last row. If the entire data unit
  253.             // is off the edge then we use zero for the value.
  254.             if (outcol != 0)
  255.               data [outrow][outcol] = data [outrow][outcol - 1] ;
  256.             else if (outrow != 0)
  257.               data [outrow][outcol] = data [outrow-1][outcol] ;
  258.             else
  259.               data [outrow][outcol] = 0 ;
  260.           }
  261.         }
  262.       }
  263.  
  264.       data.ForwardDct (*quantization_table, dct_coefficients [index]) ;
  265.     }
  266.     progress += progressincrement ;
  267.     jpeg_encoder->CallProgressFunction (progress >> progressscale) ;
  268.   }
  269.   return ;
  270. }
  271.  
  272. //
  273. //  Description:
  274. //
  275. //    This function samples the Y component for the image.
  276. //
  277. //    What we do here is determine how much memory is required
  278. //    to hold the image, what color conversion function to use
  279. //    for the component, and if downsampling is required.
  280. //
  281. //  Parameters:
  282. //    encoder:  The JPEG encoder that owns the component
  283. //    image:  The image to be sampled
  284. //    maxhf:  The maximum horizontal frequency of all components
  285. //    maxvf:  The maximum vertical frequency of all components
  286. //    
  287. void JpegEncoderComponent::SampleYComponent (JpegEncoder &encoder,
  288.                                              const BitmapImage &image,
  289.                                              unsigned int maxhf,
  290.                                              unsigned int maxvf)
  291. {
  292.   jpeg_encoder = &encoder ;
  293.   CalculateDuDimensions (image, maxhf, maxvf) ;
  294.  
  295.   if (maxhf == h_frequency && maxvf == v_frequency)
  296.   {
  297.     Sample1to1Component (image, RGBToY) ;
  298.   }
  299.   else
  300.   {
  301.     SampleNtoNComponent (image, RGBToY) ;
  302.   }
  303.  
  304.   return ;
  305. }
  306.  
  307. //
  308. //  Description:
  309. //
  310. //    This function samples the Cb component for the image.
  311. //
  312. //    What we do here is determine how much memory is required
  313. //    to hold the image, what color conversion function to use
  314. //    for the component, and if downsampling is required.
  315. //
  316. //  Parameters:
  317. //    encoder:  The JPEG encoder that owns the component
  318. //    image:  The image to be sampled
  319. //    maxhf:  The maximum horizontal frequency of all components
  320. //    maxvf:  The maximum vertical frequency of all components
  321. //    
  322. void JpegEncoderComponent::SampleCbComponent (JpegEncoder &encoder,
  323.                                               const BitmapImage &image,
  324.                                               unsigned int maxhf,
  325.                                               unsigned int maxvf)
  326. {
  327.   jpeg_encoder = &encoder ;
  328.   CalculateDuDimensions (image, maxhf, maxvf) ;
  329.  
  330.   if (maxhf == h_frequency && maxvf == v_frequency)
  331.   {
  332.     Sample1to1Component (image, RGBToCb) ;
  333.   }
  334.   else
  335.   {
  336.     SampleNtoNComponent (image, RGBToCb) ;
  337.   }
  338.  
  339.   return ;
  340. }
  341.  
  342. //
  343. //  Description:
  344. //
  345. //    This function samples the Cr component for the image.
  346. //
  347. //    What we do here is determine how much memory is required
  348. //    to hold the image, what color conversion function to use
  349. //    for the component, and if downsampling is required.
  350. //
  351. //  Parameters:
  352. //    encoder:  The JPEG encoder that owns the component
  353. //    image:  The image to be sampled
  354. //    maxhf:  The maximum horizontal frequency of all components
  355. //    maxvf:  The maximum vertical frequency of all components
  356. //    
  357.  
  358. void JpegEncoderComponent::SampleCrComponent (JpegEncoder &encoder,
  359.                                               const BitmapImage &image,
  360.                                               unsigned int maxhf,
  361.                                               unsigned int maxvf)
  362. {
  363.   jpeg_encoder = &encoder ;
  364.   CalculateDuDimensions (image, maxhf, maxvf) ;
  365.  
  366.   if (maxhf == h_frequency && maxvf == v_frequency)
  367.   {
  368.     Sample1to1Component (image, RGBToCr) ;
  369.   }
  370.   else
  371.   {
  372.     SampleNtoNComponent (image, RGBToCr) ;
  373.   }
  374.  
  375.   return ;
  376. }
  377.  
  378. //
  379. //  Description:
  380. //
  381. //    This function is use to gather Huffman statistics for DC coefficients.
  382. //    The calling sequences is idential to PrintDcData (). Only the huffvalue
  383. //    parameter is used here.
  384. //
  385. //  Parameters:
  386. //    huffvalue:  The Huffman value (not code) to process.
  387. //
  388. void JpegEncoderComponent::GatherDcData (int huffvalue, int)
  389. {
  390.   dc_table->IncrementFrequency (huffvalue) ;
  391.   return ;
  392. }
  393.  
  394. //
  395. //  Description:
  396. //
  397. //    This function is use to gather Huffman statistics for AC coefficients.
  398. //    The calling sequences is idential to PrintAcData (). Only the huffvalue
  399. //    parameter is used here.
  400. //
  401. //    If huffval==-1 then an unencoded bit string would be output by
  402. //    PrintAcData (). In that situation this function does nothing.
  403. //
  404. //  Parameters:
  405. //    huffvalue:  The Huffman value (not code) to process
  406. //
  407. void JpegEncoderComponent::GatherAcData (int huffvalue, int, int)
  408. {
  409.   if (huffvalue >= 0)
  410.   {
  411.     ac_table->IncrementFrequency (huffvalue) ;
  412.   }
  413.   return ;
  414. }
  415.  
  416. //
  417. //  Description:
  418. //
  419. //    This function is use to output Huffman-encoded data for a DC value.
  420. //
  421. //  Parameters:
  422. //    huffvalue:  The Huffman value
  423. //    bits: The additional data bits
  424. //
  425. //    8-bit DC values are in the range 0..11. The value specifies the number
  426. //    of additional bits of refining data (bits).
  427. //
  428.  
  429. void JpegEncoderComponent::PrintDcData (int huffvalue, int bits)
  430. {
  431.   UBYTE2 huffcode ;
  432.   UBYTE1 huffsize ;
  433.  
  434.   // Section F.1.2.1
  435.   dc_table->Encode (huffvalue, huffcode, huffsize) ;
  436.   jpeg_encoder->OutputBits (huffcode, huffsize) ;
  437.   if (huffvalue != 0)
  438.     jpeg_encoder->OutputBits (bits, huffvalue) ;
  439.   return ;
  440. }
  441.  
  442. //
  443. //  Description:
  444. //
  445. //    This function is use to output Huffman-encoded data for an AC value.
  446. //
  447. //  Parameters:
  448. //    huffvalue:  The Huffman value
  449. //    value: The additional data bits
  450. //    size: The number of additional data bits.
  451. //
  452. //    When huffvalue==-1 this function is also used to output unencoded bit
  453. //    strings.
  454. //
  455. void JpegEncoderComponent::PrintAcData (int huffvalue, int value, int size)
  456. {
  457.   UBYTE2 huffcode ;
  458.   UBYTE1 huffsize ;
  459.  
  460.   // Section F.1.2.2.1
  461.   if (huffvalue >= 0)
  462.   {
  463.     ac_table->Encode (huffvalue, huffcode, huffsize) ;
  464.     jpeg_encoder->OutputBits (huffcode, huffsize) ;
  465.   }
  466.   if (size != 0)
  467.     jpeg_encoder->OutputBits (value, size) ;
  468.   return ;
  469. }
  470. //
  471. //  Description:
  472. //
  473. //    This function is used for two purposes in a sequential scan:
  474. //
  475. //      o To gather statistics for generating Huffman Tables
  476. //      o To encode and output a data unit.
  477. //
  478. //    The dcfunction and acfunction arguments are determine which of these
  479. //    actions are performed. If these arguments are PrintDcData () and
  480. //    PrintAcData () the data unit is encoded and written to the output
  481. //    stream.  If the arguments are GatherDcData () and GatherAcData ()
  482. //    usage statistics are gathered.
  483. //
  484. //    While creating a separate function for each purpose may have been clearer,
  485. //    it would create maintenance problems because they would have to be kept
  486. //    in strict synchronization with each other.
  487. //
  488. //  Parameters:
  489. //    row,col: Data unit position
  490. //    dcfunction: Function for outputting DC coefficient values.
  491. //    acfunction: Function for outputting AC coefficient values.
  492. //
  493. //    This function is of the type COMPONENTPASSFUNCTION.
  494. //
  495. void JpegEncoderComponent::EncodeSequential (
  496.                             unsigned int row, unsigned int col,
  497.                             DCOUTPUTFUNCTION dcfunction,
  498.                             ACOUTPUTFUNCTION acfunction,
  499.                             unsigned int, unsigned int, unsigned int)
  500. {
  501.   JpegEncoderCoefficientBlock *du = &dct_coefficients [row * du_cols + col] ;
  502.  
  503.   // DC value calculation
  504.   // Section F.1.2.1.3
  505.   int diff = (*du) [0][0] - last_dc_value ;
  506.   last_dc_value = (*du)[0][0] ;
  507.  
  508.   // Break the DC coefficient into a category (Table F.12) and
  509.   // additional bits.
  510.   int bits ;
  511.   if (diff >= 0)
  512.   {
  513.     bits = diff ;
  514.   }
  515.   else
  516.   {
  517.     diff = -diff ;
  518.     bits = ~diff ;
  519.   }
  520.   int ssss = 0 ;  // Category
  521.   while (diff != 0)
  522.   {
  523.     ++ ssss ;
  524.     diff >>= 1 ;
  525.   }
  526.   (this->*dcfunction) (ssss, bits) ;
  527.  
  528.   // AC coefficient coding
  529.   // F.1.2.2.3 Figure F.2
  530.   int zerorun = 0 ; // Called rrrr in the specification.
  531.   for (unsigned int index = 1 ; index < JpegSampleSize ; ++ index)
  532.   {
  533.     if (du->ZigZagInput (index) != 0)
  534.     {
  535.       // 16 is the longest run of zeros that can be encoded except for the
  536.       // final EOB code.
  537.       while (zerorun >= 16)
  538.       {
  539.         // 0xF0 is the code to skip 16 zeros (Figure F.1)
  540.         (this->*acfunction) (0xF0, 0, 0) ;
  541.         zerorun -= 16 ;
  542.       }
  543.  
  544.       // Non-zero AC coefficients are encoded with
  545.       // 8-bit Huffman-encoded values of the form rrrrssss followed by
  546.       // 1..10 additional bits of data. rrrr is the number of zero values
  547.       // to skip (0..15). ssss is the category (1..10) which specifies the
  548.       // number of additional raw bits to follow. (Figure F.1)
  549.       int value = du->ZigZagInput (index) ;
  550.       int bits ;
  551.       if (value >= 0)
  552.       {
  553.         bits = value ;
  554.       }
  555.       else
  556.       {
  557.         value = -value ;
  558.         bits = ~value ;
  559.       }
  560.       int ssss = 0 ;
  561.       while (value != 0)
  562.       {
  563.         value >>= 1 ;
  564.         ++ ssss ;
  565.       }
  566.  
  567.       int rrrrssss = (zerorun << 4) | ssss ;
  568.       (this->*acfunction) (rrrrssss, bits, ssss) ;
  569.       zerorun = 0 ;
  570.     }
  571.     else
  572.     {
  573.       ++ zerorun ;
  574.     }
  575.   }
  576.   // The code 0x00 indicates all remaining AC coefficients are zero.
  577.   if (zerorun > 0)
  578.   {
  579.     (this->*acfunction) (0, 0, 0) ;
  580.   }
  581.  
  582.   return ;
  583. }
  584.  
  585. //
  586. //  Description:
  587. //
  588. //    This function outputs an End of Band run in an initial AC coefficient
  589. //    scan of a progressive frame.
  590. //
  591. //  Parameters:
  592. //    acfunction: Function for outputting AC coefficient values
  593. //
  594. void JpegEncoderComponent::PrintEobRun (ACOUTPUTFUNCTION acfunction)
  595. {
  596.   // Figure G.4
  597.   if (eob_run != 0)
  598.   {
  599.     unsigned int bits = eob_run ;
  600.     unsigned int value = bits >> 1 ;
  601.     unsigned int ssss = 0 ; // Category (Table G.1)
  602.     while (value != 0)
  603.     {
  604.       value >>= 1 ;
  605.       ++ ssss ;
  606.     }
  607.     (this->*acfunction)(ssss << 4, bits, ssss) ;
  608.     eob_run = 0 ;
  609.   }
  610.  
  611.   return ;
  612. }                               
  613.  
  614. //
  615. //  Description:
  616. //
  617. //    This function is use to output a data unit for the first pass
  618. //    DC progressive scan. The DC coefficients are encoded in the same manner
  619. //    as in a sequential scan except for the point transform.
  620. //
  621. //    This function gets called twice for each data unit in the scan. The
  622. //    first pass is used to gather Huffman statistics and the second is
  623. //    used to Huffman-encode the data and write it to the output stream.
  624. //    We use pointers to the statistics/output functions to ensure that
  625. //    both passes are performed in the exact same manner.
  626. //
  627. //  Parameters:
  628. //    row,col: Data unit position
  629. //    dcfunction: Function for outputting DC coefficient values.
  630. //    successiveapproximation: Successive Approximation
  631. //
  632. //    This function is of the type COMPONENTPASSFUNCTION.
  633. //
  634. void JpegEncoderComponent::ProgressiveDcFirst (
  635.                           unsigned int row, unsigned int col,
  636.                           DCOUTPUTFUNCTION dcfunction, ACOUTPUTFUNCTION,
  637.                           unsigned int, unsigned int,
  638.                           unsigned int successiveapproximation)
  639. {
  640.   // G.1.2.1
  641.  
  642.   // DC value calculation
  643.   // A.4
  644.   int value = dct_coefficients [row * du_cols + col][0][0]
  645.             >> successiveapproximation ;
  646.  
  647.   // Section F.1.2
  648.   int diff = value - last_dc_value ;
  649.   last_dc_value = value ;
  650.  
  651.   // Break the difference into a category for Huffman coding and additional
  652.   // raw bits for refinement.
  653.   int bits ;
  654.   if (diff >= 0)
  655.   {
  656.     bits = diff ;
  657.   }
  658.   else
  659.   {
  660.     diff = -diff ;
  661.     bits = ~diff ;
  662.   }
  663.   int ssss = 0 ;  // Category
  664.   while (diff != 0)
  665.   {
  666.     ++ ssss ;
  667.     diff >>= 1 ;
  668.   }
  669.   (this->*dcfunction) (ssss, bits) ;
  670.  
  671.   return ;
  672. }
  673.  
  674. //
  675. //  Description:
  676. //
  677. //    This function outputs DC coefficient data for refining scans in a
  678. //    progressive frame. This is the only thing simple about progressive
  679. //    JPEG. In this scan we simply encode an additional bit for each
  680. //    DC coefficient.
  681. //
  682. //    Since there is no Huffman coding for this refining DC scans this function
  683. //    only gets called once per data unit in a scan. Therefore we do not
  684. //    use the output function pararmeters.
  685. //
  686. //  Parameters:
  687. //    row,col: Data unit position
  688. //    ssa:  Successive Approximation
  689. //
  690. //    This function is of the type COMPONENTPASSFUNCTION.
  691. //
  692. void JpegEncoderComponent::ProgressiveDcRefine (
  693.                             unsigned int row, unsigned int col,
  694.                             DCOUTPUTFUNCTION, ACOUTPUTFUNCTION,
  695.                             unsigned int, unsigned int,
  696.                             unsigned int ssa)
  697. {
  698.   // Section G.1.2.1
  699.   int value = (dct_coefficients [row * du_cols + col][0][0] >> ssa) & 0x1 ;
  700.   jpeg_encoder->OutputBits (value, 1) ;
  701.   return ;
  702. }
  703.  
  704. //
  705. //  Description:
  706. //
  707. //    This function encodes a data unit for the first AC coefficient scan
  708. //    for a spectral range in a progressive frame. The procedure here
  709. //    is taken literally from the JPEG specification.
  710. //
  711. //    The AC encoding complexity is significantly increased over that of
  712. //    sequential scans because End of Bands can span data units.
  713. //
  714. //  Parameters:
  715. //    row,col: Data unit position
  716. //    acfunction: Function for outputting AC coefficient values
  717. //    sss:  Spectral Selection Start
  718. //    sse:  Spectral Selection End
  719. //    ssa:  Successive Approximation
  720. //
  721. void JpegEncoderComponent::ProgressiveAcFirst (
  722.                             unsigned int row, unsigned int col,
  723.                             ACOUTPUTFUNCTION acfunction,
  724.                             unsigned int sss, unsigned int sse,
  725.                             unsigned int ssa)
  726. {
  727.   JpegEncoderCoefficientBlock *du = &dct_coefficients [row * du_cols + col] ;
  728.  
  729.   // G.1.2.2 Figure G.3
  730.   unsigned int zerorun = 0 ;
  731.   for (unsigned int ii = sss ; ii <= sse ; ++ ii)
  732.   {
  733.     int value = du->ZigZagInput (ii) ;
  734.     // Point Transform
  735.     value = value / (1 << ssa) ;
  736.  
  737.     if (value == 0)
  738.     {
  739.       ++ zerorun ;
  740.     }
  741.     else
  742.     {
  743.       PrintEobRun (acfunction) ;
  744.       // Figure G.5
  745.       while (zerorun >= 16)
  746.       {
  747.         (this->*acfunction)(0xF0, 0, 0) ;
  748.         zerorun -= 16 ;
  749.       }
  750.  
  751.       int bits ;
  752.       if (value >= 0)
  753.       {
  754.         bits = value ;
  755.       }
  756.       else
  757.       {
  758.         value = -value ;
  759.         bits = ~value ;
  760.       }
  761.       int ssss = 0 ;
  762.       while (value != 0)
  763.       {
  764.         ++ ssss ;
  765.         value >>= 1 ;
  766.       }
  767.       unsigned int rrrrssss = (zerorun << 4) | ssss ;
  768.       (this->*acfunction) (rrrrssss, bits, ssss) ;
  769.       zerorun = 0 ;
  770.  
  771.       if (ii >= sse)
  772.         return ;
  773.     }
  774.   }
  775.   ++ eob_run ;
  776.  
  777.   // Do not allow the EOB run to exceed 0x7FFF.
  778.   // G.1.2.2
  779.   if (eob_run == 0x7FFF)
  780.     PrintEobRun (acfunction) ;
  781.   return ;
  782. }
  783.  
  784. //
  785. //  Description:
  786. //
  787. //    This function encodes the AC coefficients for a refining scan in a
  788. //    progressive frame.
  789. //
  790. //    The JPEG standard is nebulous here (Section G.1.2.3). It is
  791. //    unfortunate that for such a brain-damaged encoding method as
  792. //    this that they should be unclear. In addition to the complexity
  793. //    of having EOB runs span data units, data does not get written
  794. //    out in the order it occurs.
  795. //
  796. //    This is why there are no section references in the code other than
  797. //    the one above. I am simply guessing here, sorry. I created this code by
  798. //    guessing and running the output through various applications that handle
  799. //    progressive JPEG until I could find no complaints.
  800. //
  801. //    If you thing this is bad wait until you get to the part about decoding
  802. //    progressive scans (G.2)!
  803. //
  804. //  Parameters:
  805. //    row,col: Data unit position
  806. //    acfunction: Function for outputting AC coefficient values
  807. //    sss:  Spectral Selection Start
  808. //    sse:  Spectral Selection End
  809. //    ssa:  Successive Approximation
  810. //
  811. void JpegEncoderComponent::ProgressiveAcRefine (
  812.                             unsigned int row, unsigned int col,
  813.                             ACOUTPUTFUNCTION acfunction,
  814.                             unsigned int sss, unsigned int sse,
  815.                             unsigned int ssa)
  816. {
  817.   JpegEncoderCoefficientBlock *du = &dct_coefficients [row * du_cols + col] ;
  818.   // Number of zero coefficients - Note that existing non-zero coefficients
  819.   // are not included in this count.
  820.   unsigned int zerorun = 0 ;
  821.   // The start of the zero run.
  822.   unsigned int zerostart = sss ;
  823.   // Number of existing non-zero coefficients - used only for error checking.
  824.   unsigned int correctioncount = 0 ;
  825.  
  826.   for (unsigned int ii = sss ; ii <= sse ; ++ ii)
  827.   {
  828.     // Point Transform
  829.     int value = du->ZigZagInput (ii) / (1 << ssa) ;
  830.  
  831.     // We have three types of values:
  832.     //  o A Zero
  833.     //  o A coefficient that was zero in all previous scan that we are
  834.     //    going to make non-zero in this scan (value = +/-1)
  835.     //  o An coefficient that was made non-zero in a previous scan
  836.     //      (value > 1 OR value < -1)
  837.     if (value == 0)
  838.     {
  839.       ++ zerorun ;
  840.     }
  841.     else if (value == 1 || value == -1)
  842.     {
  843.       // If way have an EOB run then print it out.
  844.       PrintRefineEobRun (acfunction, sss, sse, ssa) ;
  845.  
  846.       // The longest zero run we can have is 16.
  847.       while (zerorun >= 16)
  848.       {
  849.         (this->*acfunction)(0xF0, 0, 0) ;
  850.         zerorun -= 16 ;
  851.  
  852.         // Refine all the existing coefficients skipped by the zero run.
  853.         for (int zerocount = 0 ;
  854.              zerocount < 16 ;
  855.              ++ zerostart)
  856.         {
  857.           if (zerostart < sss || zerostart > sse
  858.               || correctioncount > JpegSampleSize)
  859.           {
  860.             throw EJpegFatal ("INTERNAL ERROR - Invalid Zero Run") ;
  861.  
  862.           }
  863.  
  864.           int oldvalue = du->ZigZagInput (zerostart) / (1 << ssa) ;
  865.           if (oldvalue < 0)
  866.             oldvalue = - oldvalue ;
  867.           if (oldvalue > 1)
  868.           {
  869.             (this->*acfunction)(-1, (oldvalue & 0x1), 1) ;
  870.             -- correctioncount ;
  871.           }
  872.           else if (oldvalue == 0)
  873.           {
  874.             // Because we need to count only zero values we our loop counter
  875.             // gets incremented here.
  876.             ++ zerocount ;
  877.           }
  878.           else
  879.           {
  880.             // If the value is +/- 1 we should have already processed it.
  881.             throw EJpegFatal ("INTERNAL ERROR - Bad Value") ;
  882.           }
  883.         }
  884.       }
  885.  
  886.       // This is the first time this value has been nonzero.
  887.       int output = (zerorun << 0x4) | 1 ;
  888.       if (value > 0)
  889.         (this->*acfunction)(output, 1, 1) ;
  890.       else
  891.         (this->*acfunction)(output, 0, 1) ;
  892.       zerorun = 0 ;
  893.  
  894.       // No go back and refine all the previously non-zero coefficients
  895.       // skipped by this zero run.
  896.       for (unsigned int jj = zerostart ; jj < ii ; ++ jj)
  897.       {
  898.         int oldvalue = du->ZigZagInput (jj) / (1 << ssa) ;
  899.         if (oldvalue < 0)
  900.           oldvalue = - oldvalue ;
  901.         if (oldvalue > 1)
  902.         {
  903.           (this->*acfunction)(-1, (oldvalue & 0x1), 1) ;
  904.           -- correctioncount ;
  905.         }
  906.       }
  907.       zerostart = ii + 1 ;
  908.       if (ii == sse)
  909.         return ;  // All finished with this data unit.
  910.     }
  911.     else
  912.     {
  913.       // We only use this counter for error checking. It contains the
  914.       // number of previously non-zero coefficients that we have skipped
  915.       /// as part of a zero run.
  916.       ++ correctioncount ;
  917.     }
  918.   }
  919.   // If we get here then the data unit ends with a string of zero coefficients
  920.   // or previously non-zero coefficients that we are skipping.
  921.   if (eob_run == 0)
  922.   {
  923.     // We are beginning and End of Band run. Mark the starting position
  924.     // including the spectral position.
  925.     eob_start_du_row = row ;
  926.     eob_start_du_col = col ;
  927.     eob_start_position = zerostart ;
  928.   }
  929.   ++ eob_run ;
  930.   // G.1.2.2
  931.   if (eob_run == 0x7FFF)
  932.     PrintRefineEobRun (acfunction, sss, sse, ssa) ;
  933.   return ;
  934. }
  935.  
  936. //
  937. //  Description:
  938. //
  939. //    This function Resets the End of Band run counters. It should be called
  940. //    before beginning to output a scan.
  941. //
  942. void JpegEncoderComponent::ResetEobRun ()
  943. {
  944.   eob_run = 0 ;
  945.  
  946.   // We use values here that should make an error easier to detect.
  947.   eob_start_du_row = du_cols * du_rows ;
  948.   eob_start_du_col = du_cols * du_rows ;
  949.   eob_start_position = JpegSampleSize ;
  950.  
  951.   return ;
  952. }
  953.  
  954. //
  955. //  Description:
  956. //
  957. //    This function outputs an End of Band run in a refining AC ceofficient
  958. //    scan of a progressive frame. As for the rest of the refining AC scan
  959. //    data I am mostly guessing here. I have taken the process from
  960. //    Figure G.4 and the vague description in Section G.1.2.3. It seems to
  961. //    work.
  962. //
  963. //  Parameters:
  964. //    acfunction: Function for outputting AC coefficient values
  965. //    sss:  Spectral Selection Start
  966. //    sse:  Spectral Selection End
  967. //    ssa:  Successive Approximation
  968. //
  969. void JpegEncoderComponent::PrintRefineEobRun (ACOUTPUTFUNCTION acfunction,
  970.                             unsigned int sss, unsigned int sse,
  971.                             unsigned int ssa)
  972. {
  973.   if (eob_run != 0)
  974.   {
  975.     unsigned int bits = eob_run ;
  976.     unsigned int value = bits >> 1 ;
  977.     unsigned int ssss = 0 ; // Category (Table G.1)
  978.     while (value != 0)
  979.     {
  980.       value >>= 1 ;
  981.       ++ ssss ;
  982.     }
  983.     (this->*acfunction)(ssss << 4, bits, ssss) ;
  984.  
  985.     // Now that we have output the EOB run we need to refine each coefficient
  986.     // that we skipped that had previously been non-zero.
  987.     unsigned int  eobcounter = 0 ;
  988.     unsigned int row = eob_start_du_row ;
  989.     unsigned int col = eob_start_du_col ;
  990.     while (eobcounter < eob_run)
  991.     {
  992.       JpegEncoderCoefficientBlock *du
  993.         = &dct_coefficients [row * du_cols + col] ;
  994.       for (unsigned int kk = eob_start_position ;
  995.            kk <= sse ;
  996.            ++ kk)
  997.       {
  998.         int value = du->ZigZagInput (kk) / (1<< ssa) ;
  999.         if (value < 0)
  1000.           value = - value ;
  1001.         if (value > 1)
  1002.         {
  1003.           (this->*acfunction)(-1, (value & 0x1), 1) ;
  1004.         }
  1005.       }
  1006.       // Except for the first data unit we go to the first spectral value
  1007.       // in the scan.
  1008.       eob_start_position = sss ;
  1009.  
  1010.       ++ eobcounter ;
  1011.       ++ col ;
  1012.       if (col == du_cols)
  1013.       {
  1014.         col = 0 ;
  1015.         ++ row ;
  1016.         if (row >= du_cols && eobcounter != eob_run)
  1017.           throw EJpegFatal ("INTERNAL ERROR - EOB run extends past last row") ;
  1018.       }
  1019.     }
  1020.  
  1021.     // Some values that are certain to cause errors if improperly used.
  1022.     eob_start_position = JpegSampleSize ;
  1023.     eob_start_du_row = du_cols * du_rows ;
  1024.     eob_start_du_col = du_cols * du_rows ;
  1025.  
  1026.     eob_run = 0 ; // Reset the counter.
  1027.   }
  1028.  
  1029.   return ;
  1030. }
  1031.  
  1032. //
  1033. //  Description
  1034. //
  1035. //    This function sets the horizontal sampling frequency for the
  1036. //    component.
  1037. //
  1038. //  Parameters:
  1039. //    value:  The new sampling frequency.
  1040. //
  1041. void JpegEncoderComponent::SetHorizontalFrequency (unsigned int value)
  1042. {
  1043.   if (value > JpegMaxSamplingFrequency || value < JpegMinSamplingFrequency)
  1044.       throw EJpegValueOutOfRange () ;
  1045.  
  1046.   h_frequency = value ;
  1047.     return ;
  1048. }
  1049.  
  1050. //
  1051. //  Description
  1052. //
  1053. //    This function sets the vertical sampling frequency for the
  1054. //    component.
  1055. //
  1056. //  Parameters:
  1057. //    value:  The new sampling frequency.
  1058. //
  1059. void JpegEncoderComponent::SetVerticalFrequency (unsigned int value)
  1060. {
  1061.   if (value > JpegMaxSamplingFrequency || value < JpegMinSamplingFrequency)
  1062.     throw EJpegValueOutOfRange () ;
  1063.  
  1064.   v_frequency = value ;
  1065.   return ;
  1066. }
  1067.  
  1068.