+++ /dev/null
-/*UTF-8■*/\r
-#include "include_c.h" \r
-#pragma hdrstop\r
-\r
- \r
-/************************************************************************\r
-* Function: BmpFile2Class_loadBMP\r
-* BMP 形式のファイルを読み込みます。\r
-*\r
-* 引数:\r
-* Path - BMP file path\r
-*\r
-* 返り値:\r
-* エラーコード、0=エラーなし\r
-************************************************************************/\r
-/*[BmpFile2Class_loadBMP]*/\r
-errnum_t BmpFile2Class_loadBMP( BmpFile2Class* self, const TCHAR* Path )\r
-{\r
- BITMAPFILEHEADER bmp_header;\r
- errnum_t e;\r
- errno_t en;\r
- FILE* file = NULL;\r
- int height_abs;\r
-\r
-\r
- en= _tfopen_s( &file, Path, _T("rb") ); IF(en){e=E_ERRNO;goto fin;}\r
-\r
- fread( &bmp_header, 1, sizeof(bmp_header), file ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
- ASSERT_R( bmp_header.bfType == ('B' | ( 'M' << 8 )), e=E_OTHERS; goto fin );\r
-\r
- fread( &self->Info, 1, sizeof(self->Info), file ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
- if ( self->Info.biBitCount >= 8 ) {\r
- self->Stride = self->Info.biWidth * ( ( self->Info.biBitCount + 7 ) / 8 );\r
- } else {\r
- self->Stride = ( self->Info.biWidth * self->Info.biBitCount + 7 ) / 8;\r
- }\r
- self->Stride = ceil_4( self->Stride );\r
-\r
- if ( self->Info.biBitCount == 16 ) {\r
- fread( &self->RedMask, 1, sizeof(self->RedMask), file ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
- fread( &self->GreenMask, 1, sizeof(self->GreenMask), file ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
- fread( &self->BlueMask, 1, sizeof(self->BlueMask), file ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
- fread( &self->AlphaMask, 1, sizeof(self->AlphaMask), file ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
- }\r
- else if ( self->Info.biBitCount <= 8 ) {\r
- int color_count = 1 << self->Info.biBitCount;\r
-\r
- if ( self->Info.biClrUsed != 0 )\r
- { color_count = self->Info.biClrUsed; }\r
-\r
- e= MallocMemory( &self->Palette, color_count * sizeof(RGBQUAD) ); IF(e){goto fin;}\r
-\r
- fread( self->Palette, 1, color_count * sizeof(RGBQUAD), file );\r
- IF(ferror(file)){e=E_ERRNO;goto fin;}\r
-\r
- self->PaletteColorCount = color_count;\r
- }\r
-\r
- height_abs = self->Info.biHeight;\r
- if ( height_abs < 0 ) { height_abs = -height_abs; }\r
-\r
- ASSERT_R( self->Info.biSizeImage == 0 ||\r
- self->Info.biSizeImage == self->Stride * height_abs, goto err_og );\r
-\r
- if ( self->Info.biSizeImage == 0 )\r
- { self->Info.biSizeImage = self->Stride * height_abs; }\r
-\r
- e= FreeMemory( &self->Pixels, 0 ); IF(e){goto fin;}\r
- e= MallocMemory( &self->Pixels, self->Info.biSizeImage ); IF(e){goto fin;}\r
-\r
- fseek( file, bmp_header.bfOffBits, SEEK_SET ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
- fread( self->Pixels, self->Info.biSizeImage, 1, file ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
-\r
- e=0;\r
-fin:\r
- e= FileT_closeAndNULL( &file, e );\r
- if ( e ) {\r
- e= FreeMemory( &self->Pixels, e );\r
- }\r
- return e;\r
-\r
-err_og:\r
- Error4_printf( _T("<ERROR msg=\"BITMAPINFOHEADER::biSizeImage is invalid\"/>") );\r
- e = E_ORIGINAL;\r
- goto fin;\r
-}\r
-\r
-\r
- \r
-/************************************************************************\r
-* Function: BmpFile2Class_saveBMP\r
-* BMP 形式のファイルを書き込みます。\r
-*\r
-* 引数:\r
-* Path - BMP file path\r
-*\r
-* 返り値:\r
-* エラーコード、0=エラーなし\r
-************************************************************************/\r
-/*[BmpFile2Class_saveBMP]*/\r
-errnum_t BmpFile2Class_saveBMP( BmpFile2Class* self, const TCHAR* Path )\r
-{\r
- BITMAPFILEHEADER bmp_header;\r
- errnum_t e;\r
- errno_t en;\r
- FILE* file = NULL;\r
- int mod;\r
- int plus;\r
- int height_abs;\r
- int palette_index;\r
- int offset;\r
- uint32_t palette[16]; // RGBQUAD type\r
-\r
-\r
- height_abs = self->Info.biHeight;\r
- if ( height_abs < 0 ) { height_abs = -height_abs; }\r
-\r
- memset( &bmp_header, 0, sizeof(bmp_header) );\r
- bmp_header.bfType = 'B' | ( 'M' << 8 );\r
- bmp_header.bfSize = sizeof(bmp_header) + sizeof(self->Info) +\r
- height_abs * self->Stride;\r
-\r
- bmp_header.bfOffBits = 0x36;\r
- switch ( self->Info.biBitCount ) {\r
- case 1:\r
- bmp_header.bfSize += 2 * sizeof(RGBQUAD);\r
- bmp_header.bfOffBits += 2 * sizeof(RGBQUAD);\r
- break;\r
-\r
- case 4:\r
- bmp_header.bfSize += 16 * sizeof(RGBQUAD);\r
- bmp_header.bfOffBits += 16 * sizeof(RGBQUAD);\r
- break;\r
-\r
- case 8:\r
- bmp_header.bfSize += 256 * sizeof(RGBQUAD);\r
- bmp_header.bfOffBits += 256 * sizeof(RGBQUAD);\r
- break;\r
-\r
- case 16:\r
- bmp_header.bfSize += 4 * sizeof(RGBQUAD);\r
- bmp_header.bfOffBits += 4 * sizeof(RGBQUAD);\r
- break;\r
-\r
- case 24: break;\r
- case 32: break;\r
-\r
- default: ASSERT_R( false, e=E_OTHERS; goto fin ); break;\r
- }\r
- mod = bmp_header.bfOffBits % self->Alignment_bfOffBits;\r
- if ( mod != 0 ) {\r
- plus = - mod + self->Alignment_bfOffBits;\r
- bmp_header.bfSize += plus;\r
- bmp_header.bfOffBits += plus;\r
- }\r
-\r
- en= _tfopen_s( &file, Path, _T("wb") ); IF(en){e=E_ERRNO;goto fin;}\r
- ASSERT_R( file != NULL, e=E_OTHERS; goto fin );\r
- fwrite( &bmp_header, 1, sizeof(bmp_header), file ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
- fwrite( &self->Info, 1, sizeof(self->Info), file ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
-\r
- switch ( self->Info.biBitCount ) {\r
- case 1:\r
- palette[0] = 0x00000000; palette[1] = 0x00FFFFFF;\r
- fwrite( palette, 2, sizeof(*palette), file ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
- break;\r
- case 4:\r
- palette[0] = 0x00000000; palette[1] = 0x00111111; palette[2] = 0x00222222; palette[3] = 0x00333333;\r
- palette[4] = 0x00444444; palette[5] = 0x00555555; palette[6] = 0x00666666; palette[7] = 0x00777777;\r
- palette[8] = 0x00888888; palette[9] = 0x00999999; palette[10]= 0x00AAAAAA; palette[11]= 0x00BBBBBB;\r
- palette[12]= 0x00CCCCCC; palette[13]= 0x00DDDDDD; palette[14]= 0x00EEEEEE; palette[15]= 0x00FFFFFF;\r
- fwrite( palette, 16, sizeof(*palette), file ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
- break;\r
- case 8:\r
- for ( palette_index = 0; palette_index < 256; palette_index += 0x10 ) {\r
- palette[ 0 ] = 0x00010101 * palette_index;\r
- for ( offset = 1; offset < 0x10; offset += 1 ) {\r
- palette[ offset ] = palette[ 0 ] + 0x00010101 * offset;\r
- }\r
- fwrite( palette, 16, sizeof(*palette), file ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
- }\r
- break;\r
- case 16:\r
- palette[0] = self->RedMask; palette[1] = self->GreenMask;\r
- palette[2] = self->BlueMask; palette[3] = self->AlphaMask;\r
- fwrite( palette, 4, sizeof(*palette), file ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
- break;\r
- }\r
-\r
- fseek( file, bmp_header.bfOffBits, SEEK_SET ); IF(ferror(file)){e=E_ERRNO;goto fin;}\r
- fwrite( self->Pixels, 1, height_abs * self->Stride, file );\r
- IF(ferror(file)){e=E_ERRNO;goto fin;}\r
-\r
- e=0;\r
-fin:\r
- if ( file != NULL ) fclose( file );\r
- return e;\r
-}\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_finish] >>> \r
-************************************************************************/\r
-errnum_t BmpFile2Class_finish( BmpFile2Class* self, errnum_t e )\r
-{\r
- e= FreeMemory( &self->Pixels, e );\r
- e= FreeMemory( &self->Palette, e );\r
- return e;\r
-}\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_loadRaw16bit_Sub] >>> \r
-************************************************************************/\r
-errnum_t BmpFile2Class_loadRaw16bit_Sub( BmpFile2Class* self, TCHAR* Path, int Stride )\r
-{\r
- FILE* file = NULL;\r
- errno_t en;\r
- errnum_t e;\r
- size_t raw_size;\r
-\r
- ASSERT_R( Stride % 4 == 0, e=E_OTHERS; goto fin );\r
-\r
- en= _tfopen_s( &file, Path, _T("rb") ); IF(en){ e=E_ERRNO; goto fin; }\r
-\r
- fseek( file, 0, SEEK_END );\r
- raw_size = ftell( file );\r
- fseek( file, 0, SEEK_SET );\r
-\r
- if ( self->Pixels != NULL ) free( self->Pixels );\r
- self->Pixels = (uint8_t*) malloc( raw_size );\r
- ASSERT_R( self->Pixels != NULL, e=E_OTHERS; goto fin );\r
-\r
- fread( self->Pixels, 1, raw_size, file );\r
-\r
- self->Info.biSize = sizeof(BITMAPINFOHEADER) + 4 * sizeof(uint32_t);\r
- self->Info.biWidth = Stride / 2;\r
- self->Info.biHeight = - (LONG)( raw_size / Stride );\r
- self->Info.biPlanes = 1;\r
- self->Info.biBitCount = 16;\r
- self->Info.biCompression = BI_BITFIELDS;\r
- self->Info.biSizeImage = raw_size;\r
- self->Info.biXPelsPerMeter = 0;\r
- self->Info.biYPelsPerMeter = 0;\r
- self->Info.biClrUsed = 0;\r
- self->Info.biClrImportant = 0;\r
- self->RedMask = 0xF800;\r
- self->GreenMask = 0x07E0;\r
- self->BlueMask = 0x001F;\r
- self->AlphaMask = 0x0000;\r
- self->Stride = Stride;\r
-\r
- e=0;\r
-fin:\r
- if ( file != NULL ) fclose( file );\r
- if ( e ) {\r
- if ( self->Pixels != NULL ) free( self->Pixels );\r
- self->Pixels = NULL;\r
- }\r
- return e;\r
-}\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_loadRawRGB565] >>> \r
-************************************************************************/\r
-errnum_t BmpFile2Class_loadRawRGB565( BmpFile2Class* self, TCHAR* Path, int Stride )\r
-{\r
- errnum_t e;\r
-\r
- e= BmpFile2Class_loadRaw16bit_Sub( self, Path, Stride );\r
- self->RedMask = 0xF800;\r
- self->GreenMask = 0x07E0;\r
- self->BlueMask = 0x001F;\r
- self->AlphaMask = 0x0000;\r
-\r
- return e;\r
-}\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_loadRawARGB8888] >>> \r
-************************************************************************/\r
-errnum_t BmpFile2Class_loadRawARGB8888( BmpFile2Class* self, TCHAR* Path, int Stride )\r
-{\r
- FILE* file = NULL;\r
- errno_t en;\r
- errnum_t e;\r
- size_t raw_size;\r
-\r
- ASSERT_R( Stride % 4 == 0, e=E_OTHERS; goto fin );\r
-\r
- en= _tfopen_s( &file, Path, _T("rb") ); IF(en){ e=E_ERRNO; goto fin; }\r
-\r
- fseek( file, 0, SEEK_END );\r
- raw_size = ftell( file );\r
- fseek( file, 0, SEEK_SET );\r
-\r
- if ( self->Pixels != NULL ) free( self->Pixels );\r
- self->Pixels = (uint8_t*) malloc( raw_size );\r
- ASSERT_R( self->Pixels != NULL, e=E_OTHERS; goto fin );\r
-\r
- fread( self->Pixels, 1, raw_size, file );\r
-\r
- self->Info.biSize = sizeof(BITMAPINFOHEADER);\r
- self->Info.biWidth = Stride / 4;\r
- self->Info.biHeight = - (LONG)( raw_size / Stride );\r
- self->Info.biPlanes = 1;\r
- self->Info.biBitCount = 32;\r
- self->Info.biCompression = 0;\r
- self->Info.biSizeImage = raw_size;\r
- self->Info.biXPelsPerMeter = 0;\r
- self->Info.biYPelsPerMeter = 0;\r
- self->Info.biClrUsed = 0;\r
- self->Info.biClrImportant = 0;\r
- self->RedMask = 0;\r
- self->GreenMask = 0;\r
- self->BlueMask = 0;\r
- self->AlphaMask = 0;\r
- self->Stride = Stride;\r
-\r
- e=0;\r
-fin:\r
- if ( file != NULL ) fclose( file );\r
- if ( e ) {\r
- if ( self->Pixels != NULL ) free( self->Pixels );\r
- self->Pixels = NULL;\r
- }\r
- return e;\r
-}\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_loadRawARGB1555] >>> \r
-************************************************************************/\r
-errnum_t BmpFile2Class_loadRawARGB1555( BmpFile2Class* self, TCHAR* Path, int Stride )\r
-{\r
- errnum_t e;\r
-\r
- e= BmpFile2Class_loadRaw16bit_Sub( self, Path, Stride );\r
- self->RedMask = 0x7C00;\r
- self->GreenMask = 0x03E0;\r
- self->BlueMask = 0x001F;\r
- self->AlphaMask = 0x8000;\r
-\r
- return e;\r
-}\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_loadRawARGB4444] >>> \r
-************************************************************************/\r
-errnum_t BmpFile2Class_loadRawARGB4444( BmpFile2Class* self, TCHAR* Path, int Stride )\r
-{\r
- errnum_t e;\r
-\r
- e= BmpFile2Class_loadRaw16bit_Sub( self, Path, Stride );\r
- self->RedMask = 0x0F00;\r
- self->GreenMask = 0x00F0;\r
- self->BlueMask = 0x000F;\r
- self->AlphaMask = 0xF000;\r
-\r
- return e;\r
-}\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_loadPNG] >>> \r
-************************************************************************/\r
-errnum_t BmpFile2Class_loadPNG( BmpFile2Class* self, const TCHAR* Path )\r
-{\r
- FILE* f = NULL;\r
- png_struct* png = NULL;\r
- png_info* info = NULL;\r
- png_info* end_info = NULL;\r
- uint8_t** lines = NULL;\r
- int ret = 0;\r
- errno_t en;\r
- errnum_t e;\r
-\r
-\r
- /* Open file and Create work */\r
- en= _tfopen_s( &f, Path, _T("rb") ); IF(en)goto err_no;\r
- IF( f == NULL ){goto err;}\r
-\r
- png = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );\r
- IF( png == NULL ){goto err;}\r
- info = png_create_info_struct( png ); IF( info == NULL ){goto err;}\r
- end_info = png_create_info_struct( png ); IF( end_info == NULL ){goto err;}\r
-\r
- png_init_io( png, f );\r
-\r
-\r
- /* Read Information */\r
- {\r
- png_read_info( png, info );\r
-\r
- self->Stride = png_get_rowbytes( png, info );\r
- self->Stride = ceil_4( self->Stride );\r
-\r
- ASSERT_R( info->num_palette == 0, goto err );\r
- ASSERT_R( info->bit_depth == 8, goto err );\r
- ASSERT_R( info->color_type == PNG_COLOR_TYPE_RGB ||\r
- info->color_type == PNG_COLOR_TYPE_RGB_ALPHA, goto err );\r
-\r
- self->Info.biSize = sizeof(BITMAPINFOHEADER);\r
- self->Info.biWidth = info->width;\r
- self->Info.biHeight = info->height;\r
- self->Info.biPlanes = 1;\r
- switch ( info->color_type ) {\r
- case PNG_COLOR_TYPE_RGB: self->Info.biBitCount = 24; break;\r
- case PNG_COLOR_TYPE_RGB_ALPHA: self->Info.biBitCount = 32; break;\r
- default: ASSERT_R( false, goto err );\r
- }\r
- self->Info.biCompression = BI_RGB;\r
- self->Info.biSizeImage = self->Info.biHeight * self->Stride;\r
- self->Info.biXPelsPerMeter = 0;\r
- self->Info.biYPelsPerMeter = 0;\r
- self->Info.biClrUsed = 0;\r
- self->Info.biClrImportant = 0;\r
- }\r
-\r
- /* Read Pixels */\r
- {\r
- int i;\r
- uint8_t* left_of_line;\r
- uint_fast32_t stride = self->Stride;\r
-\r
- e= HeapMemory_free( &self->Pixels, 0 ); IF(e){goto fin;}\r
- e= HeapMemory_allocateArray( &lines, self->Info.biHeight ); IF(e){goto fin;}\r
- e= HeapMemory_allocateArray( &self->Pixels, stride * self->Info.biHeight ); IF(e){goto fin;}\r
-\r
- left_of_line = self->Pixels;\r
-\r
- for ( i = self->Info.biHeight - 1; i >= 0; i -= 1 ) {\r
- lines[ i ] = left_of_line;\r
-\r
- left_of_line[ stride - 3 ] = 0x00; /* Padding */\r
- left_of_line[ stride - 2 ] = 0x00;\r
- left_of_line[ stride - 1 ] = 0x00;\r
-\r
- left_of_line += stride;\r
- }\r
-\r
- png_set_bgr( png );\r
- png_read_image( png, lines ); /* Set to "self->Pixels" */\r
- png_read_end( png, end_info );\r
- }\r
-\r
-fin:\r
- e= HeapMemory_free( &lines, e );\r
- if ( info != NULL ) { png_destroy_info_struct( png, &info ); }\r
- if ( end_info != NULL ) { png_destroy_info_struct( png, &end_info ); }\r
- if ( png != NULL ) { png_destroy_read_struct( &png, NULL, NULL ); }\r
- if ( f != NULL ) { fclose( f ); }\r
-\r
- if ( e ) {\r
- self->Info.biWidth = 0;\r
- self->Info.biHeight = 0;\r
- e= HeapMemory_free( &self->Pixels, e );\r
- }\r
-\r
- return ret;\r
-\r
-err: e = E_OTHERS; goto fin;\r
-err_no: e = E_ERRNO; goto fin;\r
-}\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_loadJPEG] >>> \r
-************************************************************************/\r
-#ifndef LibJPEG_is\r
-#define LibJPEG_is LibJPEG_is_DLL\r
-#endif\r
-#define LibJPEG_is_Lib 1\r
-#define LibJPEG_is_DLL 2\r
-\r
-errnum_t BmpFile2Class_loadJPEG( BmpFile2Class* self, const TCHAR* Path )\r
-{\r
- struct jpeg_decompress_struct jpeg_decompress;\r
- struct jpeg_error_mgr jpeg_error;\r
- errnum_t e;\r
- FILE* file = NULL;\r
- errno_t en;\r
- char* pixels = NULL;\r
- char** pixel_line_pointers = NULL;\r
- unsigned width_stride;\r
- unsigned width_byte;\r
- bool is_jpeg_decompress = false;\r
- bool is_started_jpeg_decompress = false;\r
-#if LibJPEG_is == LibJPEG_is_DLL\r
- void* data_of_JPEG = NULL;\r
- int jpeg_size;\r
- int read_size;\r
-#endif\r
-\r
- en = _tfopen_s( &file, Path, _T("rb") ); IF(en){ e=E_ERRNO; goto fin; }\r
-\r
- // set up JPEG library and read JPEG header in the file\r
- jpeg_decompress.err = jpeg_std_error( &jpeg_error );\r
- jpeg_create_decompress( &jpeg_decompress ); is_jpeg_decompress = true;\r
- #if LibJPEG_is == LibJPEG_is_DLL\r
- fseek( file, 0, SEEK_END );\r
- jpeg_size = ftell( file );\r
- fseek( file, 0, SEEK_SET );\r
- data_of_JPEG = (char*) malloc( jpeg_size );\r
- IF( data_of_JPEG == NULL ){ e=E_FEW_MEMORY; goto fin; }\r
- read_size = fread( data_of_JPEG, 1, jpeg_size, file );\r
- ASSERT_R( read_size == jpeg_size, e=E_OTHERS; goto fin );\r
- jpeg_mem_src( &jpeg_decompress, (unsigned char*) data_of_JPEG, jpeg_size );\r
- #else\r
- jpeg_stdio_src( &jpeg_decompress, file );\r
- #endif\r
- jpeg_read_header( &jpeg_decompress, TRUE );\r
-\r
- ASSERT_R( jpeg_decompress.num_components == 3, e=E_OTHERS; goto fin );\r
-\r
- width_byte = jpeg_decompress.image_width * jpeg_decompress.num_components;\r
- width_stride = ceil_4( width_byte );\r
-\r
- pixels = (char*) malloc(\r
- width_stride * jpeg_decompress.image_height * sizeof(char) );\r
- IF(pixels == NULL){ e=E_FEW_MEMORY; goto fin; }\r
-\r
-\r
- // set pixel_line_pointers\r
- {\r
- char* p;\r
- char** pp;\r
- char** pp_over;\r
-\r
- pixel_line_pointers = (char**) malloc(\r
- jpeg_decompress.image_height * sizeof(char*) );\r
- IF(pixel_line_pointers == NULL){ e=E_FEW_MEMORY; goto fin; };\r
-\r
- p = pixels;\r
- pp_over = pixel_line_pointers + jpeg_decompress.image_height;\r
-\r
- for ( pp = pp_over - 1; pp >= pixel_line_pointers; pp -- ) {\r
- *pp = p;\r
- p += width_stride;\r
- *(int*)( p - 4 ) = 0; // fill zero to padding area at right of line\r
- }\r
- }\r
-\r
-\r
- // read pixels\r
- jpeg_start_decompress( &jpeg_decompress );\r
- is_started_jpeg_decompress = true;\r
- while ( jpeg_decompress.output_scanline < jpeg_decompress.output_height ) {\r
- char** pp = pixel_line_pointers + jpeg_decompress.output_scanline;\r
- char** pp_over;\r
-\r
- jpeg_read_scanlines( &jpeg_decompress,\r
- (JSAMPARRAY)( pixel_line_pointers + jpeg_decompress.output_scanline ),\r
- jpeg_decompress.output_height - jpeg_decompress.output_scanline );\r
-\r
- // change from RGB to BGR\r
- pp_over = pixel_line_pointers + jpeg_decompress.output_scanline;\r
- for ( ; pp < pp_over; pp ++ ) {\r
- char* p = *pp;\r
- char* p_over = p + width_byte;\r
-\r
- for ( ; p < p_over; p += jpeg_decompress.num_components ) {\r
- char value;\r
-\r
- value = *( p + 0 );\r
- *( p + 0 ) = *( p + 2 );\r
- *( p + 2 ) = value;\r
- }\r
- }\r
- }\r
-\r
-\r
- /* set self attributes */\r
- {\r
- self->Stride = width_stride;\r
-\r
- self->Info.biSize = sizeof(BITMAPINFOHEADER);\r
- self->Info.biWidth = jpeg_decompress.image_width;\r
- self->Info.biHeight = jpeg_decompress.image_height;\r
- self->Info.biPlanes = 1;\r
- self->Info.biBitCount = 24;\r
- self->Info.biCompression = BI_RGB;\r
- self->Info.biSizeImage = self->Info.biHeight * self->Stride;\r
- self->Info.biXPelsPerMeter = 0;\r
- self->Info.biYPelsPerMeter = 0;\r
- self->Info.biClrUsed = 0;\r
- self->Info.biClrImportant = 0;\r
- self->Pixels = (uint8_t*) pixels;\r
- }\r
-\r
- e=0;\r
-fin:\r
- if ( e ) {\r
- if ( pixels != NULL ) free( pixels );\r
- }\r
- if ( is_started_jpeg_decompress ) jpeg_finish_decompress( &jpeg_decompress );\r
- if ( is_jpeg_decompress ) jpeg_destroy_decompress( &jpeg_decompress );\r
- if ( pixel_line_pointers != NULL ) free( pixel_line_pointers );\r
- if ( file != NULL ) fclose( file );\r
- #if LibJPEG_is == LibJPEG_is_DLL\r
- if ( data_of_JPEG != NULL ) { free( data_of_JPEG ); }\r
- #endif\r
- return e;\r
-}\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_addAlphaChannel] >>> \r
-************************************************************************/\r
-errnum_t BmpFile2Class_addAlphaChannel( BmpFile2Class* self, uint8_t AlphaValue )\r
-{\r
- errnum_t e;\r
- uint32_t image_size;\r
- uint8_t* new_pixels;\r
- unsigned stride24;\r
- unsigned stride32;\r
- uint8_t* src; // source\r
- uint8_t* dst; // destination\r
- uint8_t* src_line_head;\r
- uint8_t* dst_line_head;\r
- int src_line_tail_offset;\r
- int dst_line_tail_offset;\r
-\r
- if ( self->Info.biBitCount == 32 ) return 0;\r
-\r
- ASSERT_R( self->Info.biBitCount == 24, goto err );\r
- ASSERT_R( self->Stride * self->Info.biHeight == self->Info.biSizeImage, goto err );\r
-\r
- stride24 = self->Stride;\r
- stride32 = self->Info.biWidth * 4;\r
-\r
- image_size = stride32 * self->Info.biHeight;\r
- new_pixels = (uint8_t*) realloc( self->Pixels, image_size );\r
- ASSERT_R( new_pixels != NULL, goto err_fm );\r
-\r
- self->Pixels = new_pixels;\r
- self->Info.biBitCount = 32;\r
- self->Stride = stride32;\r
- self->Info.biSizeImage = image_size;\r
-\r
- src_line_head = new_pixels + stride24 * (self->Info.biHeight - 1);\r
- dst_line_head = new_pixels + stride32 * (self->Info.biHeight - 1);\r
- src_line_tail_offset = (self->Info.biWidth - 1) * (24/8);\r
- dst_line_tail_offset = (self->Info.biWidth - 1) * (32/8);\r
- do {\r
- src = src_line_head + src_line_tail_offset;\r
- dst = dst_line_head + dst_line_tail_offset;\r
- do {\r
- *( dst + 3 ) = AlphaValue;\r
- *( dst + 2 ) = *( src + 2 ); // Red\r
- *( dst + 1 ) = *( src + 1 ); // Green\r
- *( dst ) = *( src ); // Blue\r
- src -= (24/8);\r
- dst -= (32/8);\r
- } while ( src >= src_line_head );\r
-\r
- src_line_head -= stride24;\r
- dst_line_head -= stride32;\r
- } while ( src_line_head >= new_pixels );\r
-\r
- e=0;\r
-fin:\r
- return e;\r
-\r
-err: e = E_OTHERS; goto fin;\r
-err_fm: e = E_FEW_MEMORY; goto fin;\r
-}\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_convertToRGB565Format] >>> \r
-************************************************************************/\r
-errnum_t BmpFile2Class_convertToRGB565Format( BmpFile2Class* self )\r
-{\r
- errnum_t e;\r
- uint32_t image_size;\r
- uint8_t* new_pixels = NULL;\r
- unsigned src_stride;\r
- unsigned stride16;\r
- uint16_t red, green, blue;\r
- uint8_t* src; // source\r
- uint8_t* dst; // destination\r
- uint8_t* src_line_head;\r
- uint8_t* dst_line_head;\r
- int src_line_tail_offset;\r
- int dst_line_tail_offset;\r
- int src_byte_per_pixel;\r
-\r
- ASSERT_R( self->Info.biBitCount == 24 || self->Info.biBitCount == 32, goto err );\r
- ASSERT_R( self->Stride * self->Info.biHeight == self->Info.biSizeImage, goto err );\r
-\r
- src_stride = self->Stride;\r
- stride16 = self->Info.biWidth * 2;\r
- stride16 = ( stride16 + 3 ) & ~0x3; // 4byte alignment\r
-\r
- image_size = stride16 * self->Info.biHeight;\r
- new_pixels = (uint8_t*) malloc( image_size ); IF(new_pixels==NULL)goto err_fm;\r
-\r
- src_line_head = self->Pixels + src_stride * (self->Info.biHeight - 1);\r
- dst_line_head = new_pixels + stride16 * (self->Info.biHeight - 1);\r
- src_line_tail_offset = (self->Info.biWidth - 1) * ( self->Info.biBitCount / 8 );\r
- dst_line_tail_offset = (self->Info.biWidth - 1) * (16/8);\r
- src_byte_per_pixel = self->Info.biBitCount / 8;\r
- do {\r
- src = src_line_head + src_line_tail_offset;\r
- dst = dst_line_head + dst_line_tail_offset;\r
-\r
- *(uint32_t*)( dst_line_head + stride16 - sizeof(uint32_t) ) = 0; // padding\r
-\r
- while ( src >= src_line_head ) {\r
- red = *( src + 2 );\r
- green = *( src + 1 );\r
- blue = *( src );\r
-\r
- *(uint16_t*) dst =\r
- ( ( red & 0xF8 ) << 8 ) |\r
- ( ( green & 0xFC ) << 3 ) |\r
- ( ( blue & 0xF8 ) >> 3 );\r
-\r
- src -= src_byte_per_pixel;\r
- dst -= 2;\r
- }\r
- src_line_head -= src_stride;\r
- dst_line_head -= stride16;\r
- } while ( dst_line_head >= new_pixels );\r
-\r
- self->Pixels = new_pixels;\r
- self->Info.biBitCount = 16;\r
- self->Stride = stride16;\r
- self->Info.biSizeImage = image_size;\r
- self->Info.biCompression = BI_BITFIELDS;\r
- self->Info.biSize = sizeof(BITMAPINFOHEADER) + 4 * sizeof(uint32_t);\r
- self->RedMask = 0xF800;\r
- self->GreenMask = 0x07E0;\r
- self->BlueMask = 0x001F;\r
- self->AlphaMask = 0x0000;\r
-\r
- new_pixels = NULL;\r
-\r
- e=0;\r
-fin:\r
- if ( new_pixels != NULL ) free( new_pixels );\r
- return e;\r
-\r
-err: e = E_OTHERS; goto fin;\r
-err_fm: e = E_FEW_MEMORY; goto fin;\r
-}\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_convertToARGB1555Format] >>> \r
-************************************************************************/\r
-errnum_t BmpFile2Class_convertTo16bitARGBFormat( BmpFile2Class* self, uint16_t AlphaMask );\r
-\r
-errnum_t BmpFile2Class_convertToARGB1555Format( BmpFile2Class* self )\r
-{\r
- return BmpFile2Class_convertTo16bitARGBFormat( self, 0x8000 );\r
-}\r
-\r
-errnum_t BmpFile2Class_convertTo16bitARGBFormat( BmpFile2Class* self, uint16_t AlphaMask )\r
-{\r
- errnum_t e;\r
- uint32_t image_size;\r
- uint8_t* new_pixels = NULL;\r
- unsigned stride32;\r
- unsigned stride16;\r
- uint16_t red, green, blue, alpha;\r
- uint8_t* src; // source\r
- uint8_t* dst; // destination\r
- uint8_t* src_line_head;\r
- uint8_t* dst_line_head;\r
- int src_line_tail_offset;\r
- int dst_line_tail_offset;\r
-\r
- ASSERT_R( self->Info.biBitCount == 32, goto err ); // need alpha channel\r
- ASSERT_R( self->Stride * self->Info.biHeight == self->Info.biSizeImage, goto err );\r
- ASSERT_R( AlphaMask == 0x8000 || AlphaMask == 0xF000, goto err );\r
- // 0x8000 = ARGB1555, 0xF000 = ARGB4444\r
-\r
- stride32 = self->Stride;\r
- stride16 = self->Info.biWidth * 2;\r
- stride16 = ( stride16 + 3 ) & ~0x3; // 4byte alignment\r
-\r
- image_size = stride16 * self->Info.biHeight;\r
- new_pixels = (uint8_t*) malloc( image_size ); IF(new_pixels==NULL)goto err_fm;\r
-\r
- src_line_head = self->Pixels + stride32 * (self->Info.biHeight - 1);\r
- dst_line_head = new_pixels + stride16 * (self->Info.biHeight - 1);\r
- src_line_tail_offset = (self->Info.biWidth - 1) * (32/8);\r
- dst_line_tail_offset = (self->Info.biWidth - 1) * (16/8);\r
- do {\r
- src = src_line_head + src_line_tail_offset;\r
- dst = dst_line_head + dst_line_tail_offset;\r
-\r
- *(uint32_t*)( dst_line_head + stride16 - sizeof(uint32_t) ) = 0; // padding\r
-\r
- if ( AlphaMask == 0x8000 ) { // ARGB1555\r
- while ( src >= src_line_head ) {\r
- alpha = *( src + 3 );\r
- red = *( src + 2 );\r
- green = *( src + 1 );\r
- blue = *( src );\r
-\r
- *(uint16_t*) dst =\r
- ( ( alpha & 0x80 ) << 8 ) |\r
- ( ( red & 0xF8 ) << 7 ) |\r
- ( ( green & 0xF8 ) << 2 ) |\r
- ( ( blue & 0xF8 ) >> 3 );\r
-\r
- src -= 4;\r
- dst -= 2;\r
- }\r
- }\r
- else { // ARGB4444\r
- while ( src >= src_line_head ) {\r
- alpha = *( src + 3 );\r
- red = *( src + 2 );\r
- green = *( src + 1 );\r
- blue = *( src );\r
-\r
- *(uint16_t*) dst =\r
- ( ( alpha & 0xF0 ) << 8 ) |\r
- ( ( red & 0xF0 ) << 4 ) |\r
- ( ( green & 0xF0 ) ) |\r
- ( ( blue & 0xF0 ) >> 4 );\r
-\r
- src -= 4;\r
- dst -= 2;\r
- }\r
- }\r
- src_line_head -= stride32;\r
- dst_line_head -= stride16;\r
- } while ( dst_line_head >= new_pixels );\r
-\r
- self->Pixels = new_pixels;\r
- self->Info.biBitCount = 16;\r
- self->Stride = stride16;\r
- self->Info.biSizeImage = image_size;\r
- self->Info.biCompression = BI_BITFIELDS;\r
- self->Info.biSize = sizeof(BITMAPINFOHEADER) + 4 * sizeof(uint32_t);\r
- if ( AlphaMask == 0x8000 ) {\r
- self->RedMask = 0x7C00;\r
- self->GreenMask = 0x03E0;\r
- self->BlueMask = 0x001F;\r
- self->AlphaMask = 0x8000;\r
- }\r
- else {\r
- self->RedMask = 0x0F00;\r
- self->GreenMask = 0x00F0;\r
- self->BlueMask = 0x000F;\r
- self->AlphaMask = 0xF000;\r
- }\r
-\r
- new_pixels = NULL;\r
-\r
- e=0;\r
-fin:\r
- if ( new_pixels != NULL ) free( new_pixels );\r
- return e;\r
-\r
-err: e = E_OTHERS; goto fin;\r
-err_fm: e = E_FEW_MEMORY; goto fin;\r
-}\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_convertToARGB4444Format] >>> \r
-************************************************************************/\r
-errnum_t BmpFile2Class_convertToARGB4444Format( BmpFile2Class* self )\r
-{\r
- return BmpFile2Class_convertTo16bitARGBFormat( self, 0xF000 );\r
-}\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_convertToA4Format] >>> \r
-************************************************************************/\r
-errnum_t BmpFile2Class_convertToA4Format( BmpFile2Class* self )\r
-{\r
- errnum_t e;\r
- uint32_t image_size;\r
- uint8_t* new_pixels = NULL;\r
- unsigned stride24;\r
- unsigned stride4;\r
- uint8_t* src; // source\r
- uint8_t* dst; // destination\r
- uint8_t* src_line_head;\r
- uint8_t* dst_line_head;\r
- int src_line_tail_offset;\r
- int dst_line_tail_offset;\r
- const bool is_width_odd = ( self->Info.biWidth % 2 == 1 );\r
-\r
- ASSERT_R( self->Info.biBitCount == 24, goto err );\r
- ASSERT_R( self->Stride * self->Info.biHeight == self->Info.biSizeImage, goto err );\r
-\r
- stride24 = self->Stride;\r
- stride4 = ( self->Info.biWidth + 1 ) / 2;\r
- stride4 = ( stride4 + 3 ) & ~0x3; // 4byte alignment\r
-\r
- image_size = stride4 * self->Info.biHeight;\r
- new_pixels = (uint8_t*) malloc( image_size ); IF(new_pixels==NULL)goto err_fm;\r
-\r
- src_line_head = self->Pixels + stride24 * (self->Info.biHeight - 1);\r
- dst_line_head = new_pixels + stride4 * (self->Info.biHeight - 1);\r
- src_line_tail_offset = (self->Info.biWidth - 1) * (24/8);\r
- dst_line_tail_offset = (self->Info.biWidth - 1) * 4 / 8;\r
- do {\r
- src = src_line_head + src_line_tail_offset;\r
- dst = dst_line_head + dst_line_tail_offset;\r
-\r
- *(uint32_t*)( dst_line_head + stride4 - sizeof(uint32_t) ) = 0; // padding\r
-\r
- if ( is_width_odd ) {\r
- *dst = *( src + 1 ) & 0xF0; // Green\r
- src -= (24/8);\r
- dst -= 1;\r
- }\r
- while ( src >= src_line_head ) {\r
- *dst = ( *( src - 2 ) & 0xF0 ) | ( *( src + 1 ) >> 4 ); // Green\r
- src -= 2*(24/8);\r
- dst -= 1;\r
- }\r
-\r
- src_line_head -= stride24;\r
- dst_line_head -= stride4;\r
- } while ( dst_line_head >= new_pixels );\r
-\r
- self->Pixels = new_pixels;\r
- self->Info.biBitCount = 4;\r
- self->Stride = stride4;\r
- self->Info.biSizeImage = image_size;\r
- new_pixels = NULL;\r
-\r
- e=0;\r
-fin:\r
- if ( new_pixels != NULL ) free( new_pixels );\r
- return e;\r
-\r
-err: e = E_OTHERS; goto fin;\r
-err_fm: e = E_FEW_MEMORY; goto fin;\r
-}\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_convertToA1Format] >>> \r
-************************************************************************/\r
-errnum_t BmpFile2Class_convertToA1Format( BmpFile2Class* self )\r
-{\r
- errnum_t e;\r
- uint32_t image_size;\r
- uint8_t* new_pixels = NULL;\r
- unsigned stride24;\r
- unsigned stride1;\r
- uint8_t* src; // source\r
- uint8_t* dst; // destination\r
- uint8_t* src_line_head;\r
- uint8_t* dst_line_head;\r
- int src_line_tail_offset;\r
- int dst_line_tail_offset;\r
- const int width_mod = self->Info.biWidth % 8;\r
- int x_mod;\r
- uint8_t bits;\r
-\r
- ASSERT_R( self->Info.biBitCount == 24, goto err );\r
- ASSERT_R( self->Stride * self->Info.biHeight == self->Info.biSizeImage, goto err );\r
-\r
- stride24 = self->Stride;\r
- stride1 = ( self->Info.biWidth + 7 ) / 8;\r
- stride1 = ( stride1 + 3 ) & ~0x3; // 4byte alignment\r
-\r
- image_size = stride1 * self->Info.biHeight;\r
- new_pixels = (uint8_t*) malloc( image_size ); IF(new_pixels==NULL)goto err_fm;\r
-\r
- src_line_head = self->Pixels + stride24 * (self->Info.biHeight - 1);\r
- dst_line_head = new_pixels + stride1 * (self->Info.biHeight - 1);\r
- src_line_tail_offset = (self->Info.biWidth - 1) * (24/8);\r
- dst_line_tail_offset = (self->Info.biWidth - 1) / 8;\r
- do {\r
- src = src_line_head + src_line_tail_offset;\r
- dst = dst_line_head + dst_line_tail_offset;\r
-\r
- *(uint32_t*)( dst_line_head + stride1 - sizeof(uint32_t) ) = 0; // padding\r
-\r
- if ( width_mod > 0 ) {\r
- bits = 0;\r
- for ( x_mod = width_mod - 1; x_mod >= 0; x_mod -= 1 ) {\r
- bits |= ( *( src + 1 ) & 0x80 ) >> x_mod; // Green\r
- src -= (24/8);\r
- }\r
- *dst = bits;\r
- dst -= 1;\r
- }\r
- while ( src >= src_line_head ) {\r
- *dst =\r
- ( *( src + 1 ) & 0x80 ) >> 7 | // Green\r
- ( *( src - 2 ) & 0x80 ) >> 6 |\r
- ( *( src - 5 ) & 0x80 ) >> 5 |\r
- ( *( src - 8 ) & 0x80 ) >> 4 |\r
- ( *( src -11 ) & 0x80 ) >> 3 |\r
- ( *( src -14 ) & 0x80 ) >> 2 |\r
- ( *( src -17 ) & 0x80 ) >> 1 |\r
- ( *( src -20 ) & 0x80 );\r
-\r
- src -= 8*(24/8);\r
- dst -= 1;\r
- }\r
- src_line_head -= stride24;\r
- dst_line_head -= stride1;\r
- } while ( dst_line_head >= new_pixels );\r
-\r
- self->Pixels = new_pixels;\r
- self->Info.biBitCount = 1;\r
- self->Stride = stride1;\r
- self->Info.biSizeImage = image_size;\r
- new_pixels = NULL;\r
-\r
- e=0;\r
-fin:\r
- if ( new_pixels != NULL ) free( new_pixels );\r
- return e;\r
-\r
-err: e = E_OTHERS; goto fin;\r
-err_fm: e = E_FEW_MEMORY; goto fin;\r
-}\r
-\r
-\r
- \r
-/***********************************************************************\r
- <<< [BmpFile2Class_trimming] >>> \r
-************************************************************************/\r
-errnum_t BmpFile2Class_trimming( BmpFile2Class* self, int LeftX, int TopY, int Width, int Height )\r
-{\r
- errnum_t e;\r
- uint8_t* source_left;\r
- uint8_t* source_left_over;\r
- uint8_t* destination_left;\r
- int new_stride;\r
- int padding_size;\r
- int height_abs;\r
-\r
-\r
- if ( self->Info.biHeight > 0 ) {\r
- TopY = self->Info.biHeight - ( TopY + Height );\r
- height_abs = self->Info.biHeight;\r
- } else {\r
- height_abs = - self->Info.biHeight;\r
- }\r
-\r
- ASSERT_R( Width >= 0 && Height >= 0, e=E_OTHERS; goto fin );\r
- ASSERT_R( LeftX >= 0 && LeftX + Width <= self->Info.biWidth, e=E_OTHERS; goto fin );\r
- ASSERT_R( TopY >= 0 && TopY + Height <= height_abs, e=E_OTHERS; goto fin );\r
-\r
- source_left = self->Pixels + self->Stride * TopY + LeftX * self->Info.biBitCount / 8;\r
- source_left_over = source_left + self->Stride * height_abs;\r
- destination_left = self->Pixels;\r
-\r
- if ( self->Info.biBitCount == 16 ) {\r
- new_stride = ceil_4( Width * 2 );\r
- padding_size = mod_2( Width ) * 2;\r
- } else {\r
- IF ( self->Info.biBitCount != 32 ) { e=E_OTHERS; goto fin; }\r
- new_stride = Width * 4;\r
- padding_size = 0;\r
- }\r
-\r
- while ( source_left < source_left_over ) {\r
- memcpy( destination_left, source_left, new_stride );\r
- source_left += self->Stride;\r
- destination_left += new_stride;\r
- memset( destination_left - padding_size, 0x00, padding_size );\r
- }\r
-\r
- self->Info.biWidth = Width;\r
- if ( self->Info.biHeight >= 0 )\r
- { self->Info.biHeight = Height; }\r
- else\r
- { self->Info.biHeight = - Height; }\r
- self->Stride = new_stride;\r
-\r
- e=0;\r
-fin:\r
- return e;\r
-}\r
-\r
-\r
- \r