OSDN Git Service

#xxxxx DTXViewerのプロジェクトを追加。
[dtxmania/dtxmania.git] / DTXViewerプロジェクト / @FDK10プロジェクト / LoadJPEG.cpp
diff --git a/DTXViewerプロジェクト/@FDK10プロジェクト/LoadJPEG.cpp b/DTXViewerプロジェクト/@FDK10プロジェクト/LoadJPEG.cpp
new file mode 100644 (file)
index 0000000..b0d122a
--- /dev/null
@@ -0,0 +1,198 @@
+#include "stdafx.h"
+#include <windows.h>
+#include <stdio.h>
+#include <setjmp.h>
+#include "jpeglib.h"
+#include "LoadJPEG.h"
+
+namespace FDK {
+       namespace Graphics {
+
+// \93Æ\8e©\82Ì\83G\83\89\81[\83n\83\93\83h\83\8a\83\93\83O\82ð\8ds\82¤\8fê\8d\87\8eg\97p
+struct my_error_mgr {
+  struct jpeg_error_mgr pub;   /* "public" fields */
+
+  // \93Æ\8e©\82Ì\8ag\92£\95\94\95ª
+  jmp_buf setjmp_buffer;       /* for return to caller */
+};
+
+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);
+
+  // setjmp \82Ö\96ß\82é
+  longjmp(myerr->setjmp_buffer, 1);
+}
+
+int LoadJPEG( FILE* fp, BITMAPINFO** lppInfo, BYTE** lppBMP )
+{
+       BITMAPINFO* lpInfo = *lppInfo = NULL;
+       BYTE* lpBMP = *lppBMP = NULL;
+
+       // jpeg \83\89\83C\83u\83\89\83\8a\82Å\82Í\8e\9f\82Ì\82Q\82Â\82Ì\8d\\91¢\91Ì\82ª\8eg\82í\82ê\82é
+    struct jpeg_decompress_struct cinfo;
+    struct my_error_mgr jerr;
+
+    JSAMPARRAY buffer;              /* \8ds\8fo\97Í\83o\83b\83t\83@ */
+    int                        row_stride;          /* \8fo\97Í\83o\83b\83t\83@\82Ì\95¨\97\9d\8ds\95\9d(bytes) */
+    int                        image_width;
+    int                        image_height;
+       int                     image_bpp;
+       int                     image_num_palette;
+       RGBQUAD*        image_palette;
+       UCHAR*          bmp_image;
+    int                        bmp_row;
+    int                        bmp_row_bytes;
+    int                        bmp_image_size;
+
+    // \83G\83\89\81[\82Ì\83n\83\93\83h\83\8a\83\93\83O
+    cinfo.err = jpeg_std_error(&jerr.pub);
+    jerr.pub.error_exit = my_error_exit;
+
+    // \88È\8d~\82Ì jpeg \83\89\83C\83u\83\89\83\8a\93à\82Å\83G\83\89\81[\82ª\90\82\82½\8fê\8d\87\81A\8e\91\8c¹\82ð\8aJ\95ú\82µ\82Ä\8fI\82í\82é\81B
+    if (setjmp(jerr.setjmp_buffer)) {
+        jpeg_destroy_decompress(&cinfo);
+               if( lpInfo ) free( lpInfo );
+               if( lpBMP ) free( lpBMP );
+        return 0;
+    }
+
+       // \89ð\93\80\8aJ\8en
+    jpeg_create_decompress( &cinfo );  // \8d\\91¢\91Ì\82Ì\8f\89\8aú\90Ý\92è
+    jpeg_stdio_src( &cinfo, fp );              // \83t\83@\83C\83\8b\93ü\97Í\83n\83\93\83h\83\8b\82Ì\90Ý\92è
+    jpeg_read_header( &cinfo, true );  // \83t\83@\83C\83\8b\82Ì\8fî\95ñ\83w\83b\83_\82Ì\93Ç\8d\9e\82Ý
+    jpeg_start_decompress( &cinfo );   // \89ð\93\80\82Ì\8aJ\8en
+
+    // DIB \82Ì\83C\83\81\81[\83W\8fî\95ñ\8eæ\93¾\81i\8f\89\8aú\89»\81j
+    image_width                        = cinfo.image_width;
+    image_height               = cinfo.image_height;
+       image_bpp                       = 0;
+       image_num_palette       = 0;
+       image_palette           = NULL;
+
+       // bpp \82Æ\83p\83\8c\83b\83g\82Ì\8eæ\93¾
+       switch( cinfo.out_color_space )
+       {
+       case JCS_GRAYSCALE:
+               if( cinfo.num_components == 1 )
+               {
+                       image_bpp = 8;
+                       image_num_palette = 256;
+                       image_palette = (RGBQUAD *) malloc( sizeof(RGBQUAD) * 256 );
+                       for( int x = 0; x < 256; x++ )
+                       {
+                               image_palette[x].rgbBlue = image_palette[x].rgbGreen = image_palette[x].rgbRed = x;
+                               image_palette[x].rgbReserved = 0;
+                       }
+               }
+               break;
+
+       case JCS_RGB:
+               if( cinfo.num_components == 3 )
+                       image_bpp = 24;
+               break;
+
+       case JCS_CMYK:
+               if( cinfo.num_components == 4 )
+                       image_bpp = 24;                                 // \82P\90F\82S\83o\83C\83g\82Å\82à 24bpp \82Æ\82·\82é
+               break;
+       }
+       
+       // bpp == 0 \82È\82ç\96¢\91Î\89\9e\83t\83H\81[\83}\83b\83g\82Æ\82Ý\82È\82µ\82Ä\8bA\8aÒ
+       if( image_bpp == 0 )
+       {
+               jpeg_destroy_decompress( &cinfo );
+               return 0;
+       }
+
+    // \8ds\83o\83b\83t\83@\82Ì\97Ì\88æ\90Ý\92è
+    row_stride = cinfo.output_width * cinfo.output_components;
+    buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
+    if( !buffer ) goto SKIP1;
+
+    // BMP \91¤\83f\81[\83^\97Ì\88æ\82Ì\8f\80\94õ
+       if( lpBMP ) { free( lpBMP ); lpBMP = NULL; }
+       bmp_row_bytes =  ( ( image_width * (image_bpp / 8) + 3 ) / 4 ) * 4;             // DIB \82Ì\8ds\82Í DWORD \8b«\8aE\82Å\8fI\82í\82é\95K\97v\82ª\82 \82é
+    bmp_image_size = bmp_row_bytes * image_height;
+    bmp_image = (UCHAR*) lpBMP = (BYTE*) malloc( bmp_image_size );
+
+       // \82P\8ds\82¸\82Â\93Ç\82Ý\81A\83o\83b\83t\83@\82Ö\8ai\94[\82·\82é
+    bmp_row = image_height - 1;
+    while( cinfo.output_scanline < cinfo.output_height )
+       {
+        int i;
+        UCHAR *src, *dest;
+
+        jpeg_read_scanlines( &cinfo, buffer, 1 );
+
+        src = buffer[ 0 ];
+        dest = &bmp_image[ bmp_row_bytes * bmp_row-- ];
+
+               switch( cinfo.out_color_space )
+               {
+               case JCS_GRAYSCALE:
+                       memcpy( dest, src, cinfo.output_width );
+                       break;
+
+               case JCS_RGB:
+                       for( i = 0; i < row_stride; i += 3 )
+                       {
+                               *dest++ = src[ i+2 ];
+                               *dest++ = src[ i+1 ];
+                               *dest++ = src[ i+0 ];
+                       }
+               for( i = 0; i < bmp_row_bytes - row_stride; i++ )      // DWORD \8b«\8aE\95â\90³(0\82Å\96\84\82ß\82é)
+                               *dest++ = 0;
+                       break;
+
+               case JCS_CMYK:
+                       for( i = 0; i < row_stride; i += 4 )
+                       {
+                               *dest++ = ( src[ i+2 ] * src[ i+3 ] ) / 255;
+                               *dest++ = ( src[ i+1 ] * src[ i+3 ] ) / 255;
+                               *dest++ = ( src[ i+0 ] * src[ i+3 ] ) / 255;
+                       }
+               for( i = 0; i < bmp_row_bytes - row_stride; i++ )      // DWORD \8b«\8aE\95â\90³(0\82Å\96\84\82ß\82é)
+                               *dest++ = 0;
+                       break;
+               }
+    }
+
+SKIP1:;
+       // \89ð\93\80\8fI\97¹
+       jpeg_finish_decompress( &cinfo );
+       jpeg_destroy_decompress( &cinfo );
+
+       // BITMAP \8dì\90¬
+       if( lpInfo ) { free( lpInfo ); lpInfo = NULL; }
+       lpInfo = (BITMAPINFO*) malloc( sizeof( BITMAPINFOHEADER ) + (sizeof(RGBQUAD) * image_num_palette) );
+    memset( &(lpInfo->bmiHeader), 0, sizeof( BITMAPINFOHEADER ) + (sizeof(RGBQUAD) * image_num_palette) );
+       lpInfo->bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
+       lpInfo->bmiHeader.biWidth = image_width;
+       lpInfo->bmiHeader.biHeight = image_height;
+       lpInfo->bmiHeader.biPlanes = 1;
+       lpInfo->bmiHeader.biBitCount = image_bpp;
+       lpInfo->bmiHeader.biClrUsed  = image_num_palette;
+       lpInfo->bmiHeader.biSizeImage = bmp_image_size;
+       if( image_num_palette > 0 )
+       {
+               // \83p\83\8c\83b\83g\82ª\82 \82é\82Ì\82Í 256\8aK\92²\83O\83\8c\81[\83X\83P\81[\83\8b\82¾\82¯\81i\82Æ\8c\88\82ß\95t\82¯\82é\81j
+               for( int i = 0; i < 256; i++ )
+               {
+                       lpInfo->bmiColors[i].rgbBlue = lpInfo->bmiColors[i].rgbGreen = lpInfo->bmiColors[i].rgbRed = i;
+                       lpInfo->bmiColors[i].rgbReserved = 0;
+               }
+       }
+
+       if( image_palette ) { free( image_palette ); image_palette = NULL; }
+       *lppInfo = lpInfo;
+       *lppBMP = lpBMP;
+    return 1;
+}
+       }//Graphics
+}//FDK
\ No newline at end of file