home *** CD-ROM | disk | FTP | other *** search
/ Compressed Image File Formats / CompressedImageFileFormatsJohnMiano.iso / pc / Library / source / jpegenco.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-27  |  70.0 KB  |  2,339 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:   JpegEncoder Class Implementation
  17. //
  18. // Author: John M. Miano  miano@colosseumbuilders.com
  19. //
  20. //
  21.  
  22. #include <math.h>
  23. #include <string>
  24. #include "jpegenco.h"
  25. #include "bitimage.h"
  26. #include "jfif.h"
  27. #include "jpenquan.h"
  28. #include "jpenhuff.h"         
  29.  
  30.  
  31. //
  32. // These are sample quantization tables defined in the the JPEG Standard.
  33. //
  34.  
  35. // From Section K.1 Table K-1
  36. static const unsigned int default_luminance_table [JpegSampleSize]  =
  37. {
  38. 16, 11, 10, 16,  24,  40,  51,  61,
  39. 12, 12, 14, 19,  26,  58,  60,  55,
  40. 14, 13, 16, 24,  40,  57,  69,  56,
  41. 14, 17, 22, 29,  51,  87,  80,  62,
  42. 18, 22, 37, 56,  68, 109, 103,  77,
  43. 24, 35, 55, 64,  81, 104, 113,  92,
  44. 49, 64, 78, 87, 103, 121, 120, 101,
  45. 72, 92, 95, 98, 112, 100, 103,  99,
  46. } ;
  47.  
  48. // From Section K.1 Table K-2
  49. static const unsigned int default_chrominance_table [JpegSampleSize] =
  50. {
  51. 17, 18, 24, 47, 99, 99, 99, 99,
  52. 18, 21, 26, 66, 99, 99, 99, 99,
  53. 24, 26, 56, 99, 99, 99, 99, 99,
  54. 47, 66, 99, 99, 99, 99, 99, 99,
  55. 99, 99, 99, 99, 99, 99, 99, 99,
  56. 99, 99, 99, 99, 99, 99, 99, 99,
  57. 99, 99, 99, 99, 99, 99, 99, 99,
  58. 99, 99, 99, 99, 99, 99, 99, 99,
  59. } ;
  60.  
  61. //
  62. //  Description:
  63. //
  64. //    Class Default Constructor
  65. //
  66. JpegEncoder::JpegEncoder ()
  67. {
  68.   Initialize () ;
  69.   return ;
  70. }
  71.  
  72. //
  73. //  Description:
  74. //
  75. //    Class Copy Constructor
  76. //
  77. JpegEncoder::JpegEncoder (const JpegEncoder &source)
  78. {
  79.   Initialize () ;
  80.   DoCopy (source) ;
  81.   return ;
  82. }
  83.  
  84. //
  85. //  Description:
  86. //
  87. //    Class Destructor
  88. //
  89. JpegEncoder::~JpegEncoder ()
  90. {
  91.   delete [] ac_tables ; ac_tables = NULL ;
  92.   delete [] dc_tables ; dc_tables = NULL ;
  93.   delete chrominance_quanttbl ; chrominance_quanttbl = NULL ;
  94.   delete luminance_quanttbl ; luminance_quanttbl = NULL ;
  95.   return ;
  96. }
  97. //
  98. //  Description:
  99. //
  100. //    Class assignment operator.
  101. //
  102. JpegEncoder &JpegEncoder::operator=(const JpegEncoder &source)
  103. {
  104.   DoCopy (source) ;
  105.   return *this ;
  106. }
  107. //
  108. //  Description:
  109. //
  110. //    Class copy function. This function gets called from the
  111. //    copy constructor and assignment operator.  The only thing
  112. //    we copy are the use settable parameters.
  113. //
  114. void JpegEncoder::DoCopy (const JpegEncoder &source)
  115. {
  116.   gray_scale = source.gray_scale ;
  117.   rows_per_restart = source.rows_per_restart ;
  118.   comment_string = source.comment_string ;
  119.   image_quality = source.image_quality ;
  120.   progressive_mode = source.progressive_mode ;
  121.  
  122.   for (unsigned int ii = 0 ; ii < MaxScans ; ++ ii)
  123.     image_scans [ii] = source.image_scans [ii] ;
  124.  
  125.   BitmapImageCoder::operator=(source) ;
  126.   return ;
  127. }
  128. //
  129. //  Description:
  130. //
  131. //    This function writes an image to the output stream.
  132. //
  133. //  Parameters:
  134. //    strm:   The output stream to write the image to. This most be opened in
  135. //            binary mode
  136. //    image:  The image to output.
  137. //
  138. void JpegEncoder::WriteImage (std::ostream &strm, BitmapImage &image)
  139. {
  140.   bit_count = 0 ;
  141.   current_image = &image ;
  142.  
  143.   output_stream = &strm ;
  144.  
  145.   CreateQuantizationTables (image_quality) ;
  146.  
  147.   frame_height = image.Height () ;
  148.   frame_width = image.Width () ;
  149.  
  150.   // Find the MCU size and maximum sampling frequencies.
  151.   CalculateMcuDimensions () ;
  152.  
  153.   // Validate Parameters. If there is an error this function will throw
  154.   // an exception.
  155.   ValidateParameters () ;
  156.  
  157.   CountPassesForProgressReporting () ;
  158.  
  159.   // Write the image header.
  160.   OutputMarker (SOI) ;
  161.   OutputMarker (APP0) ;
  162.   OutputJfifHeader () ;
  163.  
  164.   if (comment_string != "")
  165.     PrintComment (comment_string) ;
  166.  
  167.   PrintComment ("Created using the Colosseum Builders JPEG library") ;
  168.  
  169.   if (progressive_mode)
  170.     PrintProgressiveFrame (image) ;
  171.   else
  172.     PrintSequentialFrame (image) ;
  173.  
  174.   OutputMarker (EOI) ;
  175.  
  176.   // Make sure that we are not holding on to any memory we do not
  177.   // need any more.
  178.   image_components [YComponent].FreeDynamicStorage () ;
  179.   image_components [CbComponent].FreeDynamicStorage () ;
  180.   image_components [CrComponent].FreeDynamicStorage () ;
  181.  
  182.   return ;
  183. }
  184. //
  185. //  Description:
  186. //
  187. //    Class Initialization function. This function is intended to be
  188. //    called from constructors.
  189. //
  190. void JpegEncoder::Initialize ()
  191. {
  192.   memset (image_scans, 0, sizeof (image_scans)) ;
  193.   image_scans [0].component_mask = (1<<YComponent)
  194.                                  |(1<<CbComponent)
  195.                                  |(1<<CrComponent) ;
  196.   progressive_mode = false ;
  197.   image_quality = 75 ;
  198.   progress_function = NULL ;
  199.   progress_data = NULL ;
  200.   restart_interval = 0 ;
  201.   rows_per_restart = 0 ;
  202.   gray_scale = false ;
  203.  
  204.   for (unsigned int ii = 0 ; ii < MaxComponents ; ++ ii)
  205.   {
  206.     image_components [ii].SetHorizontalFrequency (1) ;
  207.     image_components [ii].SetVerticalFrequency (1) ;
  208.   }
  209.  
  210.   ac_tables = new JpegEncoderHuffmanTable [2] ;
  211.   dc_tables = new JpegEncoderHuffmanTable [2] ;
  212.   chrominance_quanttbl = new JpegEncoderQuantizationTable ;
  213.   luminance_quanttbl = new JpegEncoderQuantizationTable ;
  214.  
  215.   image_components [YComponent].SetHuffmanTables (dc_tables [0],
  216.                                                   ac_tables [0]) ;
  217.   image_components [CbComponent].SetHuffmanTables (dc_tables [1],
  218.                                                    ac_tables [1]) ;
  219.   image_components [CrComponent].SetHuffmanTables (dc_tables [1],
  220.                                                    ac_tables [1]) ;
  221.  
  222.   image_components [YComponent].SetQuantizationTable (*luminance_quanttbl) ;
  223.   image_components [CbComponent].SetQuantizationTable (
  224.                                           *chrominance_quanttbl) ;
  225.   image_components [CrComponent].SetQuantizationTable (
  226.                                           *chrominance_quanttbl) ;
  227.  
  228.   return ;
  229. }
  230.  
  231.  
  232. //
  233. //  Description:
  234. //
  235. //    This function creates the quantization tables for writing the image.
  236. //
  237. //    Rather than have the user specify all 128 quantization table
  238. //    values we have the user specify a quality vale in the range
  239. //    1..100 then scale the sample quantization tables in the JPEG
  240. //    specification. A quality value of 50 uses the unmodified tables.
  241. //    At a quality value of 100 no quantization takes place (all 1s).
  242. //    A quality value of 1 will create a solid black image. Quality
  243. //    values below around 25 are pretty useless.
  244. //
  245. //  Parameters:
  246. //    quality:  The image quality (1-100)
  247. //
  248.  
  249. void JpegEncoder::CreateQuantizationTables (unsigned int quality)
  250. {
  251.   // We need this declaration because MSVC++ does not support
  252.   // standard scoping in for statements.
  253.   unsigned int ii ;
  254.  
  255.   if (quality < 1 || quality > 100)
  256.     throw EJpegValueOutOfRange () ;
  257.  
  258.   // Scale Factor
  259.   double scale = exp ((6 * (50 - (int) quality)/50.0) * log (2.0)) ;
  260.  
  261.   for (ii = 0 ; ii < JpegSampleSize ; ++ ii)
  262.   {
  263.     unsigned int value = (unsigned int) 
  264.          (default_luminance_table [JpegZigZagInputOrder (ii)]
  265.          * scale) ;
  266.     if (value < JpegMinQuantizationValue)
  267.       (*luminance_quanttbl) [ii] = JpegMinQuantizationValue ;
  268.     else if (value > JpegMax8BitQuantizationValue)
  269.       (*luminance_quanttbl) [ii] = JpegMax8BitQuantizationValue ;
  270.     else
  271.       (*luminance_quanttbl) [ii] = value ;
  272.   }
  273.  
  274.   for (ii = 0 ; ii < JpegSampleSize ; ++ ii)
  275.   {
  276.     unsigned int value = (unsigned int) 
  277.         (default_chrominance_table [JpegZigZagInputOrder (ii)]
  278.         * scale) ;
  279.     if (value < 1)
  280.       (*chrominance_quanttbl) [ii] = JpegMinQuantizationValue ;
  281.     else if (value > JpegMax8BitQuantizationValue)
  282.       (*chrominance_quanttbl) [ii] = JpegMax8BitQuantizationValue ;
  283.     else
  284.       (*chrominance_quanttbl) [ii] = value ;
  285.   }
  286.  
  287.   // Here we generate the scaled tables used for the fast FDCT.
  288.   chrominance_quanttbl->BuildScaledTables () ;
  289.   luminance_quanttbl->BuildScaledTables () ;
  290.   return ;
  291.  
  292. }
  293.  
  294. //
  295. //  Description:
  296. //
  297. //    This function writes a single byte to the output stream.
  298. //
  299. //  Parameters:
  300. //    value: The byte to be written to the output stream.
  301. //
  302. void JpegEncoder::OutputByte (UBYTE1 value)
  303. {
  304.   if (bit_count != 0)
  305.     FlushBitBuffer () ;
  306.  
  307.   output_stream->write ((char *) &value, sizeof (value)) ;
  308.   return ;
  309. }
  310.  
  311. //
  312. //  Description:
  313. //
  314. //    This function writes a 2-byte integer in system format to the output
  315. //    stream in bit-endian order (most significant byte first).
  316. //
  317. //  Parameters:
  318. //    value: The 2-byte data to be written to the output stream
  319. //
  320. void JpegEncoder::OutputWord (UBYTE2 value)
  321. {
  322.   if (bit_count != 0)
  323.     FlushBitBuffer () ;
  324.  
  325.   UBYTE2 data = SystemToBigEndian (value) ;
  326.   output_stream->write ((char *) &data, sizeof (data)) ;
  327.   return ;
  328. }
  329.  
  330. //
  331. //  Description:
  332. //
  333. //    This function outputs a single bit to the output stream.
  334. //
  335. //    Individual its are buffered using the bit_buffer and bit_count member
  336. //    variables.
  337. //
  338. //    This function throws an exception if it is called with a zero bit count.
  339. //    We use this for error trapping since no place in the rest of the
  340. //    code should attempt to write zero bits.
  341. //
  342. //  Parameters:
  343. //    bits: The bit string to be output
  344. //    count: The number of bits to output
  345. //
  346. void JpegEncoder::OutputBits (int bits, unsigned int count)
  347. {
  348.   if (count == 0)
  349.     throw EJpegFatal ("Internal Error - Invalid Bit Count") ;
  350.  
  351.   for (unsigned int ii = 0 ; ii < count ; ++ ii)
  352.   {
  353.     bit_buffer <<= 1 ;
  354.     ++ bit_count ;
  355.     bit_buffer |= ((bits >> (count - ii - 1)) & 0x1) ;
  356.     if (bit_count == 8)
  357.     {
  358.       output_stream->write ((char *) &bit_buffer, 1) ;
  359.       // The Sequence FF00 in the files is used to represent the value FF
  360.       // in the stream to differentiate it from a marker.
  361.       if (bit_buffer == SOB)
  362.       {
  363.         bit_buffer = 0 ;
  364.         output_stream->write ((char *) &bit_buffer, 1) ;
  365.       }
  366.       bit_count = 0 ;
  367.     }
  368.   }
  369.   return ;
  370. }
  371.  
  372. //
  373. //  Description:
  374. //
  375. //    This function flushes the bit buffer. This causes buffered bit streams
  376. //    of less than the bit buffer size to be written out.
  377. //
  378. void JpegEncoder::FlushBitBuffer ()
  379. {
  380.   if (bit_count != 0)
  381.   {
  382.     bit_buffer <<= (8 - bit_count) ;
  383.     output_stream->write ((char *) &bit_buffer, 1) ;
  384.     bit_count = 0 ;
  385.   }
  386.   return ;
  387. }
  388.  
  389. //
  390. //  This function writes a marker to the output stream.
  391. //
  392. //  Parameters:
  393. //    marker: The marker to be written to the output stream
  394. //
  395. void JpegEncoder::OutputMarker (UBYTE1 marker)
  396. {
  397.   OutputByte (SOB) ;
  398.   OutputByte (marker) ;
  399.   return ;
  400. }
  401.  
  402. //
  403. //  Description:
  404. //
  405. //    This function validates the user-set output parameters. If an error is
  406. //    detected an EJpegBadOutputParameter exception is thrown.
  407. //
  408.  
  409. void JpegEncoder::ValidateParameters ()
  410. {
  411.   const int ALL = (1<<YComponent)|(1<<CbComponent)|(1<<CrComponent) ;
  412.   // Ensure we do not have fractional sampling of pixels.
  413.   if (! gray_scale)
  414.   {
  415.     if (image_components [YComponent].GetHorizontalFrequency () == 3
  416.         || image_components [CbComponent].GetHorizontalFrequency () == 3
  417.         || image_components [CrComponent].GetHorizontalFrequency () == 3)
  418.     {
  419.       if (image_components [YComponent].GetHorizontalFrequency () == 2
  420.           || image_components [YComponent].GetHorizontalFrequency () == 4
  421.           || image_components [CbComponent].GetHorizontalFrequency () == 2
  422.           || image_components [CbComponent].GetHorizontalFrequency () == 4
  423.           || image_components [CrComponent].GetHorizontalFrequency () == 2
  424.           || image_components [CrComponent].GetHorizontalFrequency () == 4)
  425.       {
  426.         throw EJpegError ("Fractional Horizontal Sampling") ;
  427.       }
  428.     }
  429.  
  430.     if (image_components [YComponent].GetVerticalFrequency () == 3
  431.         || image_components [CbComponent].GetVerticalFrequency () == 3
  432.         || image_components [CrComponent].GetVerticalFrequency () == 3)
  433.     {
  434.       if (image_components [YComponent].GetVerticalFrequency () == 2
  435.           || image_components [YComponent].GetVerticalFrequency () == 4
  436.           || image_components [CbComponent].GetVerticalFrequency () == 2
  437.           || image_components [CbComponent].GetVerticalFrequency () == 4
  438.           || image_components [CrComponent].GetVerticalFrequency () == 2
  439.           || image_components [CrComponent].GetVerticalFrequency () == 4)
  440.       {
  441.         throw EJpegError ("Fractional Vertical Sampling") ;
  442.       }
  443.     }
  444.   }
  445.  
  446.   if (progressive_mode)
  447.   {
  448.     // For a progressive scan the following rules apply
  449.     //
  450.     // o The spectral selection start can be zero if and only if
  451.     // the spectral selection end is zero.
  452.     //
  453.     // o For each component the zero spectral selection start must occur
  454.     // before any other.
  455.     //
  456.     // o If the spectral selection start is not zero there may only be
  457.     // one component in a scan.
  458.     //
  459.     // o The entire spectral range must be specified for each component.
  460.     //
  461.     // o There can be no overlapping spectral ranges in scans.
  462.     //
  463.     int lasty = -1 ;
  464.     int lastcb = -1 ;
  465.     int lastcr = -1 ;
  466.  
  467.     if (gray_scale)
  468.     {
  469.       // For a grayscale image the Cb and Cr components are not used.
  470.       lastcb = 63 ;
  471.       lastcr = 63 ;
  472.     }
  473.  
  474.     for (scan_count = 0 ; scan_count < MaxScans ; ++ scan_count)
  475.     {
  476.       if (lasty == 63 && lastcb == 63 && lastcr == 63)
  477.         break ;
  478.  
  479.       if (image_scans [scan_count].component_mask == 0)
  480.         throw EJpegError ("Scan contains no components") ;
  481.  
  482.       if (image_scans [scan_count].successive_approximation
  483.           > JpegMaxSuccessiveApproximation)
  484.       {
  485.         throw EJpegError ("Successive Approximation too large") ;
  486.       }
  487.         
  488.       image_scans [scan_count].successive_approximation_low =
  489.         image_scans [scan_count].successive_approximation ;
  490.       image_scans [scan_count].successive_approximation_high = 0 ;
  491.  
  492.       // Y Component Validation
  493.       if ((image_scans [scan_count].component_mask & (1<<YComponent)) != 0)
  494.       {
  495.         if (image_scans [scan_count].spectral_selection_end == 0)
  496.         {
  497.           if (lasty != -1)
  498.             throw EJpegError ("Duplicate Y Component Scan") ;
  499.  
  500.           image_scans [scan_count].spectral_selection_start = 0 ;
  501.           lasty = 0 ;
  502.         }
  503.         else
  504.         {
  505.           if (image_scans [scan_count].component_mask != (1<<YComponent))
  506.             throw EJpegError ("Multiple Components in AC Scan") ;
  507.  
  508.           if (image_scans [scan_count].spectral_selection_end != 0
  509.               && lasty == -1)
  510.           {
  511.             throw EJpegError (
  512.                      "AC Scan specified before DC scan for Y Component") ;
  513.           }
  514.  
  515.           if (image_scans [scan_count].spectral_selection_end <= lasty)
  516.             throw EJpegError ("Duplicate or overlapping spectral selection for Y Component") ;
  517.  
  518.           image_scans [scan_count].spectral_selection_start = lasty + 1 ;
  519.           lasty = image_scans [scan_count].spectral_selection_end ;
  520.         }
  521.       }
  522.  
  523.       if (! gray_scale)
  524.       {
  525.         // Cb Component Validation
  526.         if ((image_scans [scan_count].component_mask & (1<<CbComponent)) != 0)
  527.         {
  528.           if (image_scans [scan_count].spectral_selection_end == 0)
  529.           {
  530.             if (lastcb != -1)
  531.               throw EJpegError ("Duplicate Cb Component Scan") ;
  532.  
  533.             image_scans [scan_count].spectral_selection_start = 0 ;
  534.             lastcb = 0 ;
  535.           }
  536.           else
  537.           {
  538.             if (image_scans [scan_count].component_mask != (1<<CbComponent))
  539.               throw EJpegError ("Multiple Components in AC Scan") ;
  540.  
  541.             if (image_scans [scan_count].spectral_selection_end != 0 && lastcb == -1)
  542.               throw EJpegError ("AC Scan specified before DC scan for cb Component") ;
  543.  
  544.             if (image_scans [scan_count].spectral_selection_end <= lastcb)
  545.             {
  546.               throw EJpegError (
  547.               "Duplicate or overlapping spectral selection for Cb Component") ;
  548.             }
  549.  
  550.             image_scans [scan_count].spectral_selection_start = lastcb + 1 ;
  551.             lastcb = image_scans [scan_count].spectral_selection_end ;
  552.           }
  553.         }
  554.  
  555.         // Cr Component Validation
  556.         if ((image_scans [scan_count].component_mask & (1<<CrComponent)) != 0)
  557.         {
  558.           if (image_scans [scan_count].spectral_selection_end == 0)
  559.           {
  560.             if (lastcr != -1)
  561.               throw EJpegError ("Duplicate Cr Component Scan") ;
  562.  
  563.             image_scans [scan_count].spectral_selection_start = 0 ;
  564.             lastcr = 0 ;
  565.           }
  566.           else
  567.           {
  568.             if (image_scans [scan_count].component_mask != (1<<CrComponent))
  569.               throw EJpegError ("Multiple Components in AC Scan") ;
  570.  
  571.             if (image_scans [scan_count].spectral_selection_end != 0
  572.                 && lastcr== -1)
  573.             {
  574.               throw EJpegError (
  575.                       "AC Scan specified before DC scan for Cr Component") ;
  576.             }
  577.  
  578.             if (image_scans [scan_count].spectral_selection_end <= lastcr)
  579.             {
  580.               throw EJpegError (
  581.              "Duplicate or overlapping spectral selection for Cr Component") ;
  582.             }
  583.             image_scans [scan_count].spectral_selection_start = lastcr + 1 ;
  584.             lastcr = image_scans [scan_count].spectral_selection_end ;
  585.           }
  586.         }
  587.       }
  588.     }
  589.     if (lasty != 63)
  590.       throw EJpegError ("Y Component not completely defined by scans") ;
  591.     if (! gray_scale)
  592.     {
  593.       if (lastcb != 63)
  594.         throw EJpegError ("Cb Component not completely defined by scans") ;
  595.       if (lastcr != 63)
  596.         throw EJpegError ("Cr Component not completely defined by scans") ;
  597.     }
  598.   }
  599.   else
  600.   {
  601.     if (! gray_scale)
  602.     {
  603.       if ((image_scans [0].component_mask
  604.           |image_scans [1].component_mask
  605.           |image_scans [2].component_mask)
  606.           != ALL)
  607.       {
  608.         throw EJpegError ("Not all components specified in scans") ;
  609.       }
  610.       if ((image_scans [0].component_mask
  611.            +image_scans [1].component_mask
  612.            +image_scans [2].component_mask)
  613.           != ALL)
  614.       {
  615.         throw EJpegError ("Component in more than one scan") ;
  616.       }
  617.       if (image_scans [2].component_mask != 0)
  618.         scan_count = 3 ;
  619.       else if (image_scans [1].component_mask != 0)
  620.         scan_count = 2 ;
  621.       else
  622.         scan_count = 1 ;
  623.     }
  624.     else
  625.     {
  626.       scan_count = 1 ;
  627.     }
  628.   }
  629.  
  630.   // Enforce the MCU size limitation in Section B.2.3
  631.   //
  632.   // I am not certain why this limitation of 10 data units per MCU even
  633.   // exists. It seems to be an silly arbitrary limit. Maybe its to set
  634.   // a maximum upper size for an MCU decoding buffer. In any event we
  635.   // must abide by it.
  636.   if (! gray_scale)
  637.   {
  638.     for (unsigned int ii = 0 ; ii < scan_count ; ++ ii)
  639.     {
  640.       unsigned int dataunits = 0 ;
  641.       unsigned int componentcount = 0 ;
  642.       if ((image_scans [ii].component_mask & (1<<YComponent)) != 0)
  643.       {
  644.         dataunits += image_components [YComponent].GetHorizontalFrequency ()
  645.                      * image_components [YComponent].GetVerticalFrequency () ;
  646.         ++ componentcount ;
  647.       }
  648.       if ((image_scans [ii].component_mask & (1<<CbComponent)) != 0)
  649.       {
  650.         dataunits += image_components [CbComponent].GetHorizontalFrequency ()
  651.                   * image_components [CbComponent].GetVerticalFrequency () ;
  652.         ++ componentcount ;
  653.       }
  654.       if ((image_scans [ii].component_mask & (1<<CrComponent)) != 0)
  655.       {
  656.         dataunits += image_components [CrComponent].GetHorizontalFrequency ()
  657.                   * image_components [CrComponent].GetVerticalFrequency () ;
  658.         ++ componentcount ;
  659.       }
  660.       if (dataunits > JpegMaxDataUnitsPerMCU && componentcount > 1)
  661.         throw EJpegBadOutputParameter ("Data units in MCU exceeds 10") ;
  662.     }
  663.   }
  664.   return ;
  665. }
  666. //
  667. //  Description:
  668. //
  669. //    This function writes a comment marker to the output stream.
  670. //
  671. //  Parameters:
  672. //    str:  The comment string
  673. //
  674. void JpegEncoder::PrintComment (const std::string &str)
  675. {
  676.   unsigned int length = sizeof (UBYTE2) + str.length () + 1 ;
  677.   OutputMarker (COM) ;
  678.   OutputWord (length) ;
  679.   for (unsigned int ii = 0 ; ii < str.length () ; ++ ii)
  680.     OutputByte (str.c_str ()[ii]) ;
  681.  
  682.   OutputByte (0) ;
  683.   return ;
  684. }
  685.  
  686.  
  687. //
  688. //  Description:
  689. //
  690. //    This function writes the quantization tables to the output stream.
  691. //
  692. void JpegEncoder::PrintQuantizationTables ()
  693. {
  694.   // We need this declaration here because MSVC++ does not conform
  695.   // to standard scoping in for statements.
  696.   unsigned int ii ;
  697.  
  698.   const int precision = 0 ; // Byte Precision
  699.   int index ;
  700.   UBYTE1 pqtq ;
  701.  
  702.   // Section B.2.4.1
  703.  
  704.   if (gray_scale)
  705.   {
  706.     OutputMarker (DQT) ;
  707.     OutputWord (sizeof(UBYTE2) + (sizeof (pqtq) + JpegSampleSize)) ;
  708.  
  709.     index = 0 ;
  710.     pqtq = (precision << 4) | index ;
  711.     OutputByte (pqtq) ;
  712.     for (ii = 0 ; ii < JpegSampleSize ; ++ ii)
  713.       OutputByte ((*luminance_quanttbl) [ii]) ;
  714.   }
  715.   else
  716.   {
  717.     OutputMarker (DQT) ;
  718.     OutputWord (sizeof(UBYTE2) + 2 * (sizeof (pqtq) + JpegSampleSize)) ;
  719.  
  720.     index = 0 ;
  721.     pqtq = (precision << 4) | index ;
  722.     OutputByte (pqtq) ;
  723.     for (ii = 0 ; ii < JpegSampleSize ; ++ ii)
  724.       OutputByte ((*luminance_quanttbl) [ii]) ;
  725.  
  726.     index = 1 ;
  727.     pqtq = (precision << 4) | index ;
  728.     OutputByte (pqtq) ;
  729.     for (ii = 0 ; ii < JpegSampleSize ; ++ ii)
  730.       OutputByte ((*chrominance_quanttbl) [ii]) ;
  731.   }
  732.   return ;
  733. }
  734.  
  735. //
  736. //  Description:
  737. //
  738. //    This function is called by a scan to write a restart interval to the
  739. //    output stream. We do not output a Define Restart Interval marker if
  740. //    the restart interval is not changing.
  741. //
  742. //  Parameters:
  743. //    restartinterval: The new restart interval
  744. //
  745. void JpegEncoder::OutputRestartInterval (unsigned int restartinterval)
  746. {
  747.   if (restartinterval == restart_interval)
  748.     return ;
  749.   restart_interval =  restartinterval ;
  750.  
  751.   // B.2.4.4
  752.   OutputMarker (DRI) ;
  753.   OutputWord (4) ;
  754.   OutputWord (restartinterval) ;
  755.   return ;
  756. }
  757.  
  758.  
  759. //
  760. //  Description:
  761. //
  762. //    This function writes a sequential frame to the output stream. We create
  763. //    frames with either one (black & white) or three (color) components.
  764. //
  765. //  Parameters:
  766. //    image: The image to be written in the frame
  767. //
  768. void JpegEncoder::PrintSequentialFrame (BitmapImage &image)
  769. {
  770.   // Sample the components
  771.   if (gray_scale)
  772.   {
  773.     ++ current_pass ;
  774.     image_components [YComponent].SampleYComponent (
  775.                                      *this,
  776.                                      image,
  777.                                      max_horizontal_frequency,
  778.                                      max_vertical_frequency) ;
  779.   }
  780.   else
  781.   {
  782.     ++ current_pass ;
  783.     image_components [YComponent].SampleYComponent (*this,
  784.                                                     image,
  785.                                                     max_horizontal_frequency,
  786.                                                     max_vertical_frequency) ;
  787.     ++ current_pass ;
  788.     image_components [CbComponent].SampleCbComponent (
  789.                                            *this,
  790.                                            image,
  791.                                            max_horizontal_frequency,
  792.                                            max_vertical_frequency) ;
  793.     ++ current_pass ;
  794.     image_components [CrComponent].SampleCrComponent (
  795.                                            *this,
  796.                                            image,
  797.                                            max_horizontal_frequency,
  798.                                            max_vertical_frequency) ;
  799.   }
  800.  
  801.   // Write the Frame Header
  802.   // Section B.2.2
  803.  
  804.   OutputMarker (SOF0) ;
  805.   if (gray_scale)  // Length
  806.     OutputWord (8 + 3) ;
  807.   else
  808.     OutputWord (8 + 3 * 3) ;
  809.  
  810.   OutputByte (8) ; // Precision
  811.   OutputWord (image.Height ()) ;
  812.   OutputWord (image.Width ()) ;
  813.  
  814.   if (gray_scale)
  815.   {
  816.     OutputByte (1) ;  // Component Count
  817.     OutputByte(YComponent) ;
  818.     OutputByte (
  819.         (image_components [YComponent].GetHorizontalFrequency () << 4)
  820.         | image_components [YComponent].GetVerticalFrequency ()) ;
  821.     OutputByte (0) ;  // Quantization Table
  822.  
  823.  
  824.     PrintQuantizationTables () ;
  825.     scan_component_count = 1 ;
  826.     scan_components [0] = &image_components [YComponent] ;
  827.     ++ current_pass ;
  828.     PrintSequentialScan (image_scans [0]) ;
  829.   }
  830.   else
  831.   {
  832.     OutputByte (3) ;  // Component Count
  833.     OutputByte(YComponent) ;
  834.     OutputByte (
  835.         (image_components [YComponent].GetHorizontalFrequency () << 4)
  836.         | image_components [YComponent].GetVerticalFrequency ()) ;
  837.     OutputByte (0) ;  // Quantization Table
  838.  
  839.     OutputByte(CbComponent) ;
  840.     OutputByte (
  841.         (image_components [CbComponent].GetHorizontalFrequency () << 4)
  842.         | image_components [CbComponent].GetVerticalFrequency ()) ;
  843.     OutputByte (1) ;  // Quantization Table
  844.  
  845.     OutputByte(CrComponent) ;
  846.     OutputByte (
  847.         (image_components [CrComponent].GetHorizontalFrequency () << 4)
  848.         | image_components [CrComponent].GetVerticalFrequency ()) ;
  849.     OutputByte (1) ;  // Quantization Table
  850.  
  851.     PrintQuantizationTables () ;
  852.  
  853.     // Print the scans that make up the frame.
  854.     for (unsigned int ii = 0 ; ii < scan_count ; ++ ii)
  855.     {
  856.       ++ current_pass ;
  857.       if (image_scans [ii].component_mask != 0)
  858.       {
  859.         FindComponentsInScan (image_scans [ii]) ;
  860.         PrintSequentialScan (image_scans [ii]) ;
  861.       }
  862.     }
  863.   }
  864.  
  865.   return ;
  866. }
  867.  
  868. //
  869. //  Description:
  870. //
  871. //    This function writes a progressive frame to the output stream.
  872. //
  873. //  Parameters:
  874. //    image: The image to be written in the frame
  875. //
  876. void JpegEncoder::PrintProgressiveFrame (BitmapImage &image)
  877. {
  878.   if (gray_scale)
  879.   {
  880.     ++ current_pass ;
  881.     image_components [YComponent].SampleYComponent (*this,
  882.                                                     image,
  883.                                                     max_horizontal_frequency,
  884.                                                     max_vertical_frequency) ;
  885.  
  886.     // Output JPEG SOF Marker
  887.     // Section B.2.2
  888.     OutputMarker (SOF2) ;
  889.     OutputWord (8 + 3) ;
  890.  
  891.     OutputByte (8) ; // Precision
  892.     OutputWord (image.Height ()) ;
  893.     OutputWord (image.Width ()) ;
  894.  
  895.     OutputByte (1) ;  // Component Count
  896.     OutputByte(YComponent) ;
  897.     OutputByte (
  898.         (image_components [YComponent].GetHorizontalFrequency () << 4)
  899.         | image_components [YComponent].GetVerticalFrequency ()) ;
  900.     OutputByte (0) ;  // Quantization Table
  901.  
  902.     PrintQuantizationTables () ;
  903.  
  904.     scan_component_count = 1 ;
  905.     scan_components [0] = &image_components [YComponent] ;
  906.  
  907.     bool doingwork ;
  908.     do
  909.     {
  910.       doingwork = false ;
  911.       for (unsigned int ii = 0 ; ii < scan_count ; ++ ii)
  912.       {
  913.         if ((image_scans [ii].component_mask & (1<<YComponent)) != 0
  914.              && image_scans [ii].successive_approximation_low >= 0)
  915.         {
  916.           ++ current_pass ;
  917.           PrintProgressiveScan (image_scans [ii]) ;
  918.           doingwork = true ;
  919.           image_scans [ii].successive_approximation_high
  920.             = image_scans [ii].successive_approximation_low ;
  921.           -- image_scans [ii].successive_approximation_low ;
  922.         }
  923.       }
  924.     } while (doingwork) ;
  925.   }
  926.   else
  927.   {
  928.     ++ current_pass ;
  929.     image_components [YComponent].SampleYComponent (*this,
  930.                                                     image,
  931.                                                     max_horizontal_frequency,
  932.                                                     max_vertical_frequency) ;
  933.     ++ current_pass ;
  934.     image_components [CbComponent].SampleCbComponent (
  935.                                         *this,
  936.                                         image,
  937.                                         max_horizontal_frequency,
  938.                                         max_vertical_frequency) ;
  939.     ++ current_pass ;
  940.     image_components [CrComponent].SampleCrComponent (
  941.                                         *this,
  942.                                         image,
  943.                                         max_horizontal_frequency,
  944.                                         max_vertical_frequency) ;
  945.  
  946.     // Output JPEG SOS Marker
  947.     // Section B.2.2
  948.     OutputMarker (SOF2) ;
  949.     OutputWord (8 + 3 * 3) ;
  950.  
  951.     OutputByte (8) ; // Precision
  952.     OutputWord (image.Height ()) ;
  953.     OutputWord (image.Width ()) ;
  954.  
  955.     OutputByte (3) ;  // Component Count
  956.     OutputByte(YComponent) ;
  957.     OutputByte (
  958.         (image_components [YComponent].GetHorizontalFrequency () << 4)
  959.         | image_components [YComponent].GetVerticalFrequency ()) ;
  960.     OutputByte (0) ;  // Quantization Table
  961.  
  962.     OutputByte(CbComponent) ;
  963.     OutputByte (
  964.         (image_components [CbComponent].GetHorizontalFrequency () << 4)
  965.          | image_components [CbComponent].GetVerticalFrequency ()) ;
  966.     OutputByte (1) ;  // Quantization Table
  967.  
  968.     OutputByte(CrComponent) ;
  969.     OutputByte (
  970.         (image_components [CrComponent].GetHorizontalFrequency () << 4)
  971.          | image_components [CrComponent].GetVerticalFrequency ()) ;
  972.     OutputByte (1) ;  // Quantization Table
  973.  
  974.     PrintQuantizationTables () ;
  975.  
  976.     // Because of successive approximation we may have to go through the
  977.     // scan list several times. This flag gets set each time a scan
  978.     // is processed. The first time we search the scan list and do
  979.     // nothing this flag will be false and we are all done.
  980.     bool doingwork ;
  981.     do
  982.     {
  983.       doingwork = false ;
  984.       for (unsigned int ii = 0 ; ii < scan_count ; ++ ii)
  985.       {
  986.         FindComponentsInScan (image_scans [ii]) ;
  987.  
  988.         if (scan_component_count != 0
  989.             && image_scans [ii].successive_approximation_low >= 0)
  990.         {
  991.           ++ current_pass ;
  992.           PrintProgressiveScan (image_scans [ii]) ;
  993.           doingwork = true ;
  994.           image_scans [ii].successive_approximation_high
  995.             = image_scans [ii].successive_approximation_low ;
  996.           -- image_scans [ii].successive_approximation_low ;
  997.         }
  998.       }
  999.     } while (doingwork) ;
  1000.  
  1001.   }
  1002.   return ;
  1003. }
  1004.  
  1005.  
  1006. //
  1007. //  Description:
  1008. //
  1009. //    This function enables or disables progressive output. When the mode is
  1010. //    changed the image_scans is initialized with a default set of values for
  1011. //    the new mode.
  1012. //
  1013. //  Parameters:
  1014. //    value: (true=>Progressive Mode, false=>Sequential Mode)
  1015. //
  1016. void JpegEncoder::SetProgressive (bool value)
  1017. {
  1018.   if (value == progressive_mode)
  1019.     return ;
  1020.  
  1021.   progressive_mode = value ;
  1022.   memset (image_scans, 0, sizeof (image_scans)) ;
  1023.   if (progressive_mode)
  1024.   {
  1025.     // For Progressive Scans our default is four scans.  The first
  1026.     // contains the DC coefficients for all three components. The next
  1027.     // three scans contain the AC coefficients for each component.
  1028.  
  1029.     image_scans [0].component_mask = (1<<YComponent)
  1030.                                     |(1<<CbComponent)
  1031.                                     |(1<<CrComponent) ;
  1032.     image_scans [1].component_mask = (1<<YComponent) ;
  1033.     image_scans [1].spectral_selection_end = 63 ;
  1034.     image_scans [2].component_mask = (1<<CbComponent) ;
  1035.     image_scans [2].spectral_selection_end = 63 ;
  1036.     image_scans [3].component_mask = (1<<CrComponent) ;
  1037.     image_scans [3].spectral_selection_end = 63 ;
  1038.   }
  1039.   else
  1040.   {
  1041.     // For sequential mode the default is to create one scan with
  1042.     // all components.
  1043.     image_scans [0].component_mask = (1<<YComponent)
  1044.                                    |(1<<CbComponent)
  1045.                                    |(1<<CrComponent) ;
  1046.   }
  1047.   return ;
  1048. }
  1049.  
  1050. //
  1051. //  Description:
  1052. //
  1053. //    This function writes a sequential scan to the output stream.
  1054. //
  1055. //  Parameters:
  1056. //    scan:   The scan descriptor
  1057. //
  1058. void JpegEncoder::PrintSequentialScan (const Scan &scan)
  1059. {
  1060.   if (scan_component_count == 0)
  1061.     throw EJpegFatal ("INTERNAL ERROR - No components defined for scan") ;
  1062.  
  1063.   // Output the restart interval and the Huffman tables. We must set the
  1064.   // restart interval *BEFORE* gathering statistics.
  1065.   if (scan_component_count != 1)
  1066.   {
  1067.     OutputRestartInterval (rows_per_restart * mcu_cols) ;
  1068.   }
  1069.   else
  1070.   {
  1071.     OutputRestartInterval (rows_per_restart
  1072.       * scan_components [0]->DataUnitCols ()) ;
  1073.   }
  1074.  
  1075.   // Gather Huffman Statistics
  1076.   if ((scan.component_mask & (1<<YComponent)) != 0)
  1077.   {
  1078.     dc_tables [0].Reset () ;
  1079.     ac_tables [0].Reset () ;
  1080.   }
  1081.   if ((scan.component_mask & (1<<YComponent)) == 0
  1082.       || scan_component_count != 1)
  1083.   {
  1084.     ac_tables [1].Reset () ;
  1085.     dc_tables [1].Reset () ;
  1086.   }
  1087.  
  1088.  
  1089.   if (scan_component_count != 1)
  1090.   {
  1091.     InterleavedPass (false,
  1092.           &JpegEncoderComponent::EncodeSequential,
  1093.           &JpegEncoderComponent::GatherDcData,
  1094.           &JpegEncoderComponent::GatherAcData,
  1095.           0, JpegSampleSize - 1, 0) ;
  1096.   }
  1097.   else
  1098.   {
  1099.     NoninterleavedPass (false,
  1100.           &JpegEncoderComponent::EncodeSequential,
  1101.           &JpegEncoderComponent::GatherDcData,
  1102.           &JpegEncoderComponent::GatherAcData,
  1103.           0, JpegSampleSize - 1, 0) ;
  1104.   }
  1105.  
  1106.   // Create the Huffman Tables
  1107.   if ((scan.component_mask & (1<<YComponent)) != 0)
  1108.   {
  1109.     dc_tables [0].BuildTable () ;
  1110.     ac_tables [0].BuildTable () ;
  1111.   }
  1112.   if ((scan.component_mask & (1<<YComponent)) == 0
  1113.        || scan_component_count != 1)
  1114.   {
  1115.     ac_tables [1].BuildTable () ;
  1116.     dc_tables [1].BuildTable () ;
  1117.   }
  1118.  
  1119.   // Output the Huffman tables
  1120.   PrintHuffmanTables (scan, true, true) ; // Output DC and AC tables.
  1121.  
  1122.   // Create the scan marker.
  1123.   // Section B.2.3
  1124.   OutputMarker (SOS) ;
  1125.   OutputWord (6 + 2 * scan_component_count) ;  // Length
  1126.   OutputByte (scan_component_count) ;  // Component Count
  1127.  
  1128.   if ((scan.component_mask & (1<<YComponent)) != 0)
  1129.   {
  1130.     OutputByte (0x01) ; // YComponent
  1131.     OutputByte (0x00) ; // Entropy Tables
  1132.   }
  1133.   if (! gray_scale)
  1134.   {
  1135.     if ((scan.component_mask & (1<<CbComponent)) != 0)
  1136.     {
  1137.       OutputByte (0x02) ; // CbComponent
  1138.       OutputByte (0x11) ; // Entropy Tables
  1139.     }
  1140.     if ((scan.component_mask & (1<<CrComponent)) != 0)
  1141.     {
  1142.       OutputByte (0x03) ; // CrComponent
  1143.       OutputByte (0x11) ; // Entropy Tables
  1144.     }
  1145.   }
  1146.  
  1147.   OutputByte (0) ; // Spectral Selection Start
  1148.   OutputByte (JpegSampleSize - 1) ; // Spectral Selection End
  1149.   OutputByte (0) ; // Successive Approximation
  1150.  
  1151.   // Output the Scan data.
  1152.   if (scan_component_count != 1)
  1153.   {
  1154.     InterleavedPass (true,
  1155.           &JpegEncoderComponent::EncodeSequential,
  1156.           &JpegEncoderComponent::PrintDcData,
  1157.           &JpegEncoderComponent::PrintAcData,
  1158.           0, JpegSampleSize - 1, 0) ;
  1159.   }
  1160.   else
  1161.   {
  1162.     NoninterleavedPass (true,
  1163.           &JpegEncoderComponent::EncodeSequential,
  1164.           &JpegEncoderComponent::PrintDcData,
  1165.           &JpegEncoderComponent::PrintAcData,
  1166.           0, JpegSampleSize - 1, 0) ;
  1167.   }
  1168.  
  1169.   return ;
  1170. }
  1171.  
  1172. //
  1173. //  Description:
  1174. //
  1175. //    This function makes a pass through the data units for a non-interleaved
  1176. //    Scan.
  1177. //
  1178. //    The reason for having a generic function that uses pointers to member
  1179. //    functions to do processing is that there are several places where the
  1180. //    control processing has to be identical in multiple passes where the
  1181. //    low level actions are different. For example, the processing here when
  1182. //    gathering Huffman statistics has to be identical to the processing when
  1183. //    writing values to the output file. Using separate functions turned out
  1184. //    to be error prone due to the difficulty of keeping multiple functions
  1185. //    exactly in synchronization.
  1186. //
  1187. //  Parameters:
  1188. //    writerestarts: false => This is a statistics gathering pass
  1189. //                   true => This pass is writing data to the output file.
  1190. //    passfunctions: Pointer to EncoderComponent member function used
  1191. //                   to process this pass.
  1192. //    dcfunction:    Pointer to the EncoderComponent member function used
  1193. //                   to process DC coefficient values.
  1194. //    acfunction:    Pointer to the EncoderComponent member function used
  1195. //                   to process AC coefficient values.
  1196. //    sss:           Spectral Selection Start (0-63)
  1197. //    sse:           Spectral Selection End (0-63)
  1198. //    ssa:           Successive Approximation (0-13)
  1199. //
  1200. void JpegEncoder::NoninterleavedPass (
  1201.                     bool writedata,
  1202.                     JpegEncoderComponent::COMPONENTPASSFUNCTION passfunction,
  1203.                     JpegEncoderComponent::DCOUTPUTFUNCTION dcfunction,
  1204.                     JpegEncoderComponent::ACOUTPUTFUNCTION acfunction,
  1205.                     unsigned int sss,
  1206.                     unsigned int sse,
  1207.                     unsigned int ssa)
  1208. {
  1209.   // We use a scale integer to keep trake of progress to lessen the
  1210.   // change that the progress increment will be zero.
  1211.   const int progressscale = 8 ;
  1212.   unsigned int progress ;
  1213.   unsigned int progressincrement ;
  1214.   if (writedata)
  1215.     progress = 50 << progressscale ;
  1216.   else
  1217.     progress = 0 ;
  1218.   progressincrement = (100 << progressscale)
  1219.                     / (2 * scan_components [0]->DataUnitRows ()) ;
  1220.  
  1221.   ResetDcValues () ;
  1222.  
  1223.   unsigned int intervalcount = 0 ;
  1224.   unsigned int restartmarker = 0 ;
  1225.   for (unsigned int row = 0 ;
  1226.        row < scan_components [0]->DataUnitRows () ;
  1227.        ++ row)
  1228.   {
  1229.     for (unsigned int col = 0 ;
  1230.          col < scan_components [0]->DataUnitCols () ;
  1231.          ++ col, ++ intervalcount)
  1232.     {
  1233.       if (restart_interval != 0)
  1234.       {
  1235.         if (intervalcount == restart_interval && restart_interval != 0)
  1236.         {
  1237.           // If there are any outstanding EOB runs we flush them before the
  1238.           // restart marker. This is not explicitly stated in the JPEG
  1239.           // standard. The definition of "Restart Interval" in section 4.1
  1240.           // states that restart markers separate independent sequences,
  1241.           // something we would not have if we did not output the EOB run
  1242.           // here.
  1243.           scan_components [0]->PrintEobRun (acfunction) ;
  1244.           // E.1.4
  1245.           if (writedata)
  1246.             OutputMarker (RST0 | restartmarker) ;
  1247.           ResetDcValues () ;
  1248.           ++ restartmarker ;
  1249.           restartmarker %= 8 ;
  1250.           intervalcount = 0 ;
  1251.         }
  1252.       }
  1253.       (scan_components [0]->*passfunction) (
  1254.                                 row,
  1255.                                 col,
  1256.                                 dcfunction,
  1257.                                 acfunction,
  1258.                                 sss, sse,
  1259.                                 ssa) ;
  1260.  
  1261.     }
  1262.     progress += progressincrement ;
  1263.     CallProgressFunction (progress >> progressscale) ;
  1264.   }
  1265.   CallProgressFunction (100) ;
  1266.   return ;
  1267. }
  1268.  
  1269. //
  1270. //  Description:
  1271. //
  1272. //    This function makes a pass through the data units for an interleaved
  1273. //    Scan.
  1274. //
  1275. //    The reason for having a generic function that uses pointers to member
  1276. //    functions to do processing is that there are several places where the
  1277. //    control processing has to be identical in multiple passes where the
  1278. //    low level actions are different. For example, the processing here when
  1279. //    gathering Huffman statistics has to be identical to the processing when
  1280. //    writing values to the output file. Using separate functions turned out
  1281. //    to be error prone due to the difficulty of keeping multiple functions
  1282. //    exactly in synchronization.
  1283. //
  1284. //  Parameters:
  1285. //     writerestarts: false => This is a statistics gathering pass
  1286. //                    true => This pass is writing data to the output file.
  1287. //     passfunctions: Pointer to EncoderComponent member function used
  1288. //                    to process this pass.
  1289. //     dcfunction:    Pointer to the EncoderComponent member function used
  1290. //                    to process DC coefficient values.
  1291. //     acfunction:    Pointer to the EncoderComponent member function used
  1292. //                    to process AC coefficient values.
  1293. //     sss:           Spectral Selection Start (0-63)
  1294. //     sse:           Spectral Selection End (0-63)
  1295. //     ssa:           Successive Approximation (0-13)
  1296. //
  1297. void JpegEncoder::InterleavedPass (
  1298.                     bool writedata,
  1299.                     JpegEncoderComponent::COMPONENTPASSFUNCTION passfunction,
  1300.                     JpegEncoderComponent::DCOUTPUTFUNCTION dcfunction,
  1301.                     JpegEncoderComponent::ACOUTPUTFUNCTION acfunction,
  1302.                     unsigned int sss,
  1303.                     unsigned int sse,
  1304.                     unsigned int ssa)
  1305. {
  1306.   const int progressscale = 8 ;
  1307.   unsigned int progress ;
  1308.   unsigned int progressincrement ;
  1309.   if (writedata)
  1310.     progress = 50 << progressscale ;
  1311.   else
  1312.     progress = 0 ;
  1313.   progressincrement = (100 << progressscale) / (2 * mcu_rows) ;
  1314.  
  1315.   ResetDcValues () ;
  1316.  
  1317.   unsigned int intervalcount = 0 ;
  1318.   unsigned int restartmarker = 0 ;
  1319.   for (unsigned int mcurow = 0 ;
  1320.        mcurow < mcu_rows ;
  1321.        ++ mcurow)
  1322.   {
  1323.     for (unsigned int mcucol = 0 ;
  1324.          mcucol < mcu_cols ;
  1325.           ++ mcucol, ++ intervalcount)
  1326.     {
  1327.       // Handle Restart Markers
  1328.       if (restart_interval != 0)
  1329.       {
  1330.         if (intervalcount == restart_interval && restart_interval != 0)
  1331.         {
  1332.           if (writedata)
  1333.             OutputMarker (RST0 | restartmarker) ;
  1334.           ResetDcValues () ;
  1335.           ++ restartmarker ;
  1336.           restartmarker %= 8 ;
  1337.           intervalcount = 0 ;
  1338.         }
  1339.       }
  1340.  
  1341.       for (unsigned int cc = 0 ; cc < scan_component_count ; ++ cc)
  1342.       {
  1343.         for (unsigned int cy = 0 ;
  1344.              cy < scan_components [cc]->GetVerticalFrequency () ;
  1345.              ++ cy)
  1346.         {
  1347.           unsigned int durow = scan_components [cc]->GetVerticalFrequency ()
  1348.                              * mcurow + cy ;
  1349.           for (unsigned int cx = 0 ;
  1350.                cx < scan_components [cc]->GetHorizontalFrequency () ;
  1351.                ++ cx)
  1352.           {
  1353.             unsigned int ducol
  1354.               = scan_components [cc]->GetHorizontalFrequency ()
  1355.               * mcucol + cx ;
  1356.             (scan_components [cc]->*passfunction) (durow, ducol,
  1357.                                               dcfunction, acfunction,
  1358.                                               sss, sse, ssa) ;
  1359.           }
  1360.         }
  1361.       }
  1362.     }
  1363.     progress += progressincrement ;
  1364.     CallProgressFunction (progress >> progressscale) ;
  1365.   }
  1366.   CallProgressFunction (100) ;
  1367.   return ;
  1368. }
  1369.  
  1370. //
  1371. //  Description:
  1372. //
  1373. //    This function writes the Huffman tables used by a scan to the output
  1374. //    stream.
  1375. //
  1376. //    We only use two DC and two AC tables to be compatible with baseline
  1377. //    JPEG.  In progressive JPEG there is really no reason for more than
  1378. //    two tables for RGB images. If we ever go to four colors then things
  1379. //    may need to change.
  1380. //
  1381. //    The Y component always uses table ID 0. The Cb and Cr components always
  1382. //    use table ID 1.
  1383. //
  1384. //  Parameters:
  1385. //    scan:     Here the scan structure is used to determine which components
  1386. //              are part of the scan (Y and/or Cb/Cr)
  1387. //    usedc:    Set to true if the scan includes DC components. (Sequential
  1388. //              Scan or Progressive Scan with the spectral selection 0)
  1389. //    useac:    Set to true if the scan includes AC components. (Sequential
  1390. //              Scan or Progressive Scan with the spectral selection start
  1391. //              not zero)
  1392. //
  1393. void JpegEncoder::PrintHuffmanTables (const Scan &scan,
  1394.                                       bool usedc,
  1395.                                       bool useac)
  1396. {
  1397.   // Section B.2.4.2
  1398.  
  1399.   if ((scan.component_mask & (1 << YComponent)) != 0)
  1400.   {
  1401.     // See if this is a color image.
  1402.     if (scan_component_count != 1)
  1403.     {
  1404.       // We have at least two components and the first is the Y component.
  1405.       // This means we need the both of the huffman tables.
  1406.       // B.2.4.2
  1407.       OutputMarker (DHT) ;
  1408.       unsigned int size = sizeof (UBYTE2) ;
  1409.       if (usedc)
  1410.       {
  1411.         size += dc_tables [0].OutputSize ()
  1412.                 + dc_tables [1].OutputSize () ;
  1413.       }
  1414.       if (useac)
  1415.       {
  1416.         size += ac_tables [0].OutputSize ()
  1417.                 + ac_tables [1].OutputSize () ;
  1418.       }
  1419.       OutputWord (size) ;
  1420.       if (usedc)
  1421.       {
  1422.         OutputByte (0x00) ;
  1423.         dc_tables [0].PrintTable (*this) ;
  1424.       }
  1425.       if (useac)
  1426.       {
  1427.         OutputByte (0x10) ;
  1428.         ac_tables [0].PrintTable (*this) ;
  1429.       }
  1430.       if (usedc)
  1431.       {
  1432.         OutputByte (0x01) ;
  1433.         dc_tables [1].PrintTable (*this) ;
  1434.       }
  1435.       if (useac)
  1436.       {
  1437.         OutputByte (0x11) ;
  1438.         ac_tables [1].PrintTable (*this) ;
  1439.       }
  1440.     }
  1441.     else
  1442.     {
  1443.       // The only component is Y
  1444.       unsigned int size = sizeof (UBYTE2) ;
  1445.       if (usedc)
  1446.       {
  1447.         size += dc_tables [0].OutputSize () ;
  1448.       }
  1449.       if (useac)
  1450.       {
  1451.         size += ac_tables [0].OutputSize () ;
  1452.       }
  1453.  
  1454.       OutputMarker (DHT) ;
  1455.       OutputWord (size) ;
  1456.       if (usedc)
  1457.       {
  1458.         OutputByte (0x00) ;
  1459.         dc_tables [0].PrintTable (*this) ;
  1460.       }
  1461.       if (useac)
  1462.       {
  1463.         OutputByte (0x10) ;
  1464.         ac_tables [0].PrintTable (*this) ;
  1465.       }
  1466.     }
  1467.   }
  1468.   else
  1469.   {
  1470.     // The Y component is not present. Output is the same for
  1471.     // Cb, Cr, or Cb & Cr.
  1472.     unsigned int size = sizeof (UBYTE2) ;
  1473.     if (usedc)
  1474.     {
  1475.       size += dc_tables [1].OutputSize () ;
  1476.     }
  1477.     if (useac)
  1478.     {
  1479.       size += ac_tables [1].OutputSize () ;
  1480.     }
  1481.  
  1482.     OutputMarker (DHT) ;
  1483.     OutputWord (size) ;
  1484.     if (usedc)
  1485.     {
  1486.       OutputByte (0x01) ;
  1487.       dc_tables [1].PrintTable (*this) ;
  1488.     }
  1489.     if (useac)
  1490.     {
  1491.       OutputByte (0x11) ;
  1492.       ac_tables [1].PrintTable (*this) ;
  1493.     }
  1494.   }
  1495.   return ;
  1496. }
  1497.  
  1498. //
  1499. //  Description:
  1500. //
  1501. //   This function resets the DC difference values for all
  1502. //   all the components in the scan.  We do this at the start of
  1503. //   each scan and whenever we output a restart marker.
  1504. //
  1505. void JpegEncoder::ResetDcValues ()
  1506. {
  1507.   for (unsigned int ii = 0 ; ii < scan_component_count ; ++ ii)
  1508.     scan_components [ii]->ResetDcDifference () ;
  1509.   return ;
  1510. }
  1511.  
  1512. //
  1513. //  Description:
  1514. //
  1515. //    This function determines the dimensions of an MCU using the maximum
  1516. //    sampling frequencies of the components.
  1517. //
  1518. void JpegEncoder::CalculateMcuDimensions ()
  1519. {
  1520.   max_horizontal_frequency = 1 ;
  1521.   max_vertical_frequency = 1 ;
  1522.  
  1523.   if (! gray_scale)
  1524.   {
  1525.     for (unsigned int ii = YComponent ; ii <= CrComponent ; ++ ii)
  1526.     {
  1527.       if (image_components [ii].GetHorizontalFrequency ()
  1528.           > max_horizontal_frequency)
  1529.       {
  1530.         max_horizontal_frequency
  1531.           = image_components [ii].GetHorizontalFrequency () ;
  1532.       }
  1533.  
  1534.       if (image_components [ii].GetVerticalFrequency ()
  1535.           > max_vertical_frequency)
  1536.       {
  1537.         max_vertical_frequency
  1538.           = image_components [ii].GetVerticalFrequency () ;
  1539.       }
  1540.     }
  1541.   }
  1542.   else
  1543.   {
  1544.     max_horizontal_frequency
  1545.       = image_components [YComponent].GetHorizontalFrequency () ;
  1546.     max_vertical_frequency
  1547.       = image_components [YComponent].GetVerticalFrequency () ;
  1548.   }
  1549.  
  1550.   unsigned int mcuheight = max_vertical_frequency * JpegSampleWidth ;
  1551.   unsigned int mcuwidth = max_horizontal_frequency * JpegSampleWidth ;
  1552.   mcu_rows = (frame_height + mcuheight - 1) / mcuheight ;
  1553.   mcu_cols = (frame_width + mcuwidth - 1) / mcuwidth ;
  1554.   return ;
  1555. }
  1556.  
  1557. //
  1558. //  Description:
  1559. //
  1560. //    This function writes a progressive scan to the output stream.
  1561. //
  1562. //  Parameters:
  1563. //    scan:  The structure that contains the scan parameters.
  1564. //
  1565. void JpegEncoder::PrintProgressiveScan (const Scan &scan)
  1566. {
  1567.   if (scan_component_count == 0)
  1568.     throw EJpegFatal ("INTERNAL ERROR - No components in progressive scan") ;
  1569.  
  1570.   if (scan.spectral_selection_start == 0)
  1571.   {
  1572.     if (scan.successive_approximation_high == 0)
  1573.     {
  1574.       PrintDcFirst (scan) ;
  1575.     }
  1576.     else
  1577.     {
  1578.       PrintDcRefine (scan) ;
  1579.     }
  1580.   }
  1581.   else
  1582.   {
  1583.     if (scan_component_count != 1)
  1584.       throw EJpegFatal ("INTERNAL ERROR - AC Scan does not have 1 component") ;
  1585.  
  1586.     if (scan.successive_approximation_high == 0)
  1587.     {
  1588.       PrintAcFirst (scan) ;
  1589.     }
  1590.     else
  1591.     {
  1592.       PrintAcRefine (scan) ;
  1593.     }
  1594.   }
  1595.   return ;
  1596. }
  1597.  
  1598. //
  1599. //  Description:
  1600. //
  1601. //    This function handles scans containing the first pass for DC
  1602. //    coefficients.  If successive approximation is not used then
  1603. //    this would be the only DC coefficient pass. DC progressive
  1604. //    scans may be interleaved, unlike AC scans.
  1605. //
  1606. //  Parameters:
  1607. //    scan:  The structure that contains the scan parameters.
  1608. //
  1609. void JpegEncoder::PrintDcFirst (const Scan &scan)
  1610. {
  1611.   // Reset the Huffman statistics counters.
  1612.   if ((scan.component_mask & (1 << YComponent)) != 0)
  1613.   {
  1614.     dc_tables [0].Reset () ;
  1615.   }
  1616.   if ((scan.component_mask & (1 << YComponent)) == 0
  1617.        || scan_component_count > 1)
  1618.   {
  1619.     dc_tables [1].Reset () ;
  1620.   }
  1621.  
  1622.   OutputRestartInterval (restart_interval) ;
  1623.  
  1624.   // Gather the Huffman statistics
  1625.   if (scan_component_count != 1)
  1626.   {
  1627.     InterleavedPass (false,
  1628.           &JpegEncoderComponent::ProgressiveDcFirst,
  1629.           &JpegEncoderComponent::GatherDcData, NULL,
  1630.           0, 0,
  1631.           scan.successive_approximation_low) ;
  1632.   }
  1633.   else
  1634.   {
  1635.     NoninterleavedPass (false,
  1636.           &JpegEncoderComponent::ProgressiveDcFirst,
  1637.           &JpegEncoderComponent::GatherDcData, NULL,
  1638.           0, 0,
  1639.           scan.successive_approximation_low) ;
  1640.   }
  1641.  
  1642.   // Create the Huffman tables from the statistics
  1643.   if ((scan.component_mask & (1 << YComponent)) != 0)
  1644.   {
  1645.     dc_tables [0].BuildTable () ;
  1646.   }
  1647.   if ((scan.component_mask & (1 << YComponent)) == 0
  1648.       || scan_component_count > 1)
  1649.   {
  1650.     dc_tables [1].BuildTable () ;
  1651.   }
  1652.  
  1653.   PrintHuffmanTables (scan, true, false) ;
  1654.  
  1655.   // Output the scan header.
  1656.   // Section B.2.3
  1657.   OutputMarker (SOS) ;
  1658.   OutputWord (6 + 2 * scan_component_count) ;  // Length
  1659.   OutputByte (scan_component_count) ;  // Component Count
  1660.  
  1661.  
  1662.   if ((scan.component_mask & (1 << YComponent)) != 0)
  1663.   {
  1664.     OutputByte (YComponent) ;
  1665.     OutputByte (0x00) ; // Entropy Tables
  1666.   }
  1667.   if (! gray_scale)
  1668.   {
  1669.     if ((scan.component_mask & (1 << CbComponent)) != 0)
  1670.     {
  1671.       OutputByte (CbComponent) ;
  1672.       OutputByte (0x11) ; // Entropy Tables
  1673.     }
  1674.     if ((scan.component_mask & (1 << CrComponent)) != 0)
  1675.     {
  1676.       OutputByte (CrComponent) ;
  1677.       OutputByte (0x11) ; // Entropy Tables
  1678.     }
  1679.   }
  1680.  
  1681.   OutputByte (0) ; // Spectral Selection Start
  1682.   OutputByte (0) ; // Spectral Selection End
  1683.   int value = (scan.successive_approximation_high << 4)
  1684.             | scan.successive_approximation_low ;
  1685.   OutputByte (value) ; // Successive Approximation
  1686.  
  1687.   // Output the scan data.
  1688.   if (scan_component_count != 1)
  1689.   {
  1690.     InterleavedPass (true,
  1691.           &JpegEncoderComponent::ProgressiveDcFirst,
  1692.           &JpegEncoderComponent::PrintDcData, NULL,
  1693.           0, 0,
  1694.           scan.successive_approximation_low) ;
  1695.   }
  1696.   else
  1697.   {
  1698.     NoninterleavedPass (true,
  1699.           &JpegEncoderComponent::ProgressiveDcFirst,
  1700.           &JpegEncoderComponent::PrintDcData, NULL,
  1701.           0, 0,
  1702.           scan.successive_approximation_low) ;
  1703.   }
  1704.   return ;
  1705. }
  1706.  
  1707. //
  1708. //  Description:
  1709. //
  1710. //    This function outputs the data for a refining DC scan. This type of
  1711. //    scan is unique in that it does use Huffman encoding.
  1712. //
  1713. //
  1714. //  Parameters:
  1715. //    scan:  The structure that contains the scan parameters.
  1716. //
  1717. void JpegEncoder::PrintDcRefine (const Scan &scan)
  1718. {
  1719.   // Output the scan header.
  1720.   // Section B.2.3
  1721.   OutputMarker (SOS) ;
  1722.   OutputWord (6 + 2 * scan_component_count) ;  // Length
  1723.   OutputByte (scan_component_count) ;
  1724.  
  1725.  
  1726.   if ((scan.component_mask & (1 << YComponent)) != 0)
  1727.   {
  1728.     OutputByte (YComponent) ;
  1729.     OutputByte (0) ; // No Huffman table is used.
  1730.   }
  1731.   if (! gray_scale)
  1732.   {
  1733.     if ((scan.component_mask & (1 << CbComponent)) != 0)
  1734.     {
  1735.       OutputByte (CbComponent) ;
  1736.       OutputByte (0) ; // No Huffman table is used.
  1737.     }
  1738.     if ((scan.component_mask & (1 << CrComponent)) != 0)
  1739.     {
  1740.       OutputByte (CrComponent) ;
  1741.       OutputByte (0) ; // No Huffman table is used.
  1742.     }
  1743.   }
  1744.  
  1745.   OutputByte (0) ; // Spectral Selection Start
  1746.   OutputByte (0) ; // Spectral Selection End
  1747.  
  1748.   int value = (scan.successive_approximation_high << 4)
  1749.             | scan.successive_approximation_low ;
  1750.   OutputByte (value) ;
  1751.  
  1752.   // Output the scan data.
  1753.   if (scan_component_count != 1)
  1754.   {
  1755.     InterleavedPass (true,
  1756.           &JpegEncoderComponent::ProgressiveDcRefine,
  1757.           NULL, NULL,
  1758.           0, 0,
  1759.           scan.successive_approximation_low) ;
  1760.   }
  1761.   else
  1762.   {
  1763.     NoninterleavedPass (true,
  1764.           &JpegEncoderComponent::ProgressiveDcRefine,
  1765.           NULL, NULL,
  1766.           0, 0,
  1767.           scan.successive_approximation_low) ;
  1768.   }
  1769.   return ;
  1770. }
  1771.  
  1772. //
  1773. //  Description:
  1774. //
  1775. //    This function outputs a scan that is the first pass for a set of AC
  1776. //    coefficients.
  1777. //
  1778. //    Even though AC progressive scans cannot be interleaved, we follow the
  1779. //    convention of using Huffman Table #0 for the Y component and #1 for
  1780. //    the Cb and Cr components.
  1781. //
  1782. //
  1783. //  Parameters:
  1784. //    scan:  The structure that contains the scan parameters.
  1785. //
  1786. void JpegEncoder::PrintAcFirst (const Scan &scan)
  1787. {
  1788.   // Reset the Huffman statistics counters.
  1789.   if ((scan.component_mask & (1<<YComponent)) != 0)
  1790.   {
  1791.     ac_tables [0].Reset () ;
  1792.   }
  1793.   else
  1794.   {
  1795.     ac_tables [1].Reset () ;
  1796.   }
  1797.  
  1798.   OutputRestartInterval (restart_interval) ;
  1799.  
  1800.   // Gather the Huffman statistics
  1801.   FirstAcData (scan, false, &JpegEncoderComponent::GatherAcData) ;
  1802.  
  1803.   // Generate the Huffman statistics
  1804.   if ((scan.component_mask & (1<<YComponent)) != 0)
  1805.   {
  1806.     ac_tables [0].BuildTable () ;
  1807.   }
  1808.   else
  1809.   {
  1810.     ac_tables [1].BuildTable () ;
  1811.   }
  1812.  
  1813.   PrintHuffmanTables (scan, false, true) ;
  1814.  
  1815.   // Section B.2.3
  1816.   OutputMarker (SOS) ;
  1817.   OutputWord (6 + 2 * scan_component_count) ;  // Length
  1818.   OutputByte (scan_component_count) ;  // Component Count
  1819.  
  1820.   if ((scan.component_mask & (1<<YComponent)) != 0)
  1821.   {
  1822.     OutputByte (YComponent) ;
  1823.     OutputByte (0x00) ; // Entropy Table
  1824.   }
  1825.   else if ((scan.component_mask & (1<<CbComponent)) != 0)
  1826.   {
  1827.     OutputByte (CbComponent) ;
  1828.     OutputByte (0x11) ; // Entropy Tables
  1829.   }
  1830.   else if ((scan.component_mask & (1<<CrComponent)) != 0)
  1831.   {
  1832.     OutputByte (CrComponent) ;
  1833.     OutputByte (0x11) ; // Entropy Tables
  1834.   }
  1835.  
  1836.   OutputByte (scan.spectral_selection_start) ; // Spectral Selection Start
  1837.   OutputByte (scan.spectral_selection_end) ; // Spectral Selection End
  1838.   int value = (scan.successive_approximation_high << 4)
  1839.             | scan.successive_approximation_low ;
  1840.   OutputByte (value) ; // Successive Approximation
  1841.  
  1842.   FirstAcData (scan, true, &JpegEncoderComponent::PrintAcData) ;
  1843.   return ;
  1844. }
  1845.  
  1846. //
  1847. //  Descriptio:
  1848. //
  1849. //    This function outputs the data for a scan that refines AC coefficients
  1850. //    through successive approximation.
  1851. //
  1852. //
  1853. //  Parameters:
  1854. //    scan:  The structure that contains the scan parameters.
  1855. //
  1856. void JpegEncoder::PrintAcRefine (const Scan &scan)
  1857. {
  1858.   // Reset the Huffman statistics counters.
  1859.   if ((scan.component_mask & (1<<YComponent)) != 0)
  1860.   {
  1861.     ac_tables [0].Reset () ;
  1862.   }
  1863.   else
  1864.   {
  1865.     ac_tables [1].Reset () ;
  1866.   }
  1867.  
  1868.   OutputRestartInterval (restart_interval) ;
  1869.   // Gather the Huffman statistics.
  1870.   RefineAcData (scan, false, &JpegEncoderComponent::GatherAcData) ;
  1871.  
  1872.   // Create the Huffman Table.
  1873.   if ((scan.component_mask & (1 <<YComponent)) != 0)
  1874.   {
  1875.     ac_tables [0].BuildTable () ;
  1876.   }
  1877.   else
  1878.   {
  1879.     ac_tables [1].BuildTable () ;
  1880.   }
  1881.  
  1882.   PrintHuffmanTables (scan, false, true) ;  // Only output the AC table.
  1883.  
  1884.   // Create the scan header.
  1885.   // Section B.2.3
  1886.   OutputMarker (SOS) ;
  1887.   OutputWord (6 + 2 * scan_component_count) ;  // Length
  1888.   OutputByte (scan_component_count) ;  // Component Count
  1889.  
  1890.   if ((scan.component_mask & (1<<YComponent)) != 0)
  1891.   {
  1892.     OutputByte (YComponent) ;
  1893.     OutputByte (0x00) ; // Entropy Tables
  1894.   }
  1895.   if ((scan.component_mask & (1<<CbComponent)) != 0)
  1896.   {
  1897.     OutputByte (CbComponent) ;
  1898.     OutputByte (0x11) ; // Entropy Tables
  1899.   }
  1900.   if ((scan.component_mask & (1<<CrComponent)) != 0)
  1901.   {
  1902.     OutputByte (CrComponent) ;
  1903.     OutputByte (0x11) ; // Entropy Tables
  1904.   }
  1905.  
  1906.   OutputByte (scan.spectral_selection_start) ; // Spectral Selection Start
  1907.   OutputByte (scan.spectral_selection_end) ; // Spectral Selection End
  1908.   int value = (scan.successive_approximation_high << 4)
  1909.             | scan.successive_approximation_low ;
  1910.   OutputByte (value) ; // Successive Approximation
  1911.  
  1912.   // Output the scan data.
  1913.   RefineAcData (scan, true, &JpegEncoderComponent::PrintAcData) ;
  1914.  
  1915.   return ;
  1916. }
  1917.  
  1918. //
  1919. //  Description:
  1920. //
  1921. //    This function loops through the data in an initial AC scan. For
  1922. //    all scans other than AC progressive ones we use the same function for
  1923. //    this purpose. Due to the excessive complexity of AC progressive scans
  1924. //    we use a specialized function.
  1925. //
  1926. //    This function gets called twice for each scan. The first pass is used
  1927. //    to gather Huffman statistics. The second pass is to output the scan.
  1928. //    Having a common function ensures that Huffman statistics are gathered
  1929. //    in the exact same manner as the scan data is output.
  1930. //
  1931. //  Parameters:
  1932. //    scan:  The structure that contains the scan parameters.
  1933. //    outputrestarts: flag to indicate if restart markers are to be output
  1934. //    acfunction: The member function to process a data unit
  1935. //
  1936. void JpegEncoder::FirstAcData (
  1937.                         const Scan &scan,
  1938.                         bool outputrestarts,
  1939.                         JpegEncoderComponent::ACOUTPUTFUNCTION acfunction)
  1940. {
  1941.   // We use a scale integer to keep trake of progress to lessen the
  1942.   // change that the progress increment will be zero.
  1943.   const int progressscale = 8 ;
  1944.   unsigned int progress ;
  1945.   unsigned int progressincrement ;
  1946.   if (outputrestarts)
  1947.     progress = 50 << progressscale ;
  1948.   else
  1949.     progress = 0 ;
  1950.   progressincrement = (100 << progressscale)
  1951.                     / (2 * scan_components [0]->DataUnitRows ()) ;
  1952.  
  1953.   scan_components [0]->ResetEobRun () ;
  1954.  
  1955.   unsigned int intervalcount = 0 ;  // Count between restarts
  1956.   unsigned int restartmarker = 0 ;  // Value 0..7
  1957.   for (unsigned int row = 0 ;
  1958.        row < scan_components [0]->DataUnitRows () ;
  1959.        ++ row)
  1960.   {
  1961.     for (unsigned int col = 0 ;
  1962.          col < scan_components [0]->DataUnitCols () ;
  1963.          ++ col, ++ intervalcount)
  1964.     {
  1965.       // See if we are using restart markers.
  1966.       if (restart_interval != 0)
  1967.       {
  1968.         // Is a restart marker needed.
  1969.         if (intervalcount == restart_interval)
  1970.         {
  1971.           // If there are any outstanding EOB runs we flush them before the
  1972.           // restart marker. This is not explicitly stated in the JPEG
  1973.           // standard. The definition of "Restart Interval" in section 4.1
  1974.           // states that restart markers separate independent sequences,
  1975.           // something we would not have if we did not output the EOB run
  1976.           // here.
  1977.           scan_components [0]->PrintEobRun (acfunction) ;
  1978.           // Here we rely on the relationship RST0|n = RSTn [n = 0..7]
  1979.           // Section E.1.4
  1980.           if (outputrestarts)
  1981.             OutputMarker (RST0 | restartmarker) ;
  1982.           ++ restartmarker ;
  1983.           restartmarker %= 8 ;
  1984.           intervalcount = 0 ;
  1985.         }
  1986.       }
  1987.  
  1988.       // Process the data unit
  1989.       scan_components [0]->ProgressiveAcFirst (
  1990.                                 row,
  1991.                                 col,
  1992.                                 acfunction,
  1993.                                 scan.spectral_selection_start,
  1994.                                 scan.spectral_selection_end,
  1995.                                 scan.successive_approximation_low) ;
  1996.     }
  1997.     progress += progressincrement ;
  1998.     CallProgressFunction (progress >> progressscale) ;
  1999.   }
  2000.   // If there is a final end of band run then write it out.
  2001.   scan_components [0]->PrintEobRun (acfunction) ;
  2002.   CallProgressFunction (100) ;
  2003.   return ;
  2004. }
  2005.  
  2006. //
  2007. //  Description
  2008. //
  2009. //    This function loops through the DC using in a refining AC scan. For
  2010. //    all scans other than AC progressive ones we use the same function for
  2011. //    this purpose. Due to the excessive complexity of AC progressive scans
  2012. //    we use a specialized function.
  2013. //
  2014. //    This function gets called twice for each scan. The first pass is used
  2015. //    to gather Huffman statistics. The second pass is to output the scan.
  2016. //    Having a common function ensures that Huffman statistics are gathered
  2017. //    in the exact same manner as the scan data is output.
  2018. //
  2019. //  Parameters:
  2020. //    scan:  The structure that contains the scan parameters.
  2021. //    outputrestarts: flag to indicate if restart markers are to be output
  2022. //    acfunction: The member function to process a data unit
  2023. //
  2024. void JpegEncoder::RefineAcData (
  2025.                       const Scan &scan,
  2026.                       bool outputrestarts,
  2027.                       JpegEncoderComponent::ACOUTPUTFUNCTION acfunction)
  2028. {
  2029.   // We use a scale integer to keep trake of progress to lessen the
  2030.   // change that the progress increment will be zero.
  2031.   const int progressscale = 8 ;
  2032.   unsigned int progress ;
  2033.   unsigned int progressincrement ;
  2034.   if (outputrestarts)
  2035.     progress = 50 << progressscale ;
  2036.   else
  2037.     progress = 0 ;
  2038.   progressincrement = (100 << progressscale)
  2039.                     / (2 * scan_components [0]->DataUnitRows ()) ;
  2040.  
  2041.   scan_components [0]->ResetEobRun () ;
  2042.  
  2043.   unsigned int intervalcount = 0 ;  // Count between restart markers
  2044.   unsigned int restartmarker = 0 ;  // 0..7 => RST0..RST7
  2045.   for (unsigned int row = 0 ;
  2046.        row < scan_components [0]->DataUnitRows () ;
  2047.        ++ row)
  2048.   {
  2049.     for (unsigned int col = 0 ;
  2050.          col < scan_components [0]->DataUnitCols () ;
  2051.          ++ col, ++ intervalcount)
  2052.     {
  2053.       // Are we using restart markers?
  2054.       if (restart_interval != 0)
  2055.       {
  2056.         // Do we need to output a restart marker?
  2057.         if (intervalcount == restart_interval)
  2058.         {
  2059.           // If there are any outstanding EOB runs we flush them before the
  2060.           // restart marker. This is not explicitly stated in the JPEG
  2061.           // standard. The definition of "Restart Interval" in section 4.1
  2062.           // states that restart markers separate independent sequences,
  2063.           // something we would not have if we did not output the EOB run
  2064.           // here.
  2065.           scan_components [0]->PrintRefineEobRun (
  2066.                                     acfunction,
  2067.                                     scan.spectral_selection_start,
  2068.                                     scan.spectral_selection_end,
  2069.                                     scan.successive_approximation_low) ;
  2070.           // Section E.1.4
  2071.           if (outputrestarts)
  2072.             OutputMarker (RST0 | restartmarker) ;
  2073.           ++ restartmarker ;
  2074.           restartmarker %= 8 ;
  2075.           intervalcount = 0 ;
  2076.         }
  2077.       }
  2078.       scan_components [0]->ProgressiveAcRefine (
  2079.                                 row,
  2080.                                 col,
  2081.                                 acfunction,
  2082.                                 scan.spectral_selection_start,
  2083.                                 scan.spectral_selection_end,
  2084.                                 scan.successive_approximation_low) ;
  2085.  
  2086.     }
  2087.     progress += progressincrement ;
  2088.     CallProgressFunction (progress >> progressscale) ;
  2089.   }
  2090.   // If there is a final end of band run then write it out.
  2091.   scan_components [0]->PrintRefineEobRun (acfunction,
  2092.                                      scan.spectral_selection_start,
  2093.                                      scan.spectral_selection_end,
  2094.                                      scan.successive_approximation_low) ;
  2095.  
  2096.   CallProgressFunction (100) ;
  2097.   return ;
  2098. }
  2099.  
  2100. //
  2101. //  Description:
  2102. //
  2103. //    This function determines which components is in a given scan.
  2104. //
  2105. //  Parameters:
  2106. //    scan:  The structure that contains the scan parameters.
  2107. //
  2108. //  Implicit Outputs:
  2109. //    scan_component_count: The number of components in the scan.
  2110. //    scan_components:      The list of components in the scan.
  2111. //
  2112.  
  2113. void JpegEncoder::FindComponentsInScan (Scan &scan)
  2114. {
  2115.   scan_component_count = 0 ;
  2116.   if ((scan.component_mask & (1 <<YComponent)) != 0)
  2117.   {
  2118.     scan_components [scan_component_count] = &image_components [YComponent] ;
  2119.     ++ scan_component_count ;
  2120.   }
  2121.   if (! gray_scale)
  2122.   {
  2123.     if ((scan.component_mask & (1 <<CbComponent)) != 0)
  2124.     {
  2125.       scan_components [scan_component_count]
  2126.         = &image_components [CbComponent] ;
  2127.       ++ scan_component_count ;
  2128.     }
  2129.     if ((scan.component_mask & (1 <<CrComponent)) != 0)
  2130.     {
  2131.       scan_components [scan_component_count]
  2132.         = &image_components [CrComponent] ;
  2133.       ++ scan_component_count ;
  2134.     }
  2135.   }
  2136.   return ;
  2137. }
  2138.  
  2139. //
  2140. //  Description:
  2141. //
  2142. //    This function sets the sampling frequencies for a component
  2143. //
  2144. //  Parameters:
  2145. //    component:  The component ID
  2146. //    hf:         Horizontal Frequency
  2147. //    vf:         Vertical Frequency
  2148. //
  2149. void JpegEncoder::SetSamplingFrequency (unsigned int component,   
  2150.                                         unsigned int hf,
  2151.                                         unsigned int vf)
  2152. {
  2153.   if (component >= MaxComponents)
  2154.     throw EJpegError ("Invalid Component ID") ;
  2155.  
  2156.   if (hf > JpegMaxSamplingFrequency || hf < JpegMinSamplingFrequency)
  2157.     throw EJpegError ("Invalid Horizontal Sampling Frequency") ;
  2158.  
  2159.   if (vf > JpegMaxSamplingFrequency || vf < JpegMinSamplingFrequency)
  2160.     throw EJpegError ("Invalid Vertical Sampling Frequency") ;
  2161.  
  2162.   image_components [component].SetHorizontalFrequency (hf) ;
  2163.   image_components [component].SetVerticalFrequency (vf) ;
  2164.   return ;
  2165. }
  2166.  
  2167. //
  2168. //  Description:
  2169. //
  2170. //    This function gets the sampling frequencies for a component
  2171. //
  2172. //  Parameters:
  2173. //    component:  The component ID
  2174. //    hf:         Horizontal Frequency
  2175. //    vf:         Vertical Frequency
  2176. //
  2177. void JpegEncoder::GetSamplingFrequency (unsigned int component,
  2178.                                         unsigned int &hf,
  2179.                                         unsigned int &vf)
  2180. {
  2181.   if (component >= MaxComponents)
  2182.     throw EJpegError ("Invalid Component ID") ;
  2183.  
  2184.   hf = image_components [component].GetHorizontalFrequency () ;
  2185.   vf = image_components [component].GetVerticalFrequency () ;
  2186.   return ;
  2187. }
  2188.  
  2189. #pragma comment (exestr, "Copyright 1998 Colosseum Builders Inc.")
  2190.  
  2191. //
  2192. //  Description:
  2193. //
  2194. //    This function writes the JFIF header for the image.
  2195. //
  2196. void JpegEncoder::OutputJfifHeader ()
  2197. {
  2198.   // Create the JFIF header.
  2199.   struct JfifHeader jfif ;
  2200.   jfif.length = SystemToBigEndian ((UBYTE2) sizeof (jfif)) ;
  2201.   jfif.identifier [0] = 'J' ;
  2202.   jfif.identifier [1] = 'F' ;
  2203.   jfif.identifier [2] = 'I' ;
  2204.   jfif.identifier [3] = 'F' ;
  2205.   jfif.version [0] = 1 ;
  2206.   jfif.version [1] = 1 ;
  2207.   jfif.units = 0 ;
  2208.   jfif.xdensity = SystemToBigEndian ((UBYTE2) 1) ;
  2209.   jfif.ydensity = SystemToBigEndian ((UBYTE2) 1) ;
  2210.   jfif.xthumbnail = 0 ;
  2211.   jfif.ythumbnail = 0 ;
  2212.   output_stream->write ((char *) &jfif, sizeof (jfif)) ;
  2213.   return ;
  2214. }
  2215.  
  2216. //
  2217. //  Description:
  2218. //
  2219. //    This function sets the attributes for a scan.
  2220. //
  2221. //  Parameters:
  2222. //    scan:  Scan number (0..MaxScan - 1)
  2223. //    components: Bit mask of components to include inthe scan
  2224. //    sse:  The spectral selection end for the scan.  The
  2225. //          spectral selection start is the sse+1 of the previous
  2226. //          scan
  2227. //    ssa:  Initial successive approximation value for the scan.
  2228. //
  2229. void JpegEncoder::SetScanAttributes (unsigned int scan,
  2230.                                      unsigned long components,
  2231.                                      unsigned int sse,
  2232.                                      unsigned int ssa)
  2233. {
  2234.   if (scan >= MaxScans)
  2235.     throw EJpegError ("Scan Index Out of Range") ;
  2236.  
  2237.   image_scans [scan].component_mask = components ;
  2238.   image_scans [scan].spectral_selection_end = sse ;
  2239.   image_scans [scan].successive_approximation = ssa ;
  2240.   return ;
  2241. }
  2242.  
  2243. //
  2244. //  Description:
  2245. //
  2246. //    This fnction returns the attributes that have been defined
  2247. //    for a scan (revsere of SetScanAttributes).
  2248. //
  2249. //  Parameters:
  2250. //    scan: (in) The scan to retrieve information about
  2251. //    components: (out) Bitmask of component IDs in the scan
  2252. //    sse: (out) Spectral selection end
  2253. //    ssa: (out) Successive Approximation
  2254. //
  2255. void JpegEncoder::GetScanAttributes (unsigned int scan,
  2256.                                      unsigned long &components,
  2257.                                      unsigned int &sse,
  2258.                                      unsigned int &ssa)
  2259. {
  2260.   if (scan >= MaxScans)
  2261.     throw EJpegError ("Scan Index Out of Range") ;
  2262.  
  2263.   components = image_scans [scan].component_mask ;
  2264.   sse = image_scans [scan].spectral_selection_end ;
  2265.   ssa = image_scans [scan].successive_approximation ;
  2266. }
  2267.  
  2268. //
  2269. //  Description:
  2270. //
  2271. //    This function counts the number of passes through the data required
  2272. //    to write the image. This value is passed t the progress function.
  2273. //
  2274. void JpegEncoder::CountPassesForProgressReporting ()
  2275. {
  2276.   current_pass = 0 ;
  2277.   if (progressive_mode)
  2278.   {
  2279.     if (gray_scale)
  2280.     {
  2281.       total_passes = 1 ;
  2282.       for (unsigned int ii = 0 ; ii < scan_count ; ++ ii)
  2283.       {
  2284.         if ((image_scans [ii].component_mask & (1<<YComponent)) != 0)
  2285.         {
  2286.           total_passes += image_scans [ii].successive_approximation + 1 ;
  2287.         }
  2288.       }
  2289.     }
  2290.     else
  2291.     {
  2292.       total_passes = 3 ;
  2293.       for (unsigned int ii = 0 ; ii < scan_count ; ++ ii)
  2294.       {
  2295.         total_passes += image_scans [ii].successive_approximation + 1 ;
  2296.       }
  2297.     }
  2298.   }
  2299.   else
  2300.   {
  2301.     if (gray_scale)
  2302.       total_passes = 2 ;
  2303.     else
  2304.       total_passes = 3 + scan_count ;
  2305.   }
  2306.   return ;
  2307. }
  2308.  
  2309. //
  2310. //  Description:
  2311. //
  2312. //    This function returns the current quality value for the
  2313. //    encoder.
  2314. //
  2315. //  Return Value:
  2316. //    The quality value.
  2317. //
  2318. unsigned int JpegEncoder::GetQuality () const
  2319. {
  2320.   return image_quality ;
  2321. }
  2322.  
  2323. //
  2324. //  Description:
  2325. //
  2326. //    This function sets the image quality value.
  2327. //
  2328. //  Parameters:
  2329. //    value: The quality value (1..100)
  2330. //
  2331. void JpegEncoder::SetQuality (unsigned int value)
  2332. {
  2333.   if (value < 1 || value > 100)
  2334.     throw EJpegValueOutOfRange () ;
  2335.  
  2336.   image_quality = value ;
  2337.   return ;
  2338. }
  2339.