blob: 535ec22875c265292a44db1a11939efa60cb750f [file] [log] [blame]
Talustus3019a912013-04-06 11:50:07 +02001/*
2 * -- http://android-fb2png.googlecode.com/svn/trunk/img_process.c --
3 *
4 * Copyright 2011, Kyan He <kyan.ql.he@gmail.com>
5 *
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <errno.h>
22#include <png.h>
23
24#include "img_process.h"
25#include "log.h"
26
27int rgb565_to_rgb888(const char* src, char* dst, size_t pixel)
28{
29 struct rgb565 *from;
30 struct rgb888 *to;
31
32 from = (struct rgb565 *) src;
33 to = (struct rgb888 *) dst;
34
bigbiff bigbiff3c897ae2019-06-05 19:55:11 -040035 size_t i = 0;
Talustus3019a912013-04-06 11:50:07 +020036 /* traverse pixel of the row */
37 while(i++ < pixel) {
38
39 to->r = from->r;
40 to->g = from->g;
41 to->b = from->b;
42 /* scale */
43 to->r <<= 3;
44 to->g <<= 2;
45 to->b <<= 3;
46
47 to++;
48 from++;
49 }
50
51 return 0;
52}
53
54int argb8888_to_rgb888(const char* src, char* dst, size_t pixel)
55{
bigbiff bigbiff3c897ae2019-06-05 19:55:11 -040056 size_t i;
Talustus3019a912013-04-06 11:50:07 +020057 struct argb8888 *from;
58 struct rgb888 *to;
59
60 from = (struct argb8888 *) src;
61 to = (struct rgb888 *) dst;
62
63 i = 0;
64 /* traverse pixel of the row */
65 while(i++ < pixel) {
66
67 to->r = from->r;
68 to->g = from->g;
69 to->b = from->b;
70
71 to++;
72 from++;
73 }
74
75 return 0;
76}
77
78int abgr8888_to_rgb888(const char* src, char* dst, size_t pixel)
79{
bigbiff bigbiff3c897ae2019-06-05 19:55:11 -040080 size_t i;
Talustus3019a912013-04-06 11:50:07 +020081 struct abgr8888 *from;
82 struct rgb888 *to;
83
84 from = (struct abgr8888 *) src;
85 to = (struct rgb888 *) dst;
86
87 i = 0;
88 /* traverse pixel of the row */
89 while(i++ < pixel) {
90
91 to->r = from->r;
92 to->g = from->g;
93 to->b = from->b;
94
95 to++;
96 from++;
97 }
98
99 return 0;
100}
101
102int bgra8888_to_rgb888(const char* src, char* dst, size_t pixel)
103{
bigbiff bigbiff3c897ae2019-06-05 19:55:11 -0400104 size_t i;
Talustus3019a912013-04-06 11:50:07 +0200105 struct bgra8888 *from;
106 struct rgb888 *to;
107
108 from = (struct bgra8888 *) src;
109 to = (struct rgb888 *) dst;
110
111 i = 0;
112 /* traverse pixel of the row */
113 while(i++ < pixel) {
114
115 to->r = from->r;
116 to->g = from->g;
117 to->b = from->b;
118
119 to++;
120 from++;
121 }
122
123 return 0;
124}
125
126int rgba8888_to_rgb888(const char* src, char* dst, size_t pixel)
127{
bigbiff bigbiff3c897ae2019-06-05 19:55:11 -0400128 size_t i;
Talustus3019a912013-04-06 11:50:07 +0200129 struct rgba8888 *from;
130 struct rgb888 *to;
131
132 from = (struct rgba8888 *) src;
133 to = (struct rgb888 *) dst;
134
135 i = 0;
136 /* traverse pixel of the row */
137 while(i++ < pixel) {
138
139 to->r = from->r;
140 to->g = from->g;
141 to->b = from->b;
142
143 to++;
144 from++;
145 }
146
147 return 0;
148}
149
150static void
151stdio_write_func (png_structp png, png_bytep data, png_size_t size)
152{
153 FILE *fp;
154 size_t ret;
155
156 fp = png_get_io_ptr (png);
157 while (size) {
158 ret = fwrite (data, 1, size, fp);
159 size -= ret;
160 data += ret;
161 if (size && ferror (fp))
162 E("write: %m\n");
163 }
164}
165
166static void
bigbiff bigbiff3c897ae2019-06-05 19:55:11 -0400167png_simple_output_flush_fn (__attribute__((unused)) png_structp png_ptr)
Talustus3019a912013-04-06 11:50:07 +0200168{
169}
170
171static void
bigbiff bigbiff3c897ae2019-06-05 19:55:11 -0400172png_simple_error_callback (__attribute__((unused)) png_structp png,
Talustus3019a912013-04-06 11:50:07 +0200173 png_const_charp error_msg)
174{
175 E("png error: %s\n", error_msg);
176}
177
178static void
bigbiff bigbiff3c897ae2019-06-05 19:55:11 -0400179png_simple_warning_callback (__attribute__((unused)) png_structp png,
Talustus3019a912013-04-06 11:50:07 +0200180 png_const_charp error_msg)
181{
182 fprintf(stderr, "png warning: %s\n", error_msg);
183}
184
185/* save rgb888 to png format in fp */
186int save_png(const char* path, const char* data, int width, int height)
187{
188 FILE *fp;
189 png_byte **volatile rows;
190 png_struct *png;
191 png_info *info;
192
193 fp = fopen(path, "w");
194 if (!fp) {
195 int errsv = errno;
196 E("Cannot open file %s for writing.\n", path);
197 return errsv;
198 }
199
200 rows = malloc(height * sizeof rows[0]);
201 if (!rows) goto oops;
202
203 int i;
204 for (i = 0; i < height; i++)
205 rows[i] = (png_byte *) data + i * width * 3 /*fb.stride*/;
206
207 png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL,
208 png_simple_error_callback,
209 png_simple_warning_callback);
210 if (!png) {
211 E("png_create_write_struct failed\n");
212 goto oops;
213 }
214
215 info = png_create_info_struct (png);
216 if (!info) {
217 E("png_create_info_struct failed\n");
218 png_destroy_write_struct (&png, NULL);
219 goto oops;
220 }
221
222 png_set_write_fn (png, fp, stdio_write_func, png_simple_output_flush_fn);
223 png_set_IHDR (png, info,
224 width,
225 height,
226#define DEPTH 8
227 DEPTH,
228 PNG_COLOR_TYPE_RGB,
229 PNG_INTERLACE_NONE,
230 PNG_COMPRESSION_TYPE_DEFAULT,
231 PNG_FILTER_TYPE_DEFAULT);
232
233 png_color_16 white;
234
235 white.gray = (1 << DEPTH) - 1;
236 white.red = white.blue = white.green = white.gray;
237
238 png_set_bKGD (png, info, &white);
239 png_write_info (png, info);
240
241 png_write_image (png, rows);
242 png_write_end (png, info);
243
244 png_destroy_write_struct (&png, &info);
245
246 fclose(fp);
247 free (rows);
248 return 0;
249
250oops:
251 fclose(fp);
252 free (rows);
253 return -1;
254}