Mike Goslin 25 лет назад
Родитель
Сommit
1dd4581082

+ 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);
     first_arc = arc;
 
-    Texture *tex = TexturePool::load_texture("rock-floor.rgb");
+    Texture *tex = TexturePool::load_texture("rock-floor.jpg");
     if (tex != (Texture *)NULL) {
       tex->set_minfilter(Texture::FT_linear);
       tex->set_magfilter(Texture::FT_linear);

+ 8 - 2
panda/src/pnmimagetypes/pnmFileTypeJPG.h

@@ -14,6 +14,7 @@
 
 extern "C" {
 #include <jpeglib.h>
+#include <setjmp.h>
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -45,8 +46,13 @@ public:
     virtual int read_data(xel *array, xelval *alpha);
 
   private:
-    struct jpeg_decompress_struct cinfo;
-    FILE *_my_file;
+    struct jpeg_decompress_struct _cinfo;
+    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;

+ 30 - 65
panda/src/pnmimagetypes/pnmFileTypeJPGReader.cxx

@@ -7,24 +7,6 @@
 #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
@@ -37,36 +19,21 @@ Reader(PNMFileType *type, FILE *file, bool owns_file, string magic_number) :
   // 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;
-  }
+  _cinfo.err = jpeg_std_error(&_jerr.pub);
+
   /* Now we can initialize the JPEG decompression object. */
-  jpeg_create_decompress(&cinfo);
+  jpeg_create_decompress(&_cinfo);
 
   /* Step 2: specify data source (eg, a file) */
 
-  jpeg_stdio_src(&cinfo, file);
+  jpeg_stdio_src(&_cinfo, file);
 
   /* Step 3: read file parameters with jpeg_read_header() */
 
-  jpeg_read_header(&cinfo, TRUE);
+  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.
@@ -81,15 +48,14 @@ Reader(PNMFileType *type, FILE *file, bool owns_file, string magic_number) :
 
   /* Step 5: Start decompressor */
 
-  jpeg_start_decompress(&cinfo);
+  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;
+  _num_channels = _cinfo.output_components;
+  _x_size = (int)_cinfo.output_width;
+  _y_size = (int)_cinfo.output_height;
 }
 
 
@@ -111,7 +77,7 @@ 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);
+  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
@@ -120,11 +86,11 @@ read_data(xel *array, xelval *) {
    * 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;
+  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);
+  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(...); */
@@ -132,24 +98,25 @@ read_data(xel *array, xelval *) {
   /* 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) {
+  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);
+    jpeg_read_scanlines(&_cinfo, buffer, 1);
     /* Assume put_scanline_someplace wants a pointer and sample count. */
     //put_scanline_someplace(buffer[0], row_stride);
+    uchar *bufptr = buffer[0];
     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];
+    for (int i = 0; i < _cinfo.output_width; i += _cinfo.output_components) {
+      if (_cinfo.output_components == 1) {
+	xelval val = bufptr[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];
+        red = (uchar)bufptr[i];
+        grn = (uchar)bufptr[i+1];
+        blu = (uchar)bufptr[i+2];
         PPM_ASSIGN(array[x++], red, grn, blu);
       }
     } 
@@ -157,25 +124,23 @@ read_data(xel *array, xelval *) {
 
   /* Step 7: Finish decompression */
 
-  jpeg_finish_decompress(&cinfo);
+  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);
+  jpeg_destroy_decompress(&_cinfo);
 
   /* 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;
 }

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

@@ -10,6 +10,7 @@
 #include <pnmWriter.h>
 
 extern "C" {
+#include <jpeglib.h>
 }
 
 ////////////////////////////////////////////////////////////////////