mirror of
https://frontier.innolan.net/github/AmigaExamples.git
synced 2026-09-12 06:42:03 +00:00
119 lines
3.3 KiB
C
119 lines
3.3 KiB
C
/*
|
|
* Orginal copyright from libpng example code
|
|
*
|
|
* Copyright 2002-2011 Guillaume Cottenceau and contributors.
|
|
*
|
|
* This software may be freely redistributed under the terms
|
|
* of the X11 license.
|
|
*
|
|
*/
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
#include <png.h>
|
|
|
|
#include "imagecon.h"
|
|
|
|
png_bytep*
|
|
png_read(char* file_name)
|
|
{
|
|
png_structp png_ptr;
|
|
png_byte color_type;
|
|
png_byte bit_depth;
|
|
png_infop info_ptr;
|
|
int number_of_passes, rowbytes;
|
|
unsigned char header[8]; // 8 is the maximum size that can be checked
|
|
|
|
/* open file and test for it being a png */
|
|
FILE *fp = fopen(file_name, "rb");
|
|
if (!fp)
|
|
abort_("Failed to open %s", file_name);
|
|
fread(header, 1, 8, fp);
|
|
if (png_sig_cmp(header, 0, 8))
|
|
abort_("File %s is not recognized as a PNG file", file_name);
|
|
|
|
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
|
|
|
if (!png_ptr)
|
|
abort_("png_create_read_struct failed");
|
|
|
|
info_ptr = png_create_info_struct(png_ptr);
|
|
if (!info_ptr)
|
|
abort_("png_create_info_struct failed");
|
|
|
|
if (setjmp(png_jmpbuf(png_ptr)))
|
|
abort_("Error during init_io");
|
|
|
|
png_init_io(png_ptr, fp);
|
|
png_set_sig_bytes(png_ptr, 8);
|
|
|
|
png_read_info(png_ptr, info_ptr);
|
|
|
|
config.width = png_get_image_width(png_ptr, info_ptr);
|
|
config.height = png_get_image_height(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 (config.verbose) {
|
|
printf("width = %d\n", config.width);
|
|
printf("height = %d\n", config.height);
|
|
printf("color_type = %d (palette = %s)\n", color_type, color_type == PNG_COLOR_TYPE_PALETTE ? "yes" : "no");
|
|
printf("bit_depth = %d\n", bit_depth);
|
|
printf("number_of_passes = %d\n", number_of_passes);
|
|
}
|
|
|
|
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
|
png_set_palette_to_rgb(png_ptr);
|
|
|
|
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
|
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
|
|
|
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
|
png_set_tRNS_to_alpha(png_ptr);
|
|
|
|
if (color_type == PNG_COLOR_TYPE_RGB ||
|
|
color_type == PNG_COLOR_TYPE_GRAY ||
|
|
color_type == PNG_COLOR_TYPE_PALETTE)
|
|
png_set_add_alpha(png_ptr, 0xFF, PNG_FILLER_AFTER);
|
|
|
|
if (bit_depth == 16)
|
|
png_set_strip_16(png_ptr);
|
|
|
|
number_of_passes = png_set_interlace_handling(png_ptr);
|
|
|
|
png_read_update_info(png_ptr, info_ptr);
|
|
config.width = png_get_image_width(png_ptr, info_ptr);
|
|
config.height = png_get_image_height(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 (setjmp(png_jmpbuf(png_ptr)))
|
|
abort_("Error during read_image");
|
|
|
|
png_bytep* rowPointers = (png_bytep*) malloc(sizeof(png_bytep) * config.height);
|
|
|
|
if (bit_depth == 16)
|
|
rowbytes = config.width*8;
|
|
else
|
|
rowbytes = config.width*4;
|
|
|
|
for (int y=0; y<config.height; y++)
|
|
rowPointers[y] = (png_byte*) malloc(rowbytes);
|
|
|
|
png_read_image(png_ptr, rowPointers);
|
|
|
|
fclose(fp);
|
|
|
|
if (config.verbose) {
|
|
printf("width = %d\n", config.width);
|
|
printf("height = %d\n", config.height);
|
|
printf("color_type = %d (palette = %s)\n", color_type, color_type == PNG_COLOR_TYPE_PALETTE ? "yes" : "no");
|
|
printf("bit_depth = %d\n", bit_depth);
|
|
printf("number_of_passes = %d\n", number_of_passes);
|
|
}
|
|
|
|
return rowPointers;
|
|
}
|