From 01496b8e3d302af31f527a80d03f875236b667a0 Mon Sep 17 00:00:00 2001 From: cxgeorge <> Date: Thu, 28 Mar 2002 06:20:49 +0000 Subject: [PATCH] add non-functional jpeg2000 skeleton --- panda/src/pnmimagetypes/Sources.pp | 18 +- .../pnmimagetypes/config_pnmimagetypes.cxx | 10 + .../src/pnmimagetypes/config_pnmimagetypes.h | 1 + .../src/pnmimagetypes/pnmFileTypeJPG2000.cxx | 166 ++++++++++++++++ panda/src/pnmimagetypes/pnmFileTypeJPG2000.h | 133 +++++++++++++ .../pnmFileTypeJPG2000Reader.cxx | 166 ++++++++++++++++ .../pnmFileTypeJPG2000Writer.cxx | 186 ++++++++++++++++++ .../pnmimagetypes_composite4.cxx | 5 + 8 files changed, 682 insertions(+), 3 deletions(-) create mode 100644 panda/src/pnmimagetypes/pnmFileTypeJPG2000.cxx create mode 100644 panda/src/pnmimagetypes/pnmFileTypeJPG2000.h create mode 100644 panda/src/pnmimagetypes/pnmFileTypeJPG2000Reader.cxx create mode 100644 panda/src/pnmimagetypes/pnmFileTypeJPG2000Writer.cxx create mode 100644 panda/src/pnmimagetypes/pnmimagetypes_composite4.cxx diff --git a/panda/src/pnmimagetypes/Sources.pp b/panda/src/pnmimagetypes/Sources.pp index 078712ebd1..5665f6a604 100644 --- a/panda/src/pnmimagetypes/Sources.pp +++ b/panda/src/pnmimagetypes/Sources.pp @@ -1,6 +1,8 @@ #define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \ dtoolutil:c dtoolbase:c dtool:m + #define USE_JPEG yes +#define USE_JPEG2000 yes #begin lib_target #define TARGET pnmimagetypes @@ -26,15 +28,25 @@ pnmFileTypeTGA.cxx pnmFileTypeYUV.cxx #define IF_JPEG_INCLUDED_SOURCES \ - pnmFileTypeJPG.cxx \ - pnmFileTypeJPGReader.cxx pnmFileTypeJPGWriter.cxx + pnmFileTypeJPG2000.cxx \ + pnmFileTypeJPG2000Reader.cxx pnmFileTypeJPG2000Writer.cxx #define IF_JPEG_SOURCES \ - pnmFileTypeJPG.h + pnmFileTypeJPG2000.h #define IF_JPEG_COMBINED_SOURCES \ $[TARGET]_composite3.cxx + #define IF_JPEG2000_INCLUDED_SOURCES \ + pnmFileTypeJPG2000.cxx \ + pnmFileTypeJPG2000Reader.cxx pnmFileTypeJPG2000Writer.cxx + + #define IF_JPEG2000_SOURCES \ + pnmFileTypeJPG2000.h + + #define IF_JPEG2000_COMBINED_SOURCES \ + $[TARGET]_composite4.cxx + #define INSTALL_HEADERS \ config_pnmimagetypes.h diff --git a/panda/src/pnmimagetypes/config_pnmimagetypes.cxx b/panda/src/pnmimagetypes/config_pnmimagetypes.cxx index 87f44cdcc0..81eaa5ea1a 100644 --- a/panda/src/pnmimagetypes/config_pnmimagetypes.cxx +++ b/panda/src/pnmimagetypes/config_pnmimagetypes.cxx @@ -49,6 +49,7 @@ NotifyCategoryDef(pnmimage_img, pnmimage_cat); NotifyCategoryDef(pnmimage_soft, pnmimage_cat); NotifyCategoryDef(pnmimage_bmp, pnmimage_cat); NotifyCategoryDef(pnmimage_jpg, pnmimage_cat); +NotifyCategoryDef(pnmimage_jpg2000, pnmimage_cat); int sgi_storage_type = STORAGE_RLE; const string sgi_imagename = config_pnmimagetypes.GetString("sgi-imagename", ""); @@ -133,6 +134,9 @@ init_libpnmimagetypes() { #ifdef HAVE_JPEG PNMFileTypeJPG::init_type(); #endif +#ifdef HAVE_JPEG2000 + PNMFileTypeJPG2000::init_type(); +#endif string sgi_storage_type_str = config_pnmimagetypes.GetString("sgi-storage-type", "rle"); @@ -174,6 +178,9 @@ init_libpnmimagetypes() { #ifdef HAVE_JPEG tr->register_type(new PNMFileTypeJPG); #endif +#ifdef HAVE_JPEG2000 + tr->register_type(new PNMFileTypeJPG2000); +#endif // Also register with the Bam reader. PNMFileTypePNM::register_with_read_factory(); @@ -189,4 +196,7 @@ init_libpnmimagetypes() { #ifdef HAVE_JPEG PNMFileTypeJPG::register_with_read_factory(); #endif +#ifdef HAVE_JPEG2000 + PNMFileTypeJPG2000::register_with_read_factory(); +#endif } diff --git a/panda/src/pnmimagetypes/config_pnmimagetypes.h b/panda/src/pnmimagetypes/config_pnmimagetypes.h index faf064bc41..b73d8b23c5 100644 --- a/panda/src/pnmimagetypes/config_pnmimagetypes.h +++ b/panda/src/pnmimagetypes/config_pnmimagetypes.h @@ -33,6 +33,7 @@ NotifyCategoryDecl(pnmimage_img, EXPCL_PANDA, EXPTP_PANDA); NotifyCategoryDecl(pnmimage_soft, EXPCL_PANDA, EXPTP_PANDA); NotifyCategoryDecl(pnmimage_bmp, EXPCL_PANDA, EXPTP_PANDA); NotifyCategoryDecl(pnmimage_jpg, EXPCL_PANDA, EXPTP_PANDA); +NotifyCategoryDecl(pnmimage_jpg2000, EXPCL_PANDA, EXPTP_PANDA); extern int sgi_storage_type; extern const string sgi_imagename; diff --git a/panda/src/pnmimagetypes/pnmFileTypeJPG2000.cxx b/panda/src/pnmimagetypes/pnmFileTypeJPG2000.cxx new file mode 100644 index 0000000000..b0ff795694 --- /dev/null +++ b/panda/src/pnmimagetypes/pnmFileTypeJPG2000.cxx @@ -0,0 +1,166 @@ +// Filename: pnmFileTypeJPG2000.cxx +// Created by: mike (19Jun00) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#include "pnmFileTypeJPG2000.h" +#include "config_pnmimagetypes.h" + +#include +#include + +static const char * const extensions_JPG2000[] = { + "JP2","JPC" +}; +static const int num_extensions_JPG2000 = sizeof(extensions_JPG2000) / sizeof(const char *); + +TypeHandle PNMFileTypeJPG2000::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +PNMFileTypeJPG2000:: +PNMFileTypeJPG2000() { +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::get_name +// Access: Public, Virtual +// Description: Returns a few words describing the file type. +//////////////////////////////////////////////////////////////////// +string PNMFileTypeJPG2000:: +get_name() const { + return "JPEG_2000"; +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::get_num_extensions +// Access: Public, Virtual +// Description: Returns the number of different possible filename +// extensions_JPG2000 associated with this particular file type. +//////////////////////////////////////////////////////////////////// +int PNMFileTypeJPG2000:: +get_num_extensions() const { + return num_extensions_JPG2000; +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::get_extension +// Access: Public, Virtual +// Description: Returns the nth possible filename extension +// associated with this particular file type, without a +// leading dot. +//////////////////////////////////////////////////////////////////// +string PNMFileTypeJPG2000:: +get_extension(int n) const { + nassertr(n >= 0 && n < num_extensions_JPG2000, string()); + return extensions_JPG2000[n]; +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::get_suggested_extension +// Access: Public, Virtual +// Description: Returns a suitable filename extension (without a +// leading dot) to suggest for files of this type, or +// empty string if no suggestions are available. +//////////////////////////////////////////////////////////////////// +string PNMFileTypeJPG2000:: +get_suggested_extension() const { + return "JP2"; +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::has_magic_number +// Access: Public, Virtual +// Description: Returns true if this particular file type uses a +// magic number to identify it, false otherwise. +//////////////////////////////////////////////////////////////////// +bool PNMFileTypeJPG2000:: +has_magic_number() const { + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::matches_magic_number +// Access: Public, Virtual +// Description: Returns true if the indicated "magic number" byte +// stream (the initial few bytes read from the file) +// matches this particular file type, false otherwise. +//////////////////////////////////////////////////////////////////// +bool PNMFileTypeJPG2000:: +matches_magic_number(const string &magic_number) const { + nassertr(magic_number.size() >= 2, false); + return ((char)magic_number[0] == (char)0xff && + (char)magic_number[1] == (char)0xd8); +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::make_reader +// Access: Public, Virtual +// Description: Allocates and returns a new PNMReader suitable for +// reading from this file type, if possible. If reading +// from this file type is not supported, returns NULL. +//////////////////////////////////////////////////////////////////// +PNMReader *PNMFileTypeJPG2000:: +make_reader(FILE *file, bool owns_file, const string &magic_number) { + init_pnm(); + return new Reader(this, file, owns_file, magic_number); +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::make_writer +// Access: Public, Virtual +// Description: Allocates and returns a new PNMWriter suitable for +// reading from this file type, if possible. If writing +// files of this type is not supported, returns NULL. +//////////////////////////////////////////////////////////////////// +PNMWriter *PNMFileTypeJPG2000:: +make_writer(FILE *file, bool owns_file) { + init_pnm(); + return new Writer(this, file, owns_file); +} + + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::register_with_read_factory +// Access: Public, Static +// Description: Registers the current object as something that can be +// read from a Bam file. +//////////////////////////////////////////////////////////////////// +void PNMFileTypeJPG2000:: +register_with_read_factory() { + BamReader::get_factory()-> + register_factory(get_class_type(), make_PNMFileTypeJPG2000); +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::make_PNMFileTypeJPG2000 +// Access: Protected, Static +// Description: This method is called by the BamReader when an object +// of this type is encountered in a Bam file; it should +// allocate and return a new object with all the data +// read. +// +// In the case of the PNMFileType objects, since these +// objects are all shared, we just pull the object from +// the registry. +//////////////////////////////////////////////////////////////////// +TypedWritable *PNMFileTypeJPG2000:: +make_PNMFileTypeJPG2000(const FactoryParams ¶ms) { + return PNMFileTypeRegistry::get_ptr()->get_type_by_handle(get_class_type()); +} diff --git a/panda/src/pnmimagetypes/pnmFileTypeJPG2000.h b/panda/src/pnmimagetypes/pnmFileTypeJPG2000.h new file mode 100644 index 0000000000..1b827f203e --- /dev/null +++ b/panda/src/pnmimagetypes/pnmFileTypeJPG2000.h @@ -0,0 +1,133 @@ +// Filename: pnmFileTypeJPG2000.h +// Created by: mike (17Jun00) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#ifndef PNMFILETYPEJPG2000_H +#define PNMFILETYPEJPG2000_H + +#include + +#include +#include +#include + +#if defined(_WIN32) +#include // we need to include this before jpeglib. +#endif + +#include + +/* +extern "C" { +#include +#include +} +*/ + +//////////////////////////////////////////////////////////////////// +// Class : PNMFileTypeJPG2000 +// Description : For reading and writing Jpeg files. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA PNMFileTypeJPG2000 : public PNMFileType { +public: + PNMFileTypeJPG2000(); + + virtual string get_name() const; + + virtual int get_num_extensions() const; + virtual string get_extension(int n) const; + virtual string get_suggested_extension() const; + + virtual bool has_magic_number() const; + virtual bool matches_magic_number(const string &magic_number) const; + + virtual PNMReader *make_reader(FILE *file, bool owns_file = true, + const string &magic_number = string()); + virtual PNMWriter *make_writer(FILE *file, bool owns_file = true); + +public: + class Reader : public PNMReader { + public: + Reader(PNMFileType *type, FILE *file, bool owns_file, string magic_number); + ~Reader(void); + + virtual int read_data(xel *array, xelval *alpha); + + private: +/* + // struct jpeg_decompress_struct _cinfo; + jas_image_t *image; + jas_stream_t *in; + jas_stream_t *out; +*/ + + + struct my_error_mgr { + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; + }; + typedef struct my_error_mgr *_my_error_ptr; + struct my_error_mgr _jerr; + unsigned long pos; + + unsigned long offBits; + + unsigned short cBitCount; + int indexed; + int classv; + + pixval R[256]; /* reds */ + pixval G[256]; /* greens */ + pixval B[256]; /* blues */ + }; + + class Writer : public PNMWriter { + public: + Writer(PNMFileType *type, FILE *file, bool owns_file); + + virtual int write_data(xel *array, xelval *alpha); + }; + + + // The TypedWritable interface follows. +public: + static void register_with_read_factory(); + +protected: + static TypedWritable *make_PNMFileTypeJPG2000(const FactoryParams ¶ms); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + PNMFileType::init_type(); + register_type(_type_handle, "PNMFileTypeJPG2000", + PNMFileType::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +#endif + + diff --git a/panda/src/pnmimagetypes/pnmFileTypeJPG2000Reader.cxx b/panda/src/pnmimagetypes/pnmFileTypeJPG2000Reader.cxx new file mode 100644 index 0000000000..4d3e80c285 --- /dev/null +++ b/panda/src/pnmimagetypes/pnmFileTypeJPG2000Reader.cxx @@ -0,0 +1,166 @@ +// Filename: pnmFileTypeJPGReader.cxx +// Created by: mike (19Jun00) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#include "pnmFileTypeJPG2000.h" +#include "config_pnmimagetypes.h" +#include + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::Reader::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +PNMFileTypeJPG2000::Reader:: +Reader(PNMFileType *type, FILE *file, bool owns_file, string magic_number) : + PNMReader(type, file, owns_file) +{ + // Put the magic number bytes back into the file + fseek(file, 0, SEEK_SET); + + /* Step 1: allocate and initialize JPEG decompression object */ + + /* We set up the normal JPEG error routines, then override error_exit. */ + _cinfo.err = jpeg_std_error(&_jerr.pub); + + /* Now we can initialize the JPEG decompression object. */ + jpeg_create_decompress(&_cinfo); + + /* Step 2: specify data source (eg, a file) */ + + jpeg_stdio_src(&_cinfo, file); + + /* Step 3: read file parameters with jpeg_read_header() */ + + jpeg_read_header(&_cinfo, TRUE); + /* We can ignore the return value from jpeg_read_header since + * (a) suspension is not possible with the stdio data source, and + * (b) we passed TRUE to reject a tables-only JPEG file as an error. + * See libjpeg.doc for more info. + */ + + /* Step 4: set parameters for decompression */ + _cinfo.scale_num = jpeg_scale_num; + _cinfo.scale_denom = jpeg_scale_denom; + + /* Step 5: Start decompressor */ + + jpeg_start_decompress(&_cinfo); + /* We can ignore the return value since suspension is not possible + * with the stdio data source. + */ + + _num_channels = _cinfo.output_components; + _x_size = (int)_cinfo.output_width; + _y_size = (int)_cinfo.output_height; + _maxval = MAXJSAMPLE; +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::Reader::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +PNMFileTypeJPG2000::Reader:: +~Reader(void) { + jpeg_destroy_decompress(&_cinfo); +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::Reader::read_data +// Access: Public, Virtual +// Description: Reads in an entire image all at once, storing it in +// the pre-allocated _x_size * _y_size array and alpha +// pointers. (If the image type has no alpha channel, +// alpha is ignored.) Returns the number of rows +// correctly read. +// +// Derived classes need not override this if they +// instead provide supports_read_row() and read_row(), +// below. +//////////////////////////////////////////////////////////////////// +int PNMFileTypeJPG2000::Reader:: +read_data(xel *array, xelval *) { + JSAMPARRAY buffer; /* Output row buffer */ + int row_stride; /* physical row width in output buffer */ + + nassertr(_cinfo.output_components == 1 || _cinfo.output_components == 3, 0); + + /* We may need to do some setup of our own at this point before reading + * the data. After jpeg_start_decompress() we have the correct scaled + * output image dimensions available, as well as the output colormap + * if we asked for color quantization. + * In this example, we need to make an output work buffer of the right size. + */ + /* JSAMPLEs per row in output buffer */ + row_stride = _cinfo.output_width * _cinfo.output_components; + /* Make a one-row-high sample array that will go away when done with image */ + + buffer = (*_cinfo.mem->alloc_sarray) + ((j_common_ptr) &_cinfo, JPOOL_IMAGE, row_stride, 1); + + /* Step 6: while (scan lines remain to be read) */ + /* jpeg_read_scanlines(...); */ + + /* Here we use the library's state variable cinfo.output_scanline as the + * loop counter, so that we don't have to keep track ourselves. + */ + int x = 0; + while (_cinfo.output_scanline < _cinfo.output_height) { + /* jpeg_read_scanlines expects an array of pointers to scanlines. + * Here the array is only one element long, but you could ask for + * more than one scanline at a time if that's more convenient. + */ + jpeg_read_scanlines(&_cinfo, buffer, 1); + /* Assume put_scanline_someplace wants a pointer and sample count. */ + //put_scanline_someplace(buffer[0], row_stride); + JSAMPROW bufptr = buffer[0]; + for (int i = 0; i < row_stride; i += _cinfo.output_components) { + if (_cinfo.output_components == 1) { + xelval val = (xelval)bufptr[i]; + nassertr(x < _x_size * _y_size, 0); + PNM_ASSIGN1(array[x], val); + } else { + xelval red, grn, blu; + red = (xelval)bufptr[i]; + grn = (xelval)bufptr[i+1]; + blu = (xelval)bufptr[i+2]; + nassertr(x < _x_size * _y_size, 0); + PPM_ASSIGN(array[x], red, grn, blu); + } + x++; + } + } + + /* Step 7: Finish decompression */ + + jpeg_finish_decompress(&_cinfo); + + /* We can ignore the return value since suspension is not possible + * with the stdio data source. + */ + + /* At this point you may want to check to see whether any corrupt-data + * warnings occurred (test whether jerr.pub.num_warnings is nonzero). + */ + if (_jerr.pub.num_warnings) { + pnmimage_jpg_cat.warning() + << "Jpeg data may be corrupt" << endl; + } + + return _y_size; +} diff --git a/panda/src/pnmimagetypes/pnmFileTypeJPG2000Writer.cxx b/panda/src/pnmimagetypes/pnmFileTypeJPG2000Writer.cxx new file mode 100644 index 0000000000..95282516c5 --- /dev/null +++ b/panda/src/pnmimagetypes/pnmFileTypeJPG2000Writer.cxx @@ -0,0 +1,186 @@ +// Filename: pnmFileTypeJPGWriter.cxx +// Created by: mike (19Jun00) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#include "pnmFileTypeJPG2000.h" +#include "config_pnmimagetypes.h" + +#include +#include + +extern "C" { +#include +} + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::Writer::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +PNMFileTypeJPG2000::Writer:: +Writer(PNMFileType *type, FILE *file, bool owns_file) : + PNMWriter(type, file, owns_file) +{ +} + + +//////////////////////////////////////////////////////////////////// +// Function: PNMFileTypeJPG2000::Writer::write_data +// Access: Public, Virtual +// Description: Writes out an entire image all at once, including the +// header, based on the image data stored in the given +// _x_size * _y_size array and alpha pointers. (If the +// image type has no alpha channel, alpha is ignored.) +// Returns the number of rows correctly written. +// +// It is the user's responsibility to fill in the header +// data via calls to set_x_size(), set_num_channels(), +// etc., or copy_header_from(), before calling +// write_data(). +// +// It is important to delete the PNMWriter class after +// successfully writing the data. Failing to do this +// may result in some data not getting flushed! +// +// Derived classes need not override this if they +// instead provide supports_streaming() and write_row(), +// below. +//////////////////////////////////////////////////////////////////// +int PNMFileTypeJPG2000::Writer:: +write_data(xel *array, xelval *) { + if (_y_size<=0 || _x_size<=0) { + return 0; + } + + /* This struct contains the JPEG compression parameters and pointers to + * working space (which is allocated as needed by the JPEG library). + * It is possible to have several such structures, representing multiple + * compression/decompression processes, in existence at once. We refer + * to any one struct (and its associated working data) as a "JPEG object". + */ + struct jpeg_compress_struct cinfo; + /* This struct represents a JPEG error handler. It is declared separately + * because applications often want to supply a specialized error handler + * (see the second half of this file for an example). But here we just + * take the easy way out and use the standard error handler, which will + * print a message on stderr and call exit() if compression fails. + * Note that this struct must live as long as the main JPEG parameter + * struct, to avoid dangling-pointer problems. + */ + struct jpeg_error_mgr jerr; + /* More stuff */ + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + int row_stride; /* physical row width in image buffer */ + + /* Step 1: allocate and initialize JPEG compression object */ + + /* We have to set up the error handler first, in case the initialization + * step fails. (Unlikely, but it could happen if you are out of memory.) + * This routine fills in the contents of struct jerr, and returns jerr's + * address which we place into the link field in cinfo. + */ + cinfo.err = jpeg_std_error(&jerr); + + /* Now we can initialize the JPEG compression object. */ + jpeg_create_compress(&cinfo); + + /* Step 2: specify data destination (eg, a file) */ + /* Note: steps 2 and 3 can be done in either order. */ + + /* Here we use the library-supplied code to send compressed data to a + * stdio stream. You can also write your own code to do something else. + * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that + * requires it in order to write binary files. + */ + jpeg_stdio_dest(&cinfo, _file); + + /* Step 3: set parameters for compression */ + + /* First we supply a description of the input image. + * Four fields of the cinfo struct must be filled in: + */ + cinfo.image_width = _x_size; /* image width and height, in pixels */ + cinfo.image_height = _y_size; + if (is_grayscale()) { + cinfo.input_components = 1; + cinfo.in_color_space = JCS_GRAYSCALE; + } else { + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + } + /* Now use the library's routine to set default compression parameters. + * (You must set at least cinfo.in_color_space before calling this, + * since the defaults depend on the source color space.) + */ + jpeg_set_defaults(&cinfo); + /* Now you can set any non-default parameters you wish to. + * Here we just illustrate the use of quality (quantization table) scaling: + */ + jpeg_set_quality(&cinfo, jpeg_quality, TRUE /* limit to baseline-JPEG values */); + + /* Step 4: Start compressor */ + + /* TRUE ensures that we will write a complete interchange-JPEG file. + * Pass TRUE unless you are very sure of what you're doing. + */ + jpeg_start_compress(&cinfo, TRUE); + + /* Step 5: while (scan lines remain to be written) */ + /* jpeg_write_scanlines(...); */ + + /* Here we use the library's state variable cinfo.next_scanline as the + * loop counter, so that we don't have to keep track ourselves. + * To keep things simple, we pass one scanline per call; you can pass + * more if you wish, though. + */ + row_stride = _x_size * cinfo.input_components; /* JSAMPLEs per row in image_buffer */ + + int x = 0; + JSAMPROW row = new JSAMPLE[row_stride]; + while (cinfo.next_scanline < cinfo.image_height) { + /* jpeg_write_scanlines expects an array of pointers to scanlines. + * Here the array is only one element long, but you could pass + * more than one scanline at a time if that's more convenient. + */ + for (int i = 0; i < row_stride; i += cinfo.input_components) { + if (cinfo.input_components == 1) { + row[i] = (JSAMPLE)(MAXJSAMPLE * PPM_GETB(array[x])/_maxval); + } else { + row[i] = (JSAMPLE)(MAXJSAMPLE * PPM_GETR(array[x])/_maxval); + row[i+1] = (JSAMPLE)(MAXJSAMPLE * PPM_GETG(array[x])/_maxval); + row[i+2] = (JSAMPLE)(MAXJSAMPLE * PPM_GETB(array[x])/_maxval); + } + x++; + } + //row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; + //(void) jpeg_write_scanlines(&cinfo, row_pointer, 1); + row_pointer[0] = row; + (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + delete row; + + /* Step 6: Finish compression */ + + jpeg_finish_compress(&cinfo); + + /* Step 7: release JPEG compression object */ + + /* This is an important step since it will release a good deal of memory. */ + jpeg_destroy_compress(&cinfo); + + return _y_size; +} diff --git a/panda/src/pnmimagetypes/pnmimagetypes_composite4.cxx b/panda/src/pnmimagetypes/pnmimagetypes_composite4.cxx new file mode 100644 index 0000000000..3ab6d64bb4 --- /dev/null +++ b/panda/src/pnmimagetypes/pnmimagetypes_composite4.cxx @@ -0,0 +1,5 @@ + +#include "pnmFileTypeJPG2000.cxx" +#include "pnmFileTypeJPG2000Reader.cxx" +#include "pnmFileTypeJPG2000Writer.cxx" +