Mercurial > repos > blastem
comparison png.c @ 2685:da2e06c42d16
Add a compile-time flag to use RGB565 instead of ABGR/ARGB
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 30 Mar 2025 00:06:53 -0700 |
parents | 0111c8344477 |
children |
comparison
equal
deleted
inserted
replaced
2684:c649bcc18487 | 2685:da2e06c42d16 |
---|---|
58 fputs("Error writing PNG magic\n", stderr); | 58 fputs("Error writing PNG magic\n", stderr); |
59 } | 59 } |
60 write_chunk(f, ihdr, chunk, sizeof(chunk)); | 60 write_chunk(f, ihdr, chunk, sizeof(chunk)); |
61 } | 61 } |
62 | 62 |
63 void save_png24_frame(FILE *f, uint32_t *buffer, apng_state *apng, uint32_t width, uint32_t height, uint32_t pitch) | 63 void save_png24_frame(FILE *f, pixel_t *buffer, apng_state *apng, uint32_t width, uint32_t height, uint32_t pitch) |
64 { | 64 { |
65 uint32_t idat_size = (1 + width*3) * height; | 65 uint32_t idat_size = (1 + width*3) * height; |
66 uint8_t *idat_buffer = malloc(idat_size); | 66 uint8_t *idat_buffer = malloc(idat_size); |
67 uint32_t *pixel = buffer; | 67 pixel_t *pixel = buffer; |
68 uint8_t *cur = idat_buffer; | 68 uint8_t *cur = idat_buffer; |
69 for (uint32_t y = 0; y < height; y++) | 69 for (uint32_t y = 0; y < height; y++) |
70 { | 70 { |
71 //save filter type | 71 //save filter type |
72 *(cur++) = 0; | 72 *(cur++) = 0; |
73 uint32_t *start = pixel; | 73 pixel_t *start = pixel; |
74 for (uint32_t x = 0; x < width; x++, pixel++) | 74 for (uint32_t x = 0; x < width; x++, pixel++) |
75 { | 75 { |
76 uint32_t value = *pixel; | 76 pixel_t value = *pixel; |
77 #ifdef USE_RGB565 | |
78 *(cur++) = (value >> 8 & 0xF8) | (value >> (8+5)); | |
79 *(cur++) = (value >> 3 & 0xFC) | (value >> (3+5) & 0x3); | |
80 *(cur++) = value << 3 | (value >> (5-3) & 0x3); | |
81 #else | |
82 #ifdef USE_GLES | |
83 *(cur++) = value; | |
84 *(cur++) = value >> 8; | |
85 *(cur++) = value >> 16; | |
86 #else | |
77 *(cur++) = value >> 16; | 87 *(cur++) = value >> 16; |
78 *(cur++) = value >> 8; | 88 *(cur++) = value >> 8; |
79 *(cur++) = value; | 89 *(cur++) = value; |
90 #endif | |
91 #endif | |
80 } | 92 } |
81 pixel = start + pitch / sizeof(uint32_t); | 93 pixel = start + pitch / sizeof(pixel_t); |
82 } | 94 } |
83 | 95 |
84 uLongf compress_buffer_size = idat_size + 5 * (idat_size/16383 + 1) + 3; | 96 uLongf compress_buffer_size = idat_size + 5 * (idat_size/16383 + 1) + 3; |
85 uint32_t offset = 0; | 97 uint32_t offset = 0; |
86 if (apng) { | 98 if (apng) { |
145 fwrite(bytes, 1, sizeof(bytes), f); | 157 fwrite(bytes, 1, sizeof(bytes), f); |
146 fclose(f); | 158 fclose(f); |
147 free(apng); | 159 free(apng); |
148 } | 160 } |
149 | 161 |
150 void save_png24(FILE *f, uint32_t *buffer, uint32_t width, uint32_t height, uint32_t pitch) | 162 void save_png24(FILE *f, pixel_t *buffer, uint32_t width, uint32_t height, uint32_t pitch) |
151 { | 163 { |
152 write_header(f, width, height, COLOR_TRUE); | 164 write_header(f, width, height, COLOR_TRUE); |
153 save_png24_frame(f, buffer, NULL, width, height, pitch); | 165 save_png24_frame(f, buffer, NULL, width, height, pitch); |
154 write_chunk(f, iend, NULL, 0); | 166 write_chunk(f, iend, NULL, 0); |
155 } | 167 } |
156 | 168 |
157 void save_png(FILE *f, uint32_t *buffer, uint32_t width, uint32_t height, uint32_t pitch) | 169 void save_png(FILE *f, pixel_t *buffer, uint32_t width, uint32_t height, uint32_t pitch) |
158 { | 170 { |
159 uint32_t palette[256]; | 171 pixel_t palette[256]; |
160 uint8_t pal_buffer[256*3]; | 172 uint8_t pal_buffer[256*3]; |
161 uint32_t num_pal = 0; | 173 uint32_t num_pal = 0; |
162 uint32_t index_size = (1 + width) * height; | 174 uint32_t index_size = (1 + width) * height; |
163 uint8_t *index_buffer = malloc(index_size); | 175 uint8_t *index_buffer = malloc(index_size); |
164 uint8_t *cur = index_buffer; | 176 uint8_t *cur = index_buffer; |
165 uint32_t *pixel = buffer; | 177 pixel_t *pixel = buffer; |
166 for (uint32_t y = 0; y < height; y++) | 178 for (uint32_t y = 0; y < height; y++) |
167 { | 179 { |
168 //save filter type | 180 //save filter type |
169 *(cur++) = 0; | 181 *(cur++) = 0; |
170 uint32_t *start = pixel; | 182 pixel_t *start = pixel; |
171 for (uint32_t x = 0; x < width; x++, pixel++, cur++) | 183 for (uint32_t x = 0; x < width; x++, pixel++, cur++) |
172 { | 184 { |
173 uint32_t value = (*pixel) & 0xFFFFFF; | 185 uint32_t value = (*pixel) & 0xFFFFFF; |
174 uint32_t i; | 186 uint32_t i; |
175 for (i = 0; i < num_pal; i++) | 187 for (i = 0; i < num_pal; i++) |
187 palette[i] = value; | 199 palette[i] = value; |
188 num_pal++; | 200 num_pal++; |
189 } | 201 } |
190 *cur = i; | 202 *cur = i; |
191 } | 203 } |
192 pixel = start + pitch / sizeof(uint32_t); | 204 pixel = start + pitch / sizeof(pixel_t); |
193 } | 205 } |
194 write_header(f, width, height, COLOR_INDEXED); | 206 write_header(f, width, height, COLOR_INDEXED); |
195 cur = pal_buffer; | 207 cur = pal_buffer; |
196 for (uint32_t i = 0; i < num_pal; i++) | 208 for (uint32_t i = 0; i < num_pal; i++) |
197 { | 209 { |
210 #ifdef USE_RGB565 | |
211 *(cur++) = (palette[i] >> 8 & 0xF8) | (palette[i] >> (8+5)); | |
212 *(cur++) = (palette[i] >> 3 & 0xFC) | (palette[i] >> (3+5) & 0x3); | |
213 *(cur++) = palette[i] << 3 | (palette[i] >> (5-3) & 0x3); | |
214 #else | |
215 #ifdef USE_GLES | |
216 *(cur++) = palette[i]; | |
217 *(cur++) = palette[i] >> 8; | |
218 *(cur++) = palette[i] >> 16; | |
219 #else | |
198 *(cur++) = palette[i] >> 16; | 220 *(cur++) = palette[i] >> 16; |
199 *(cur++) = palette[i] >> 8; | 221 *(cur++) = palette[i] >> 8; |
200 *(cur++) = palette[i]; | 222 *(cur++) = palette[i]; |
223 #endif | |
224 #endif | |
201 } | 225 } |
202 write_chunk(f, plte, pal_buffer, num_pal * 3); | 226 write_chunk(f, plte, pal_buffer, num_pal * 3); |
203 uLongf compress_buffer_size = index_size + 5 * (index_size/16383 + 1) + 3; | 227 uLongf compress_buffer_size = index_size + 5 * (index_size/16383 + 1) + 3; |
204 uint8_t *compressed = malloc(compress_buffer_size); | 228 uint8_t *compressed = malloc(compress_buffer_size); |
205 compress(compressed, &compress_buffer_size, index_buffer, index_size); | 229 compress(compressed, &compress_buffer_size, index_buffer, index_size); |