home *** CD-ROM | disk | FTP | other *** search
/ Compressed Image File Formats / CompressedImageFileFormatsJohnMiano.iso / pc / Library / source / jpendu.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-17  |  8.0 KB  |  279 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:   EncoderDataUnit Class Implementation
  17. //
  18. // Author: John M. Miano  miano@colosseumbuilders.com
  19. //
  20. //
  21.  
  22. #include <math.h>
  23. #include "jpendu.h"
  24.  
  25. #if defined (_MSC_VER)
  26. const double M_PI = acos (-1.0) ;
  27. #endif
  28.  
  29. const double FC4 = cos (M_PI * 4.0 / 16.0) ;
  30. const double FSEC2 = 0.5 / cos (M_PI * 2.0 / 16.0) ;
  31. const double FSEC6 = 0.5 / cos (M_PI * 6.0 / 16.0) ;
  32.  
  33.  
  34. //
  35. //  Description:
  36. //
  37. //    This is an implementation of the Forward Discrete Transform based
  38. //    on matrix factorization of the DCT matrix. My first factorization
  39. //    always left a constant factor of 1/8 at the end which could be merged
  40. //    with quantization or as part of an integer descaling.
  41. //
  42. //    Using the cosine product formula it was possible to eliminate some
  43. //    multiplication operations which resulted in a more complex scaling
  44. //    matrix.
  45. //
  46. //    I have documented the derivation process for this DCT process as well
  47. //    as another I have tried. I have some more factorization ideas to try
  48. //    out when I have to to get around to it. Unfortunately matrix factorization
  49. //    is a very tedious process. When you see the documents it looks easy, but
  50. //    believe me and all the legal pad I went through that it is not.
  51. //
  52. //    This implementation is a litteral mapping of the matrix implementation.
  53. //    Each set of temporaries represents one matrix multiplication. Hopefully
  54. //    your compile will optimize the temporaries out. It is possible to
  55. //    reorder the operations to reduce the number of temporaries variables
  56. //    required (The Intel C++ compile does this on its own) which seems to be
  57. //    the best optimization to try next.
  58. //
  59. //
  60. //    I have not implemented a scaled integer version of the FDCT because I
  61. //    believe that most people will want quality over speed in encoding.
  62. //
  63. //  Parameters:
  64. //    qt:  The quantization table
  65. //    output:  The output DCT coefficients
  66. //
  67.  
  68. void JpegEncoderDataUnit::ForwardDct (JpegEncoderQuantizationTable &qt,
  69.                                       JpegEncoderCoefficientBlock &output)
  70. {
  71.   double tmp [JpegSampleWidth][JpegSampleWidth] ;
  72.  
  73.   for (unsigned int col = 0 ; col < JpegSampleWidth ; ++ col)
  74.   {
  75.     // Shift this first matrix multiplication includes the range shift from
  76.     // 0...255 to -128...127. Notice that the shift term is canceled out
  77.     // in the alst four elements.
  78.     double a0 = data [0][col] + data [7][col] - 2 * JpegMidpointSampleValue ;
  79.     double a1 = data [1][col] + data [6][col] - 2 * JpegMidpointSampleValue ;
  80.     double a2 = data [2][col] + data [5][col] - 2 * JpegMidpointSampleValue ;
  81.     double a3 = data [3][col] + data [4][col] - 2 * JpegMidpointSampleValue ;
  82.     double a4 = data [3][col] - data [4][col] ;
  83.     double a5 = data [2][col] - data [5][col] ;
  84.     double a6 = data [1][col] - data [6][col] ;
  85.     double a7 = data [0][col] - data [7][col] ;
  86.  
  87.     double b0 = a0 + a3 ;
  88.     double b1 = a1 + a2 ;
  89.     double b2 = a1 - a2 ;
  90.     double b3 = a0 - a3 ;
  91.     double b4 = a4 ;
  92.     double b5 = a5 ;
  93.     double b6 = a6 ;
  94.     double b7 = a7 ;
  95.  
  96.     double c0 = b0 ;
  97.     double c1 = b1 ;
  98.     double c2 = b2 + b3 ;
  99.     double c3 = b3 ;
  100.     double c4 = b4 + b5 ;
  101.     double c5 = b5 + b6 ;
  102.     double c6 = b6 + b7 ;
  103.     double c7 = b7 ;
  104.  
  105.     double d0  = c0 ;
  106.     double d1  = c1 ;
  107.     double d2  = c2 ;
  108.     double d3  = c3 ;
  109.     double d4  = c4 + c6 ;
  110.     double d5  = c5 ;
  111.     double d6  = c6 ;
  112.     double d7  = c7 ;
  113.  
  114.     double e0 = d0 + d1 ;
  115.     double e1 = d0 - d1 ;
  116.     double e2 = FC4 * d2 ;
  117.     double e3 = d3 ;
  118.     double e4 = FC4 * d4 ;
  119.     double e5 = FC4 * d5 ;
  120.     double e6 = d6 ;
  121.     double e7 = d7 ;
  122.  
  123.     double f0 = e0 ;
  124.     double f1 = e1 ;
  125.     double f2 = e2 ;
  126.     double f3 = e3 ;
  127.     double f4 = e4 + e6 ;
  128.     double f5 = e5 ;
  129.     double f6 = e4 - e6 ;
  130.     double f7 = e7 ;
  131.  
  132.     double g0 = f0 ;
  133.     double g1 = f1 ;
  134.     double g2 = f2 ;
  135.     double g3 = f3 ;
  136.     double g4 = FSEC2 * f4 ;
  137.     double g5 = f7 - f5 ;
  138.     double g6 = FSEC6 * f6 ;
  139.     double g7 = f5 + f7 ;
  140.  
  141.     double h0 = g0 ;
  142.     double h1 = g1 ;
  143.     double h2 = g2 + g3 ;
  144.     double h3 = g3 - g2 ;
  145.     double h4 = g4 + g7 ;
  146.     double h5 = g5 + g6 ;
  147.     double h6 = g5 - g6 ;
  148.     double h7 = g7 - g4 ;
  149.  
  150.     tmp [0][col] = h0 ;
  151.     tmp [1][col] = h4 ;
  152.     tmp [2][col] = h2 ;
  153.     tmp [3][col] = h6 ;
  154.     tmp [4][col] = h1 ;
  155.     tmp [5][col] = h5 ;
  156.     tmp [6][col] = h3 ;
  157.     tmp [7][col] = h7 ;
  158.   }
  159.  
  160.   for (unsigned int row = 0 ; row < JpegSampleWidth ; ++ row)
  161.   {
  162.     double a0 = tmp [row][0] + tmp [row][7] ;
  163.     double a1 = tmp [row][1] + tmp [row][6] ;
  164.     double a2 = tmp [row][2] + tmp [row][5] ;
  165.     double a3 = tmp [row][3] + tmp [row][4] ;
  166.     double a4 = tmp [row][3] - tmp [row][4] ;
  167.     double a5 = tmp [row][2] - tmp [row][5] ;
  168.     double a6 = tmp [row][1] - tmp [row][6] ;
  169.     double a7 = tmp [row][0] - tmp [row][7] ;
  170.  
  171.     double b0 = a0 + a3 ;
  172.     double b1 = a1 + a2 ;
  173.     double b2 = a1 - a2 ;
  174.     double b3 = a0 - a3 ;
  175.     double b4 = a4 ;
  176.     double b5 = a5 ;
  177.     double b6 = a6 ;
  178.     double b7 = a7 ;
  179.  
  180.     double c0 = b0 ;
  181.     double c1 = b1 ;
  182.     double c2 = b2 + b3 ;
  183.     double c3 = b3 ;
  184.     double c4 = b4 + b5 ;
  185.     double c5 = b5 + b6 ;
  186.     double c6 = b6 + b7 ;
  187.     double c7 = b7 ;
  188.  
  189.     double d0  = c0 ;
  190.     double d1  = c1 ;
  191.     double d2  = c2 ;
  192.     double d3  = c3 ;
  193.     double d4  = c4 + c6 ;
  194.     double d5  = c5 ;
  195.     double d6  = c6 ;
  196.     double d7  = c7 ;
  197.  
  198.     double e0 = d0 + d1 ;
  199.     double e1 = d0 - d1 ;
  200.     double e2 = FC4 * d2 ;
  201.     double e3 = d3 ;
  202.     double e4 = FC4 * d4 ;
  203.     double e5 = FC4 * d5 ;
  204.     double e6 = d6 ;
  205.     double e7 = d7 ;
  206.  
  207.     double f0 = e0 ;
  208.     double f1 = e1 ;
  209.     double f2 = e2 ;
  210.     double f3 = e3 ;
  211.     double f4 = e4 + e6 ;
  212.     double f5 = e5 ;
  213.     double f6 = e4 - e6 ;
  214.     double f7 = e7 ;
  215.  
  216.     double g0 = f0 ;
  217.     double g1 = f1 ;
  218.     double g2 = f2 ;
  219.     double g3 = f3 ;
  220.     double g4 = FSEC2 * f4 ;
  221.     double g5 = f7 - f5 ;
  222.     double g6 = FSEC6 * f6 ;
  223.     double g7 = f5 + f7 ;
  224.  
  225.     double h0 = g0 ;
  226.     double h1 = g1 ;
  227.     double h2 = g2 + g3 ;
  228.     double h3 = g3 - g2 ;
  229.     double h4 = g4 + g7 ;
  230.     double h5 = g5 + g6 ;
  231.     double h6 = g5 - g6 ;
  232.     double h7 = g7 - g4 ;
  233.  
  234.     double i0 = h0 * qt.float_scaling [row][0] ;
  235.     double i1 = h4 * qt.float_scaling [row][1] ;
  236.     double i2 = h2 * qt.float_scaling [row][2] ;
  237.     double i3 = h6 * qt.float_scaling [row][3] ;
  238.     double i4 = h1 * qt.float_scaling [row][4] ;
  239.     double i5 = h5 * qt.float_scaling [row][5] ;
  240.     double i6 = h3 * qt.float_scaling [row][6] ;
  241.     double i7 = h7 * qt.float_scaling [row][7] ;
  242.  
  243.     if (i0 >= 0.0)
  244.       output [row][0] = (BYTE2) (i0 + 0.5) ;
  245.     else
  246.       output [row][0] = (BYTE2) (i0 - 0.5) ;
  247.     if (i1 >= 0.0)
  248.       output [row][1] = (BYTE2) (i1 + 0.5) ;
  249.     else
  250.       output [row][1] = (BYTE2) (i1 - 0.5) ;
  251.     if (i2 >= 0.0)
  252.       output [row][2] = (BYTE2) (i2 + 0.5) ;
  253.     else
  254.       output [row][2] = (BYTE2) (i2 - 0.5) ;
  255.     if (i3 >= 0.0)
  256.       output [row][3] = (BYTE2) (i3 + 0.5) ;
  257.     else
  258.       output [row][3] = (BYTE2) (i3 - 0.5) ;
  259.     if (i4 >= 0.0)
  260.       output [row][4] = (BYTE2) (i4 + 0.5) ;
  261.     else
  262.       output [row][4] = (BYTE2) (i4 - 0.5) ;
  263.     if (i5 >= 0.0)
  264.       output [row][5] = (BYTE2) (i5 + 0.5) ;
  265.     else
  266.       output [row][5] = (BYTE2) (i5 - 0.5) ;
  267.     if (i6 >= 0.0)
  268.       output [row][6] = (BYTE2) (i6 + 0.5) ;
  269.     else
  270.       output [row][6] = (BYTE2) (i6 - 0.5) ;
  271.     if (i7 >= 0.0)
  272.       output [row][7] = (BYTE2) (i7 + 0.5) ;
  273.     else
  274.       output [row][7] = (BYTE2) (i7 - 0.5) ;
  275.   }
  276.  
  277.   return ;
  278. }
  279.