Splitted Load_PNG to allow usage by Load_ICO
Introduces Load_PNG_Sub() some .ico contain PNG images
This commit is contained in:
parent
c2486ed629
commit
37a5a0a85c
@ -63,6 +63,10 @@
|
||||
#include "pages.h"
|
||||
#include "windows.h" // Best_color()
|
||||
|
||||
#ifndef __no_pnglib__
|
||||
static void Load_PNG_Sub(T_IO_Context * context, FILE * file);
|
||||
#endif
|
||||
|
||||
//////////////////////////////////// IMG ////////////////////////////////////
|
||||
|
||||
// -- Tester si un fichier est au format IMG --------------------------------
|
||||
@ -4151,25 +4155,312 @@ int PNG_read_unknown_chunk(png_structp ptr, png_unknown_chunkp chunk)
|
||||
}
|
||||
|
||||
|
||||
png_bytep * Row_pointers;
|
||||
// -- Lire un fichier au format PNG -----------------------------------------
|
||||
static void Load_PNG_Sub(T_IO_Context * context, FILE * file)
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
|
||||
// Prepare internal PNG loader
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (png_ptr)
|
||||
{
|
||||
// Prepare internal PNG loader
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr)
|
||||
{
|
||||
png_byte color_type;
|
||||
png_byte bit_depth;
|
||||
png_voidp user_chunk_ptr;
|
||||
|
||||
// Setup a return point. If a pnglib loading error occurs
|
||||
// in this if(), the else will be executed.
|
||||
if (!setjmp(png_jmpbuf(png_ptr)))
|
||||
{
|
||||
png_init_io(png_ptr, file);
|
||||
// Inform pnglib we already loaded the header.
|
||||
png_set_sig_bytes(png_ptr, 8);
|
||||
|
||||
// Hook the handler for unknown chunks
|
||||
user_chunk_ptr = png_get_user_chunk_ptr(png_ptr);
|
||||
png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, &PNG_read_unknown_chunk);
|
||||
// This is a horrid way to pass parameters, but we don't get
|
||||
// much choice. PNG loader can't be reintrant.
|
||||
PNG_current_context=context;
|
||||
|
||||
// Load file information
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
color_type = png_get_color_type(png_ptr,info_ptr);
|
||||
bit_depth = png_get_bit_depth(png_ptr,info_ptr);
|
||||
|
||||
// If it's any supported file
|
||||
// (Note: As of writing this, this test covers every possible
|
||||
// image format of libpng)
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE
|
||||
|| color_type == PNG_COLOR_TYPE_GRAY
|
||||
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA
|
||||
|| color_type == PNG_COLOR_TYPE_RGB
|
||||
|| color_type == PNG_COLOR_TYPE_RGB_ALPHA
|
||||
)
|
||||
{
|
||||
int num_text;
|
||||
png_text *text_ptr;
|
||||
|
||||
int unit_type;
|
||||
png_uint_32 res_x;
|
||||
png_uint_32 res_y;
|
||||
|
||||
// Comment (tEXt)
|
||||
context->Comment[0]='\0'; // Clear the previous comment
|
||||
if ((num_text=png_get_text(png_ptr, info_ptr, &text_ptr, NULL)))
|
||||
{
|
||||
while (num_text--)
|
||||
{
|
||||
if (!strcmp(text_ptr[num_text].key,"Title"))
|
||||
{
|
||||
int size;
|
||||
size = Min(text_ptr[num_text].text_length, COMMENT_SIZE);
|
||||
strncpy(context->Comment, text_ptr[num_text].text, size);
|
||||
context->Comment[size]='\0';
|
||||
break; // Skip all others tEXt chunks
|
||||
}
|
||||
}
|
||||
}
|
||||
// Pixel Ratio (pHYs)
|
||||
if (png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type))
|
||||
{
|
||||
// Ignore unit, and use the X/Y ratio as a hint for
|
||||
// WIDE or TALL pixels
|
||||
if (res_x>0 && res_y>0)
|
||||
{
|
||||
if (res_y/res_x>1)
|
||||
{
|
||||
context->Ratio=PIXEL_WIDE;
|
||||
}
|
||||
else if (res_x/res_y>1)
|
||||
{
|
||||
context->Ratio=PIXEL_TALL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
Pre_load(context,png_get_image_width(png_ptr,info_ptr),png_get_image_height(png_ptr,info_ptr),File_length_file(file),FORMAT_PNG,PIXEL_SIMPLE,1);
|
||||
else
|
||||
Pre_load(context,png_get_image_width(png_ptr,info_ptr),png_get_image_height(png_ptr,info_ptr),File_length_file(file),FORMAT_PNG,context->Ratio,0);
|
||||
|
||||
if (File_error==0)
|
||||
{
|
||||
int x,y;
|
||||
png_colorp palette;
|
||||
int num_palette;
|
||||
png_bytep * Row_pointers = NULL;
|
||||
byte row_pointers_allocated = 0;
|
||||
int num_trans;
|
||||
png_bytep trans;
|
||||
png_color_16p trans_values;
|
||||
|
||||
// 16-bit images
|
||||
if (bit_depth == 16)
|
||||
{
|
||||
// Reduce to 8-bit
|
||||
png_set_strip_16(png_ptr);
|
||||
}
|
||||
else if (bit_depth < 8)
|
||||
{
|
||||
// Inform libpng we want one byte per pixel,
|
||||
// even though the file was less than 8bpp
|
||||
png_set_packing(png_ptr);
|
||||
}
|
||||
|
||||
// Images with alpha channel
|
||||
if (color_type & PNG_COLOR_MASK_ALPHA)
|
||||
{
|
||||
// Tell libpng to ignore it
|
||||
png_set_strip_alpha(png_ptr);
|
||||
}
|
||||
|
||||
// Greyscale images :
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
// Map low bpp greyscales to full 8bit (0-255 range)
|
||||
if (bit_depth < 8)
|
||||
{
|
||||
#if (PNG_LIBPNG_VER_MAJOR <= 1) && (PNG_LIBPNG_VER_MINOR < 4)
|
||||
// Works well with png 1.2.8, but deprecated in 1.4 ...
|
||||
png_set_gray_1_2_4_to_8(png_ptr);
|
||||
#else
|
||||
// ...where this seems to replace it:
|
||||
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create greyscale palette
|
||||
for (x=0;x<256;x++)
|
||||
{
|
||||
context->Palette[x].R=x;
|
||||
context->Palette[x].G=x;
|
||||
context->Palette[x].B=x;
|
||||
}
|
||||
}
|
||||
else if (color_type == PNG_COLOR_TYPE_PALETTE) // Palette images
|
||||
{
|
||||
if (bit_depth < 8)
|
||||
{
|
||||
// Clear unused colors
|
||||
if (Config.Clear_palette)
|
||||
memset(context->Palette,0,sizeof(T_Palette));
|
||||
}
|
||||
// Get a pointer to the PNG palette
|
||||
png_get_PLTE(png_ptr, info_ptr, &palette,
|
||||
&num_palette);
|
||||
// Copy all colors to the context
|
||||
for (x=0;x<num_palette;x++)
|
||||
{
|
||||
context->Palette[x].R=palette[x].red;
|
||||
context->Palette[x].G=palette[x].green;
|
||||
context->Palette[x].B=palette[x].blue;
|
||||
}
|
||||
// The palette must not be freed: it is owned by libpng.
|
||||
palette = NULL;
|
||||
}
|
||||
// Transparency (tRNS)
|
||||
if (png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values))
|
||||
{
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE && trans!=NULL)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<num_trans; i++)
|
||||
{
|
||||
if (trans[i]==0)
|
||||
{
|
||||
context->Transparent_color = i;
|
||||
context->Background_transparent = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((color_type == PNG_COLOR_TYPE_GRAY
|
||||
|| color_type == PNG_COLOR_TYPE_RGB) && trans_values!=NULL)
|
||||
{
|
||||
// In this case, num_trans is supposed to be "1",
|
||||
// and trans_values[0] contains the reference color
|
||||
// (RGB triplet) that counts as transparent.
|
||||
|
||||
// Ideally, we should reserve this color in the palette,
|
||||
// (so it's not merged and averaged with a neighbor one)
|
||||
// and after creating the optimized palette, find its
|
||||
// index and mark it transparent.
|
||||
|
||||
// Current implementation: ignore.
|
||||
}
|
||||
}
|
||||
|
||||
context->Width=png_get_image_width(png_ptr,info_ptr);
|
||||
context->Height=png_get_image_height(png_ptr,info_ptr);
|
||||
|
||||
png_set_interlace_handling(png_ptr);
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
// Allocate row pointers
|
||||
Row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * context->Height);
|
||||
row_pointers_allocated = 0;
|
||||
|
||||
/* read file */
|
||||
if (!setjmp(png_jmpbuf(png_ptr)))
|
||||
{
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY
|
||||
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA
|
||||
|| color_type == PNG_COLOR_TYPE_PALETTE
|
||||
)
|
||||
{
|
||||
// 8bpp
|
||||
|
||||
for (y=0; y<context->Height; y++)
|
||||
Row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
|
||||
row_pointers_allocated = 1;
|
||||
|
||||
png_read_image(png_ptr, Row_pointers);
|
||||
|
||||
for (y=0; y<context->Height; y++)
|
||||
for (x=0; x<context->Width; x++)
|
||||
Set_pixel(context, x, y, Row_pointers[y][x]);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (context->Type)
|
||||
{
|
||||
case CONTEXT_PREVIEW:
|
||||
// 24bpp
|
||||
|
||||
// It's a preview
|
||||
// Unfortunately we need to allocate loads of memory
|
||||
for (y=0; y<context->Height; y++)
|
||||
Row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
|
||||
row_pointers_allocated = 1;
|
||||
|
||||
png_read_image(png_ptr, Row_pointers);
|
||||
|
||||
for (y=0; y<context->Height; y++)
|
||||
for (x=0; x<context->Width; x++)
|
||||
Set_pixel_24b(context, x, y, Row_pointers[y][x*3],Row_pointers[y][x*3+1],Row_pointers[y][x*3+2]);
|
||||
break;
|
||||
case CONTEXT_MAIN_IMAGE:
|
||||
case CONTEXT_BRUSH:
|
||||
case CONTEXT_SURFACE:
|
||||
// It's loading an actual image
|
||||
// We'll save memory and time by writing directly into
|
||||
// our pre-allocated 24bit buffer
|
||||
for (y=0; y<context->Height; y++)
|
||||
Row_pointers[y] = (png_byte*) (&(context->Buffer_image_24b[y * context->Width]));
|
||||
png_read_image(png_ptr, Row_pointers);
|
||||
break;
|
||||
|
||||
case CONTEXT_PALETTE:
|
||||
// No pixels to draw in a palette!
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
File_error=2;
|
||||
|
||||
/* cleanup heap allocation */
|
||||
if (row_pointers_allocated)
|
||||
{
|
||||
for (y=0; y<context->Height; y++) {
|
||||
free(Row_pointers[y]);
|
||||
Row_pointers[y] = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
free(Row_pointers);
|
||||
Row_pointers = NULL;
|
||||
}
|
||||
else
|
||||
File_error=2;
|
||||
}
|
||||
else
|
||||
// Unsupported image type
|
||||
File_error=1;
|
||||
}
|
||||
else
|
||||
File_error=1;
|
||||
}
|
||||
else
|
||||
File_error=1;
|
||||
}
|
||||
}
|
||||
|
||||
void Load_PNG(T_IO_Context * context)
|
||||
{
|
||||
FILE *file; // Fichier du fichier
|
||||
char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier
|
||||
byte png_header[8];
|
||||
byte row_pointers_allocated;
|
||||
png_bytep trans;
|
||||
int num_trans;
|
||||
png_color_16p trans_values;
|
||||
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
byte png_header[8];
|
||||
|
||||
Get_full_filename(filename, context->File_name, context->File_directory);
|
||||
|
||||
File_error=0;
|
||||
|
||||
|
||||
if ((file=fopen(filename, "rb")))
|
||||
{
|
||||
// Load header (8 first bytes)
|
||||
@ -4177,292 +4468,9 @@ void Load_PNG(T_IO_Context * context)
|
||||
{
|
||||
// Do we recognize a png file signature ?
|
||||
if ( !png_sig_cmp(png_header, 0, 8))
|
||||
{
|
||||
// Prepare internal PNG loader
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (png_ptr)
|
||||
{
|
||||
// Prepare internal PNG loader
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr)
|
||||
{
|
||||
png_byte color_type;
|
||||
png_byte bit_depth;
|
||||
png_voidp user_chunk_ptr;
|
||||
|
||||
// Setup a return point. If a pnglib loading error occurs
|
||||
// in this if(), the else will be executed.
|
||||
if (!setjmp(png_jmpbuf(png_ptr)))
|
||||
{
|
||||
png_init_io(png_ptr, file);
|
||||
// Inform pnglib we already loaded the header.
|
||||
png_set_sig_bytes(png_ptr, 8);
|
||||
|
||||
// Hook the handler for unknown chunks
|
||||
user_chunk_ptr = png_get_user_chunk_ptr(png_ptr);
|
||||
png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, &PNG_read_unknown_chunk);
|
||||
// This is a horrid way to pass parameters, but we don't get
|
||||
// much choice. PNG loader can't be reintrant.
|
||||
PNG_current_context=context;
|
||||
|
||||
// Load file information
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
color_type = png_get_color_type(png_ptr,info_ptr);
|
||||
bit_depth = png_get_bit_depth(png_ptr,info_ptr);
|
||||
|
||||
// If it's any supported file
|
||||
// (Note: As of writing this, this test covers every possible
|
||||
// image format of libpng)
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE
|
||||
|| color_type == PNG_COLOR_TYPE_GRAY
|
||||
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA
|
||||
|| color_type == PNG_COLOR_TYPE_RGB
|
||||
|| color_type == PNG_COLOR_TYPE_RGB_ALPHA
|
||||
)
|
||||
{
|
||||
int num_text;
|
||||
png_text *text_ptr;
|
||||
|
||||
int unit_type;
|
||||
png_uint_32 res_x;
|
||||
png_uint_32 res_y;
|
||||
|
||||
// Comment (tEXt)
|
||||
context->Comment[0]='\0'; // Clear the previous comment
|
||||
if ((num_text=png_get_text(png_ptr, info_ptr, &text_ptr, NULL)))
|
||||
{
|
||||
while (num_text--)
|
||||
{
|
||||
if (!strcmp(text_ptr[num_text].key,"Title"))
|
||||
{
|
||||
int size;
|
||||
size = Min(text_ptr[num_text].text_length, COMMENT_SIZE);
|
||||
strncpy(context->Comment, text_ptr[num_text].text, size);
|
||||
context->Comment[size]='\0';
|
||||
break; // Skip all others tEXt chunks
|
||||
}
|
||||
}
|
||||
}
|
||||
// Pixel Ratio (pHYs)
|
||||
if (png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type))
|
||||
{
|
||||
// Ignore unit, and use the X/Y ratio as a hint for
|
||||
// WIDE or TALL pixels
|
||||
if (res_x>0 && res_y>0)
|
||||
{
|
||||
if (res_y/res_x>1)
|
||||
{
|
||||
context->Ratio=PIXEL_WIDE;
|
||||
}
|
||||
else if (res_x/res_y>1)
|
||||
{
|
||||
context->Ratio=PIXEL_TALL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
Pre_load(context,png_get_image_width(png_ptr,info_ptr),png_get_image_height(png_ptr,info_ptr),File_length_file(file),FORMAT_PNG,PIXEL_SIMPLE,1);
|
||||
else
|
||||
Pre_load(context,png_get_image_width(png_ptr,info_ptr),png_get_image_height(png_ptr,info_ptr),File_length_file(file),FORMAT_PNG,context->Ratio,0);
|
||||
|
||||
if (File_error==0)
|
||||
{
|
||||
int x,y;
|
||||
png_colorp palette;
|
||||
int num_palette;
|
||||
|
||||
// 16-bit images
|
||||
if (bit_depth == 16)
|
||||
{
|
||||
// Reduce to 8-bit
|
||||
png_set_strip_16(png_ptr);
|
||||
}
|
||||
else if (bit_depth < 8)
|
||||
{
|
||||
// Inform libpng we want one byte per pixel,
|
||||
// even though the file was less than 8bpp
|
||||
png_set_packing(png_ptr);
|
||||
}
|
||||
|
||||
// Images with alpha channel
|
||||
if (color_type & PNG_COLOR_MASK_ALPHA)
|
||||
{
|
||||
// Tell libpng to ignore it
|
||||
png_set_strip_alpha(png_ptr);
|
||||
}
|
||||
|
||||
// Greyscale images :
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
// Map low bpp greyscales to full 8bit (0-255 range)
|
||||
if (bit_depth < 8)
|
||||
{
|
||||
#if (PNG_LIBPNG_VER_MAJOR <= 1) && (PNG_LIBPNG_VER_MINOR < 4)
|
||||
// Works well with png 1.2.8, but deprecated in 1.4 ...
|
||||
png_set_gray_1_2_4_to_8(png_ptr);
|
||||
#else
|
||||
// ...where this seems to replace it:
|
||||
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create greyscale palette
|
||||
for (x=0;x<256;x++)
|
||||
{
|
||||
context->Palette[x].R=x;
|
||||
context->Palette[x].G=x;
|
||||
context->Palette[x].B=x;
|
||||
}
|
||||
}
|
||||
else if (color_type == PNG_COLOR_TYPE_PALETTE) // Palette images
|
||||
{
|
||||
if (bit_depth < 8)
|
||||
{
|
||||
// Clear unused colors
|
||||
if (Config.Clear_palette)
|
||||
memset(context->Palette,0,sizeof(T_Palette));
|
||||
}
|
||||
// Get a pointer to the PNG palette
|
||||
png_get_PLTE(png_ptr, info_ptr, &palette,
|
||||
&num_palette);
|
||||
// Copy all colors to the context
|
||||
for (x=0;x<num_palette;x++)
|
||||
{
|
||||
context->Palette[x].R=palette[x].red;
|
||||
context->Palette[x].G=palette[x].green;
|
||||
context->Palette[x].B=palette[x].blue;
|
||||
}
|
||||
// The palette must not be freed: it is owned by libpng.
|
||||
palette = NULL;
|
||||
}
|
||||
// Transparency (tRNS)
|
||||
if (png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values))
|
||||
{
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE && trans!=NULL)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<num_trans; i++)
|
||||
{
|
||||
if (trans[i]==0)
|
||||
{
|
||||
context->Transparent_color = i;
|
||||
context->Background_transparent = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((color_type == PNG_COLOR_TYPE_GRAY
|
||||
|| color_type == PNG_COLOR_TYPE_RGB) && trans_values!=NULL)
|
||||
{
|
||||
// In this case, num_trans is supposed to be "1",
|
||||
// and trans_values[0] contains the reference color
|
||||
// (RGB triplet) that counts as transparent.
|
||||
|
||||
// Ideally, we should reserve this color in the palette,
|
||||
// (so it's not merged and averaged with a neighbor one)
|
||||
// and after creating the optimized palette, find its
|
||||
// index and mark it transparent.
|
||||
|
||||
// Current implementation: ignore.
|
||||
}
|
||||
}
|
||||
|
||||
context->Width=png_get_image_width(png_ptr,info_ptr);
|
||||
context->Height=png_get_image_height(png_ptr,info_ptr);
|
||||
|
||||
png_set_interlace_handling(png_ptr);
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
// Allocate row pointers
|
||||
Row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * context->Height);
|
||||
row_pointers_allocated = 0;
|
||||
|
||||
/* read file */
|
||||
if (!setjmp(png_jmpbuf(png_ptr)))
|
||||
{
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY
|
||||
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA
|
||||
|| color_type == PNG_COLOR_TYPE_PALETTE
|
||||
)
|
||||
{
|
||||
// 8bpp
|
||||
|
||||
for (y=0; y<context->Height; y++)
|
||||
Row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
|
||||
row_pointers_allocated = 1;
|
||||
|
||||
png_read_image(png_ptr, Row_pointers);
|
||||
|
||||
for (y=0; y<context->Height; y++)
|
||||
for (x=0; x<context->Width; x++)
|
||||
Set_pixel(context, x, y, Row_pointers[y][x]);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (context->Type)
|
||||
{
|
||||
case CONTEXT_PREVIEW:
|
||||
// 24bpp
|
||||
|
||||
// It's a preview
|
||||
// Unfortunately we need to allocate loads of memory
|
||||
for (y=0; y<context->Height; y++)
|
||||
Row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
|
||||
row_pointers_allocated = 1;
|
||||
|
||||
png_read_image(png_ptr, Row_pointers);
|
||||
|
||||
for (y=0; y<context->Height; y++)
|
||||
for (x=0; x<context->Width; x++)
|
||||
Set_pixel_24b(context, x, y, Row_pointers[y][x*3],Row_pointers[y][x*3+1],Row_pointers[y][x*3+2]);
|
||||
break;
|
||||
case CONTEXT_MAIN_IMAGE:
|
||||
case CONTEXT_BRUSH:
|
||||
case CONTEXT_SURFACE:
|
||||
// It's loading an actual image
|
||||
// We'll save memory and time by writing directly into
|
||||
// our pre-allocated 24bit buffer
|
||||
for (y=0; y<context->Height; y++)
|
||||
Row_pointers[y] = (png_byte*) (&(context->Buffer_image_24b[y * context->Width]));
|
||||
png_read_image(png_ptr, Row_pointers);
|
||||
break;
|
||||
|
||||
case CONTEXT_PALETTE:
|
||||
// No pixels to draw in a palette!
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
File_error=2;
|
||||
|
||||
/* cleanup heap allocation */
|
||||
if (row_pointers_allocated)
|
||||
{
|
||||
for (y=0; y<context->Height; y++) {
|
||||
free(Row_pointers[y]);
|
||||
Row_pointers[y] = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
free(Row_pointers);
|
||||
Row_pointers = NULL;
|
||||
}
|
||||
else
|
||||
File_error=2;
|
||||
}
|
||||
else
|
||||
// Unsupported image type
|
||||
File_error=1;
|
||||
}
|
||||
else
|
||||
File_error=1;
|
||||
}
|
||||
else
|
||||
File_error=1;
|
||||
}
|
||||
}
|
||||
/*Close_lecture();*/
|
||||
Load_PNG_Sub(context, file);
|
||||
else
|
||||
File_error=2;
|
||||
}
|
||||
else // Lecture header impossible: Error ne modifiant pas l'image
|
||||
File_error=1;
|
||||
@ -4483,6 +4491,7 @@ void Save_PNG(T_IO_Context * context)
|
||||
png_infop info_ptr;
|
||||
png_unknown_chunk crng_chunk;
|
||||
byte cycle_data[16*6]; // Storage for color-cycling data, referenced by crng_chunk
|
||||
static png_bytep * Row_pointers;
|
||||
|
||||
Get_full_filename(filename, context->File_name, context->File_directory);
|
||||
File_error=0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user