Browse Source

*** empty log message ***

Mike Goslin 25 years ago
parent
commit
32ce502fbd

+ 1 - 1
panda/src/framework/framework.cxx

@@ -1067,7 +1067,7 @@ int framework_main(int argc, char *argv[]) {
     RenderRelation *arc = new RenderRelation(root, geomnode, 10);
     RenderRelation *arc = new RenderRelation(root, geomnode, 10);
     first_arc = arc;
     first_arc = arc;
 
 
-    Texture *tex = TexturePool::load_texture("rock-floor.rgb");
+    Texture *tex = TexturePool::load_texture("rock-floor.jpg");
     if (tex != (Texture *)NULL) {
     if (tex != (Texture *)NULL) {
       tex->set_minfilter(Texture::FT_linear);
       tex->set_minfilter(Texture::FT_linear);
       tex->set_magfilter(Texture::FT_linear);
       tex->set_magfilter(Texture::FT_linear);

+ 4 - 0
panda/src/pnmimagetypes/Sources.pp

@@ -1,4 +1,5 @@
 #define OTHER_LIBS interrogatedb:c dconfig:c dtoolutil:c dtoolbase:c dtool:m
 #define OTHER_LIBS interrogatedb:c dconfig:c dtoolutil:c dtoolbase:c dtool:m
+#define USE_JPEG yes
 
 
 #begin lib_target
 #begin lib_target
   #define TARGET pnmimagetypes
   #define TARGET pnmimagetypes
@@ -17,5 +18,8 @@
     pnmFileTypeYUV.cxx pnmFileTypeYUV.h \
     pnmFileTypeYUV.cxx pnmFileTypeYUV.h \
     color.c colrops.c resolu.c header.c
     color.c colrops.c resolu.c header.c
 
 
+  #define IF_JPEG_SOURCES \
+    pnmFileTypeJPG.cxx pnmFileTypeJPGReader.cxx pnmFileTypeJPGWriter.cxx
+
 #end lib_target
 #end lib_target
 
 

+ 10 - 0
panda/src/pnmimagetypes/config_pnmimagetypes.cxx

@@ -13,6 +13,9 @@
 #include "pnmFileTypeIMG.h"
 #include "pnmFileTypeIMG.h"
 #include "pnmFileTypeSoftImage.h"
 #include "pnmFileTypeSoftImage.h"
 #include "pnmFileTypeBMP.h"
 #include "pnmFileTypeBMP.h"
+#ifdef HAVE_JPEG
+  #include "pnmFileTypeJPG.h"
+#endif
 #include "sgi.h"
 #include "sgi.h"
 
 
 #include <config_pnmimage.h>
 #include <config_pnmimage.h>
@@ -30,6 +33,7 @@ NotifyCategoryDef(pnmimage_yuv, pnmimage_cat);
 NotifyCategoryDef(pnmimage_img, pnmimage_cat);
 NotifyCategoryDef(pnmimage_img, pnmimage_cat);
 NotifyCategoryDef(pnmimage_soft, pnmimage_cat);
 NotifyCategoryDef(pnmimage_soft, pnmimage_cat);
 NotifyCategoryDef(pnmimage_bmp, pnmimage_cat);
 NotifyCategoryDef(pnmimage_bmp, pnmimage_cat);
+NotifyCategoryDef(pnmimage_jpg, pnmimage_cat);
 
 
 int sgi_storage_type = STORAGE_RLE;
 int sgi_storage_type = STORAGE_RLE;
 const string sgi_imagename = config_pnmimagetypes.GetString("sgi-imagename", "");
 const string sgi_imagename = config_pnmimagetypes.GetString("sgi-imagename", "");
@@ -61,6 +65,9 @@ ConfigureFn(config_pnmimagetypes) {
   PNMFileTypeIMG::init_type();
   PNMFileTypeIMG::init_type();
   PNMFileTypeSoftImage::init_type();
   PNMFileTypeSoftImage::init_type();
   PNMFileTypeBMP::init_type();
   PNMFileTypeBMP::init_type();
+#ifdef HAVE_JPEG
+  PNMFileTypeJPG::init_type();
+#endif
 
 
   string sgi_storage_type_str = 
   string sgi_storage_type_str = 
     config_pnmimagetypes.GetString("sgi-storage-type", "rle");
     config_pnmimagetypes.GetString("sgi-storage-type", "rle");
@@ -97,4 +104,7 @@ ConfigureFn(config_pnmimagetypes) {
   tr->register_type(new PNMFileTypeIMG);
   tr->register_type(new PNMFileTypeIMG);
   tr->register_type(new PNMFileTypeSoftImage);
   tr->register_type(new PNMFileTypeSoftImage);
   tr->register_type(new PNMFileTypeBMP);
   tr->register_type(new PNMFileTypeBMP);
+#ifdef HAVE_JPEG
+  tr->register_type(new PNMFileTypeJPG);
+#endif
 }
 }

+ 1 - 0
panda/src/pnmimagetypes/config_pnmimagetypes.h

@@ -18,6 +18,7 @@ NotifyCategoryDecl(pnmimage_yuv, EXPCL_PANDA, EXPTP_PANDA);
 NotifyCategoryDecl(pnmimage_img, EXPCL_PANDA, EXPTP_PANDA);
 NotifyCategoryDecl(pnmimage_img, EXPCL_PANDA, EXPTP_PANDA);
 NotifyCategoryDecl(pnmimage_soft, EXPCL_PANDA, EXPTP_PANDA);
 NotifyCategoryDecl(pnmimage_soft, EXPCL_PANDA, EXPTP_PANDA);
 NotifyCategoryDecl(pnmimage_bmp, EXPCL_PANDA, EXPTP_PANDA);
 NotifyCategoryDecl(pnmimage_bmp, EXPCL_PANDA, EXPTP_PANDA);
+NotifyCategoryDecl(pnmimage_jpg, EXPCL_PANDA, EXPTP_PANDA);
 
 
 extern int sgi_storage_type;
 extern int sgi_storage_type;
 extern const string sgi_imagename;
 extern const string sgi_imagename;

+ 120 - 0
panda/src/pnmimagetypes/pnmFileTypeJPG.cxx

@@ -0,0 +1,120 @@
+// Filename: pnmFileTypeJPG.cxx
+// Created by:  mike (19Jun00)
+// 
+////////////////////////////////////////////////////////////////////
+
+#include "pnmFileTypeJPG.h"
+#include "config_pnmimagetypes.h"
+
+static const char * const extensions[] = {
+  "jpg"
+};
+static const int num_extensions = sizeof(extensions) / sizeof(const char *);
+
+TypeHandle PNMFileTypeJPG::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: PNMFileTypeJPG::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+PNMFileTypeJPG::
+PNMFileTypeJPG() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PNMFileTypeJPG::get_name
+//       Access: Public, Virtual
+//  Description: Returns a few words describing the file type.
+////////////////////////////////////////////////////////////////////
+string PNMFileTypeJPG::
+get_name() const {
+  return "Jpeg";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PNMFileTypeJPG::get_num_extensions
+//       Access: Public, Virtual
+//  Description: Returns the number of different possible filename
+//               extensions associated with this particular file type.
+////////////////////////////////////////////////////////////////////
+int PNMFileTypeJPG::
+get_num_extensions() const {
+  return num_extensions;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PNMFileTypeJPG::get_extension
+//       Access: Public, Virtual
+//  Description: Returns the nth possible filename extension
+//               associated with this particular file type, without a
+//               leading dot.
+////////////////////////////////////////////////////////////////////
+string PNMFileTypeJPG::
+get_extension(int n) const {
+  nassertr(n >= 0 && n < num_extensions, string());
+  return extensions[n];
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PNMFileTypeJPG::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 PNMFileTypeJPG::
+get_suggested_extension() const {
+  return "bmp";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PNMFileTypeJPG::has_magic_number
+//       Access: Public, Virtual
+//  Description: Returns true if this particular file type uses a
+//               magic number to identify it, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool PNMFileTypeJPG::
+has_magic_number() const {
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PNMFileTypeJPG::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 PNMFileTypeJPG::
+matches_magic_number(const string &magic_number) const {
+  nassertr(magic_number.size() >= 2, false);
+  return (magic_number.substr(0, 2) == "BM");
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PNMFileTypeJPG::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 *PNMFileTypeJPG::
+make_reader(FILE *file, bool owns_file, const string &magic_number) {
+  init_pnm();
+  return new Reader(this, file, owns_file, magic_number);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PNMFileTypeJPG::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 *PNMFileTypeJPG::
+make_writer(FILE *file, bool owns_file) {
+  init_pnm();
+  return new Writer(this, file, owns_file);
+}
+

+ 91 - 0
panda/src/pnmimagetypes/pnmFileTypeJPG.h

@@ -0,0 +1,91 @@
+// Filename: pnmFileTypeJPG.h
+// Created by:  mike (17Jun00)
+// 
+////////////////////////////////////////////////////////////////////
+
+#ifndef PNMFILETYPEJPG_H
+#define PNMFILETYPEJPG_H
+
+#include <pandabase.h>
+
+#include <pnmFileType.h>
+#include <pnmReader.h>
+#include <pnmWriter.h>
+
+extern "C" {
+#include <jpeglib.h>
+}
+
+////////////////////////////////////////////////////////////////////
+// 	 Class : PNMFileTypeJPG
+// Description : For reading and writing Jpeg files.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA PNMFileTypeJPG : public PNMFileType {
+public:
+  PNMFileTypeJPG();
+
+  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);
+
+    virtual int read_data(xel *array, xelval *alpha);
+
+  private:
+    struct jpeg_decompress_struct cinfo;
+    FILE *_my_file;
+    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);
+  };
+
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    PNMFileType::init_type();
+    register_type(_type_handle, "PNMFileTypeJPG",
+                  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
+
+  

+ 181 - 0
panda/src/pnmimagetypes/pnmFileTypeJPGReader.cxx

@@ -0,0 +1,181 @@
+// Filename: pnmFileTypeJPGReader.cxx
+// Created by:  mike (19Jun00)
+// 
+////////////////////////////////////////////////////////////////////
+
+#include "pnmFileTypeJPG.h"
+#include "config_pnmimagetypes.h"
+#include <typedef.h>
+
+extern "C" {
+#include <jpeglib.h>
+#include <setjmp.h>
+}
+
+struct my_error_mgr {
+  struct jpeg_error_mgr pub;
+  jmp_buf setjmp_buffer;
+};
+
+typedef struct my_error_mgr * my_error_ptr;
+
+METHODDEF(void) my_error_exit(j_common_ptr cinfo) {
+  my_error_ptr myerr = (my_error_ptr) cinfo->err;
+  (*cinfo->err->output_message) (cinfo);
+  longjmp(myerr->setjmp_buffer, 1);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PNMFileTypeJPG::Reader::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+PNMFileTypeJPG::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);
+
+  /* We use our private extension JPEG error handler.
+   * Note that this struct must live as long as the main JPEG parameter
+   * struct, to avoid dangling-pointer problems.
+   */
+  struct my_error_mgr jerr;
+
+  /* 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);
+  jerr.pub.error_exit = my_error_exit;
+  /* Establish the setjmp return context for my_error_exit to use. */
+  if (setjmp(jerr.setjmp_buffer)) {
+    /* If we get here, the JPEG code has signaled an error.
+     * We need to clean up the JPEG object, close the input file, and return.
+     */
+    jpeg_destroy_decompress(&cinfo);
+    fclose(file);
+    return;
+  }
+  /* 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 */
+
+  /* In this example, we don't need to change any of the defaults set by
+   * jpeg_read_header(), so we do nothing here.
+   */
+
+  /* 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;
+  _my_file = file;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: PNMFileTypeJPG::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 PNMFileTypeJPG::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.
+   */
+  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);
+    int x = 0;
+    for (int i = 0; i < cinfo.output_width; i += cinfo.output_components) {
+      if (cinfo.output_components == 1) {
+	xelval val = (uchar)buffer[i];
+	PNM_ASSIGN1(array[x++], val);
+      } else {
+        xelval red, grn, blu;
+        red = (uchar)buffer[i];
+        grn = (uchar)buffer[i+1];
+        blu = (uchar)buffer[i+2];
+        PPM_ASSIGN(array[x++], red, grn, blu);
+      }
+    } 
+  }
+
+  /* Step 7: Finish decompression */
+
+  jpeg_finish_decompress(&cinfo);
+  /* We can ignore the return value since suspension is not possible
+   * with the stdio data source.
+   */
+
+  /* Step 8: Release JPEG decompression object */
+
+  /* This is an important step since it will release a good deal of memory. */
+  jpeg_destroy_decompress(&cinfo);
+
+  /* After finish_decompress, we can close the input file.
+   * Here we postpone it until after no more JPEG errors are possible,
+   * so as to simplify the setjmp error logic above.  (Actually, I don't
+   * think that jpeg_destroy can do an error exit, but why assume anything...)
+   */
+  fclose(_my_file);
+
+  /* At this point you may want to check to see whether any corrupt-data
+   * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
+   */
+  return _y_size;
+}

+ 56 - 0
panda/src/pnmimagetypes/pnmFileTypeJPGWriter.cxx

@@ -0,0 +1,56 @@
+// Filename: pnmFileTypeJPGWriter.cxx
+// Created by:  mike (19Jun00)
+// 
+////////////////////////////////////////////////////////////////////
+
+#include "pnmFileTypeJPG.h"
+#include "config_pnmimagetypes.h"
+
+#include <pnmImage.h>
+#include <pnmWriter.h>
+
+extern "C" {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PNMFileTypeJPG::Writer::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+PNMFileTypeJPG::Writer::
+Writer(PNMFileType *type, FILE *file, bool owns_file) :
+  PNMWriter(type, file, owns_file)
+{
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: PNMFileTypeJPG::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 PNMFileTypeJPG::Writer::
+write_data(xel *array, xelval *) {
+  if (_y_size<=0 || _x_size<=0) {
+    return 0;
+  }
+
+  return _y_size;
+}