Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/pnmimagetypes/pnmFileTypeJPG2000Writer.cxx

Go to the documentation of this file.
00001 // Filename: pnmFileTypeJPGWriter.cxx
00002 // Created by:  mike (19Jun00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "pnmFileTypeJPG2000.h"
00020 #include "config_pnmimagetypes.h"
00021 
00022 #include "pnmImage.h"
00023 #include "pnmWriter.h"
00024 
00025 extern "C" {
00026 #include <jpeglib.h>
00027 }
00028 
00029 ////////////////////////////////////////////////////////////////////
00030 //     Function: PNMFileTypeJPG2000::Writer::Constructor
00031 //       Access: Public
00032 //  Description:
00033 ////////////////////////////////////////////////////////////////////
00034 PNMFileTypeJPG2000::Writer::
00035 Writer(PNMFileType *type, ostream *file, bool owns_file) :
00036   PNMWriter(type, file, owns_file)
00037 {
00038 }
00039 
00040 
00041 ////////////////////////////////////////////////////////////////////
00042 //     Function: PNMFileTypeJPG2000::Writer::write_data
00043 //       Access: Public, Virtual
00044 //  Description: Writes out an entire image all at once, including the
00045 //               header, based on the image data stored in the given
00046 //               _x_size * _y_size array and alpha pointers.  (If the
00047 //               image type has no alpha channel, alpha is ignored.)
00048 //               Returns the number of rows correctly written.
00049 //
00050 //               It is the user's responsibility to fill in the header
00051 //               data via calls to set_x_size(), set_num_channels(),
00052 //               etc., or copy_header_from(), before calling
00053 //               write_data().
00054 //
00055 //               It is important to delete the PNMWriter class after
00056 //               successfully writing the data.  Failing to do this
00057 //               may result in some data not getting flushed!
00058 //
00059 //               Derived classes need not override this if they
00060 //               instead provide supports_streaming() and write_row(),
00061 //               below.
00062 ////////////////////////////////////////////////////////////////////
00063 int PNMFileTypeJPG2000::Writer::
00064 write_data(xel *array, xelval *) {
00065   if (_y_size<=0 || _x_size<=0) {
00066     return 0;
00067   }
00068 
00069   /* This struct contains the JPEG compression parameters and pointers to
00070    * working space (which is allocated as needed by the JPEG library).
00071    * It is possible to have several such structures, representing multiple
00072    * compression/decompression processes, in existence at once.  We refer
00073    * to any one struct (and its associated working data) as a "JPEG object".
00074    */
00075   struct jpeg_compress_struct cinfo;
00076   /* This struct represents a JPEG error handler.  It is declared separately
00077    * because applications often want to supply a specialized error handler
00078    * (see the second half of this file for an example).  But here we just
00079    * take the easy way out and use the standard error handler, which will
00080    * print a message on stderr and call exit() if compression fails.
00081    * Note that this struct must live as long as the main JPEG parameter
00082    * struct, to avoid dangling-pointer problems.
00083    */
00084   struct jpeg_error_mgr jerr;
00085   /* More stuff */
00086   JSAMPROW row_pointer[1];      /* pointer to JSAMPLE row[s] */
00087   int row_stride;               /* physical row width in image buffer */
00088 
00089   /* Step 1: allocate and initialize JPEG compression object */
00090 
00091   /* We have to set up the error handler first, in case the initialization
00092    * step fails.  (Unlikely, but it could happen if you are out of memory.)
00093    * This routine fills in the contents of struct jerr, and returns jerr's
00094    * address which we place into the link field in cinfo.
00095    */
00096   cinfo.err = jpeg_std_error(&jerr);
00097 
00098   /* Now we can initialize the JPEG compression object. */
00099   jpeg_create_compress(&cinfo);
00100 
00101   /* Step 2: specify data destination (eg, a file) */
00102   /* Note: steps 2 and 3 can be done in either order. */
00103 
00104   /* Here we use the library-supplied code to send compressed data to a
00105    * stdio stream.  You can also write your own code to do something else.
00106    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
00107    * requires it in order to write binary files.
00108    */
00109   // This is broken, and won't compile.  We need to drop in an
00110   // iostream replacement, like we did for JPG.
00111   jpeg_stdio_dest(&cinfo, _file);
00112 
00113   /* Step 3: set parameters for compression */
00114 
00115   /* First we supply a description of the input image.
00116    * Four fields of the cinfo struct must be filled in:
00117    */
00118   cinfo.image_width = _x_size;      /* image width and height, in pixels */
00119   cinfo.image_height = _y_size;
00120   if (is_grayscale()) {
00121     cinfo.input_components = 1;
00122     cinfo.in_color_space = JCS_GRAYSCALE;
00123   } else {
00124     cinfo.input_components = 3;
00125     cinfo.in_color_space = JCS_RGB;
00126   }
00127   /* Now use the library's routine to set default compression parameters.
00128    * (You must set at least cinfo.in_color_space before calling this,
00129    * since the defaults depend on the source color space.)
00130    */
00131   jpeg_set_defaults(&cinfo);
00132   /* Now you can set any non-default parameters you wish to.
00133    * Here we just illustrate the use of quality (quantization table) scaling:
00134    */
00135   jpeg_set_quality(&cinfo, jpeg_quality, TRUE /* limit to baseline-JPEG values */);
00136 
00137   /* Step 4: Start compressor */
00138 
00139   /* TRUE ensures that we will write a complete interchange-JPEG file.
00140    * Pass TRUE unless you are very sure of what you're doing.
00141    */
00142   jpeg_start_compress(&cinfo, TRUE);
00143 
00144   /* Step 5: while (scan lines remain to be written) */
00145   /*           jpeg_write_scanlines(...); */
00146 
00147   /* Here we use the library's state variable cinfo.next_scanline as the
00148    * loop counter, so that we don't have to keep track ourselves.
00149    * To keep things simple, we pass one scanline per call; you can pass
00150    * more if you wish, though.
00151    */
00152   row_stride = _x_size * cinfo.input_components; /* JSAMPLEs per row in image_buffer */
00153 
00154   int x = 0;
00155   JSAMPROW row = new JSAMPLE[row_stride];
00156   while (cinfo.next_scanline < cinfo.image_height) {
00157     /* jpeg_write_scanlines expects an array of pointers to scanlines.
00158      * Here the array is only one element long, but you could pass
00159      * more than one scanline at a time if that's more convenient.
00160      */
00161     for (int i = 0; i < row_stride; i += cinfo.input_components) {
00162       if (cinfo.input_components == 1) {
00163         row[i] = (JSAMPLE)(MAXJSAMPLE * PPM_GETB(array[x])/_maxval);
00164       } else {
00165         row[i] = (JSAMPLE)(MAXJSAMPLE * PPM_GETR(array[x])/_maxval);
00166         row[i+1] = (JSAMPLE)(MAXJSAMPLE * PPM_GETG(array[x])/_maxval);
00167         row[i+2] = (JSAMPLE)(MAXJSAMPLE * PPM_GETB(array[x])/_maxval);
00168       }
00169       x++;
00170     }
00171     //row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
00172     //(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
00173     row_pointer[0] = row;
00174     (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
00175   }
00176   delete row;
00177 
00178   /* Step 6: Finish compression */
00179 
00180   jpeg_finish_compress(&cinfo);
00181 
00182   /* Step 7: release JPEG compression object */
00183 
00184   /* This is an important step since it will release a good deal of memory. */
00185   jpeg_destroy_compress(&cinfo);
00186 
00187   return _y_size;
00188 }

Generated on Fri May 2 00:43:19 2003 for Panda by doxygen1.3