trunk 20080912
[gitenigma.git] / boot / bootmenue / png.cpp
blob8b9b06eccfe3bd7a1f5456ef3e302389474940ef
1 #ifdef HAVE_DREAMBOX_HARDWARE
2 #include <png.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <fcntl.h>
6 #include <unistd.h>
8 #define FH_ERROR_OK 0
9 #define FH_ERROR_FILE 1
10 #define FH_ERROR_FORMAT 2
11 #define FH_ERROR_MALLOC 3
13 #define PNG_BYTES_TO_CHECK 4
14 #define min(x, y) ((x) < (y) ? (x) : (y))
17 int fh_png_id(const char *name)
19 int fd;
20 char id[4];
21 fd = open(name, O_RDONLY);
22 if (fd == -1)
23 return(0);
24 read(fd, id, 4);
25 close(fd);
26 if (id[1] == 'P' && id[2] == 'N' && id[3] == 'G')
27 return(1);
28 return(0);
32 int fh_png_load(const char *name, unsigned char *buffer, int x, int y)
34 static const png_color_16 my_background = {0, 0, 0, 0, 0};
36 png_structp png_ptr;
37 png_infop info_ptr;
38 png_uint_32 width, height;
39 unsigned int i;
40 int bit_depth, color_type, interlace_type;
41 int number_passes, pass;
42 png_byte * fbptr;
43 FILE * fh;
45 if (!(fh = fopen(name, "rb")))
46 return(FH_ERROR_FILE);
48 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
49 if (png_ptr == NULL)
50 return(FH_ERROR_FORMAT);
51 info_ptr = png_create_info_struct(png_ptr);
52 if (info_ptr == NULL)
54 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
55 fclose(fh);
56 return(FH_ERROR_FORMAT);
59 if (setjmp(png_ptr->jmpbuf))
61 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
62 fclose(fh);
63 return(FH_ERROR_FORMAT);
66 png_init_io(png_ptr, fh);
68 png_read_info(png_ptr, info_ptr);
69 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
71 if (color_type == PNG_COLOR_TYPE_PALETTE)
73 png_set_palette_to_rgb(png_ptr);
74 png_set_background(png_ptr, (png_color_16 *)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
75 /* other possibility for png_set_background: use png_get_bKGD */
78 if (color_type == PNG_COLOR_TYPE_GRAY ||
79 color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
81 png_set_gray_to_rgb(png_ptr);
82 png_set_background(png_ptr, (png_color_16 *)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
85 if (color_type & PNG_COLOR_MASK_ALPHA)
86 png_set_strip_alpha(png_ptr);
88 if (bit_depth < 8)
89 png_set_packing(png_ptr);
91 if (bit_depth == 16)
92 png_set_strip_16(png_ptr);
94 /* on Intel PC ?:
95 if (bit_depth == 16)
96 png_set_swap(png_ptr);
99 number_passes = png_set_interlace_handling(png_ptr);
100 png_read_update_info(png_ptr, info_ptr);
102 if (width * 3 != png_get_rowbytes(png_ptr, info_ptr))
104 printf("[png.cpp]: Error processing %s - please report (including image).\n", name);
105 return(FH_ERROR_FORMAT);
108 for(pass = 0; pass < number_passes; pass++)
110 fbptr = (png_byte *)buffer;
111 for (i = 0; i < height; i++, fbptr += width * 3)
113 png_read_row(png_ptr, fbptr, NULL);
116 png_read_end(png_ptr, info_ptr);
117 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
118 fclose(fh);
119 return(FH_ERROR_OK);
121 int fh_png_getsize(const char *name, int *x, int *y, int wanted_width, int wanted_height)
123 png_structp png_ptr;
124 png_infop info_ptr;
125 png_uint_32 width, height;
126 int bit_depth, color_type, interlace_type;
127 FILE *fh;
129 if (!(fh = fopen(name, "rb")))
130 return(FH_ERROR_FILE);
132 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
133 if (png_ptr == NULL)
134 return(FH_ERROR_FORMAT);
135 info_ptr = png_create_info_struct(png_ptr);
136 if (info_ptr == NULL)
138 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
139 fclose(fh);
140 return(FH_ERROR_FORMAT);
143 if (setjmp(png_ptr->jmpbuf))
145 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
146 fclose(fh);
147 return(FH_ERROR_FORMAT);
150 png_init_io(png_ptr,fh);
151 png_read_info(png_ptr, info_ptr);
152 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
153 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
154 *x = width;
155 *y = height;
156 fclose(fh);
157 return(FH_ERROR_OK);
159 #endif