]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - plugins/image/jpeg.cpp
radiant: also list images from dds/textures/ as textures/ ones
[xonotic/netradiant.git] / plugins / image / jpeg.cpp
index 9386664a29f1d371484e5b1db4bf5e38e2133ce1..91fdf18e39cc54641170c71d9e8b7090b90555ef 100644 (file)
 // Leonardo Zide (leo@lokigames.com)
 //
 
-#ifdef _WIN32
-// Ugly hack so that INT32 is defined before jmorecfg.h is parsed.
-#include <basetsd.h>
-#endif
+#include "jpeg.h"
 
-#include <stdio.h>
 #include <setjmp.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
-#include <glib.h>
 
 extern "C" {
 #include <jpeglib.h>
 #include <jerror.h>
 }
 
-#include "image.h"
+#include "ifilesystem.h"
+
+#include "imagelib.h"
+
+typedef unsigned char byte;
 
 /* Expanded data source object for stdio input */
 
@@ -66,7 +66,7 @@ typedef struct {
 
 typedef my_source_mgr * my_src_ptr;
 
-#define INPUT_BUF_SIZE  4096    /* choose an efficiently fread'able size */
+const int INPUT_BUF_SIZE = 4096;    /* choose an efficiently fread'able size */
 
 
 /*
@@ -313,8 +313,14 @@ static void j_putRGBAScanline( unsigned char* jpegline, int widthPix, unsigned c
                *oRed = iRed;
                *oGrn = iGrn;
                *oBlu = iBlu;
-               // ydnar: see bug 900
-               *oAlp = 255; //%        iAlp;
+
+               //!\todo fix jpeglib, it leaves alpha channel uninitialised
+#if 1
+               (void) iAlp;
+               *oAlp = 255;
+#else
+               *oAlp = iAlp;
+#endif
        }
 }
 
@@ -343,68 +349,52 @@ static void j_putGrayScanlineToRGB( unsigned char* jpegline, int widthPix, unsig
        }
 }
 
-static int LoadJPGBuff( void *src_buffer, int src_size, unsigned char **pic, int *width, int *height ) {
+static Image* LoadJPGBuff_( const void *src_buffer, int src_size ){
        struct jpeg_decompress_struct cinfo;
        struct my_jpeg_error_mgr jerr;
-       JSAMPARRAY buffer;
-       int row_stride, size;
 
        cinfo.err = jpeg_std_error( &jerr.pub );
        jerr.pub.error_exit = my_jpeg_error_exit;
 
-       if ( setjmp( jerr.setjmp_buffer ) ) {
-               *pic = (unsigned char*)errormsg;
+       if ( setjmp( jerr.setjmp_buffer ) ) { //< TODO: use c++ exceptions instead of setjmp/longjmp to handle errors
+               globalErrorStream() << "WARNING: JPEG library error: " << errormsg << "\n";
                jpeg_destroy_decompress( &cinfo );
-               return -1;
+               return 0;
        }
 
        jpeg_create_decompress( &cinfo );
-       jpeg_buffer_src( &cinfo, src_buffer, src_size );
+       jpeg_buffer_src( &cinfo, const_cast<void*>( src_buffer ), src_size );
        jpeg_read_header( &cinfo, TRUE );
        jpeg_start_decompress( &cinfo );
 
-       row_stride = cinfo.output_width * cinfo.output_components;
+       int row_stride = cinfo.output_width * cinfo.output_components;
 
-       size = cinfo.output_width * cinfo.output_height * 4;
-       *width = cinfo.output_width;
-       *height = cinfo.output_height;
-       *pic = (unsigned char*) ( g_malloc( size + 1 ) );
-       memset( *pic, 0, size + 1 );
+       RGBAImage* image = new RGBAImage( cinfo.output_width, cinfo.output_height );
 
-       buffer = ( *cinfo.mem->alloc_sarray )( ( j_common_ptr ) & cinfo, JPOOL_IMAGE, row_stride, 1 );
+       JSAMPARRAY buffer = ( *cinfo.mem->alloc_sarray )( ( j_common_ptr ) & cinfo, JPOOL_IMAGE, row_stride, 1 );
 
        while ( cinfo.output_scanline < cinfo.output_height )
        {
                jpeg_read_scanlines( &cinfo, buffer, 1 );
 
                if ( cinfo.out_color_components == 4 ) {
-                       j_putRGBAScanline( buffer[0], cinfo.output_width, *pic, cinfo.output_scanline - 1 );
+                       j_putRGBAScanline( buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline - 1 );
                }
                else if ( cinfo.out_color_components == 3 ) {
-                       j_putRGBScanline( buffer[0], cinfo.output_width, *pic, cinfo.output_scanline - 1 );
+                       j_putRGBScanline( buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline - 1 );
                }
                else if ( cinfo.out_color_components == 1 ) {
-                       j_putGrayScanlineToRGB( buffer[0], cinfo.output_width, *pic, cinfo.output_scanline - 1 );
+                       j_putGrayScanlineToRGB( buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline - 1 );
                }
        }
 
        jpeg_finish_decompress( &cinfo );
        jpeg_destroy_decompress( &cinfo );
 
-       return 0;
+       return image;
 }
 
-void LoadJPG( const char *filename, unsigned char **pic, int *width, int *height ) {
-       unsigned char *fbuffer = NULL;
-       int nLen = vfsLoadFile( (char *)filename, (void **)&fbuffer, 0 );
-       if ( nLen == -1 ) {
-               return;
-       }
-
-       if ( LoadJPGBuff( fbuffer, nLen, pic, width, height ) != 0 ) {
-               g_FuncTable.m_pfnSysPrintf( "WARNING: JPEG library failed to load %s because %s\n", filename, *pic );
-               *pic = NULL;
-       }
-
-       vfsFreeFile( fbuffer );
+Image* LoadJPG( ArchiveFile& file ){
+       ScopedArchiveBuffer buffer( file );
+       return LoadJPGBuff_( buffer.buffer, static_cast<int>( buffer.length ) );
 }