a12e0116 |
1 | #include <stdio.h> |
2 | #include <string.h> |
3 | #include <png.h> |
4 | #include "readpng.h" |
5 | |
6 | void readpng(void *dest, const char *fname, readpng_what what) |
7 | { |
8 | FILE *fp; |
9 | png_structp png_ptr = NULL; |
10 | png_infop info_ptr = NULL; |
11 | png_bytepp row_ptr = NULL; |
12 | |
13 | if (dest == NULL || fname == NULL) |
14 | { |
15 | return; |
16 | } |
17 | |
18 | fp = fopen(fname, "rb"); |
19 | if (fp == NULL) |
20 | { |
21 | printf(__FILE__ ": failed to open: %s\n", fname); |
22 | return; |
23 | } |
24 | |
25 | png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); |
26 | if (!png_ptr) |
27 | { |
28 | printf(__FILE__ ": png_create_read_struct() failed\n"); |
29 | fclose(fp); |
30 | return; |
31 | } |
32 | |
33 | info_ptr = png_create_info_struct(png_ptr); |
34 | if (!info_ptr) |
35 | { |
36 | printf(__FILE__ ": png_create_info_struct() failed\n"); |
37 | goto done; |
38 | } |
39 | |
40 | // Start reading |
41 | png_init_io(png_ptr, fp); |
42 | png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_STRIP_ALPHA | PNG_TRANSFORM_PACKING, NULL); |
43 | row_ptr = png_get_rows(png_ptr, info_ptr); |
44 | if (row_ptr == NULL) |
45 | { |
46 | printf(__FILE__ ": png_get_rows() failed\n"); |
47 | goto done; |
48 | } |
49 | |
50 | // printf("%s: %ix%i @ %ibpp\n", fname, (int)info_ptr->width, (int)info_ptr->height, info_ptr->pixel_depth); |
51 | |
52 | switch (what) |
53 | { |
54 | case READPNG_BG: |
55 | { |
56 | int height, width, h; |
57 | unsigned short *dst = dest; |
58 | if (info_ptr->pixel_depth != 24) |
59 | { |
60 | printf(__FILE__ ": bg image uses %ibpp, needed 24bpp\n", info_ptr->pixel_depth); |
61 | break; |
62 | } |
63 | height = info_ptr->height; |
64 | if (height > 240) height = 240; |
65 | width = info_ptr->width; |
66 | if (width > 320) width = 320; |
67 | |
68 | for (h = 0; h < height; h++) |
69 | { |
70 | unsigned char *src = row_ptr[h]; |
71 | int len = width; |
72 | while (len--) |
73 | { |
74 | *dst++ = ((src[0]&0xf8)<<8) | ((src[1]&0xf8)<<3) | (src[2] >> 3); |
75 | src += 3; |
76 | } |
77 | dst += 320 - width; |
78 | } |
79 | break; |
80 | } |
81 | |
82 | case READPNG_FONT: |
83 | { |
84 | int x, y, x1, y1; |
85 | unsigned char *dst = dest; |
86 | if (info_ptr->width != 128 || info_ptr->height != 160) |
87 | { |
88 | printf(__FILE__ ": unexpected font image size %ix%i, needed 128x160\n", |
89 | (int)info_ptr->width, (int)info_ptr->height); |
90 | break; |
91 | } |
92 | if (info_ptr->pixel_depth != 8) |
93 | { |
94 | printf(__FILE__ ": font image uses %ibpp, needed 8bpp\n", info_ptr->pixel_depth); |
95 | break; |
96 | } |
97 | for (y = 0; y < 16; y++) |
98 | { |
99 | for (x = 0; x < 16; x++) |
100 | { |
101 | for (y1 = 0; y1 < 10; y1++) |
102 | { |
103 | unsigned char *src = row_ptr[y*10 + y1] + x*8; |
104 | for (x1 = 8/2; x1 > 0; x1--, src+=2) |
105 | *dst++ = ((src[0]^0xff) & 0xf0) | ((src[1]^0xff) >> 4); |
106 | } |
107 | } |
108 | } |
109 | break; |
110 | } |
111 | |
112 | case READPNG_SELECTOR: |
113 | { |
114 | int x1, y1; |
115 | unsigned char *dst = dest; |
116 | if (info_ptr->width != 8 || info_ptr->height != 10) |
117 | { |
118 | printf(__FILE__ ": unexpected selector image size %ix%i, needed 8x10\n", |
119 | (int)info_ptr->width, (int)info_ptr->height); |
120 | break; |
121 | } |
122 | if (info_ptr->pixel_depth != 8) |
123 | { |
124 | printf(__FILE__ ": selector image uses %ibpp, needed 8bpp\n", info_ptr->pixel_depth); |
125 | break; |
126 | } |
127 | for (y1 = 0; y1 < 10; y1++) |
128 | { |
129 | unsigned char *src = row_ptr[y1]; |
130 | for (x1 = 8/2; x1 > 0; x1--, src+=2) |
131 | *dst++ = ((src[0]^0xff) & 0xf0) | ((src[1]^0xff) >> 4); |
132 | } |
133 | break; |
134 | } |
135 | } |
136 | |
137 | |
138 | done: |
139 | png_destroy_read_struct(&png_ptr, info_ptr ? &info_ptr : NULL, (png_infopp)NULL); |
140 | fclose(fp); |
141 | } |
142 | |
143 | |