dungeon_crawler
view prototype/imago2/conv.c @ 67:2560a7ab0243
internalized libanim, libimago2, and libpsys
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 07 Oct 2012 02:04:00 +0300 |
parents | |
children |
line source
1 /*
2 libimago - a multi-format image file input/output library.
3 Copyright (C) 2010 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published
7 by the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include <string.h>
19 #include "imago2.h"
21 /* pixel-format conversions are sub-optimal at the moment to avoid
22 * writing a lot of code. optimize at some point ?
23 */
25 #define CLAMP(x, a, b) ((x) < (a) ? (a) : ((x) > (b) ? (b) : (x)))
27 struct pixel {
28 float r, g, b, a;
29 };
31 static void unpack_grey8(struct pixel *unp, void *pptr, int count);
32 static void unpack_rgb24(struct pixel *unp, void *pptr, int count);
33 static void unpack_rgba32(struct pixel *unp, void *pptr, int count);
34 static void unpack_greyf(struct pixel *unp, void *pptr, int count);
35 static void unpack_rgbf(struct pixel *unp, void *pptr, int count);
36 static void unpack_rgbaf(struct pixel *unp, void *pptr, int count);
38 static void pack_grey8(void *pptr, struct pixel *unp, int count);
39 static void pack_rgb24(void *pptr, struct pixel *unp, int count);
40 static void pack_rgba32(void *pptr, struct pixel *unp, int count);
41 static void pack_greyf(void *pptr, struct pixel *unp, int count);
42 static void pack_rgbf(void *pptr, struct pixel *unp, int count);
43 static void pack_rgbaf(void *pptr, struct pixel *unp, int count);
45 /* XXX keep in sync with enum img_fmt at imago2.h */
46 static void (*unpack[])(struct pixel*, void*, int) = {
47 unpack_grey8,
48 unpack_rgb24,
49 unpack_rgba32,
50 unpack_greyf,
51 unpack_rgbf,
52 unpack_rgbaf
53 };
55 /* XXX keep in sync with enum img_fmt at imago2.h */
56 static void (*pack[])(void*, struct pixel*, int) = {
57 pack_grey8,
58 pack_rgb24,
59 pack_rgba32,
60 pack_greyf,
61 pack_rgbf,
62 pack_rgbaf
63 };
66 int img_convert(struct img_pixmap *img, enum img_fmt tofmt)
67 {
68 struct pixel pbuf[8];
69 int bufsz = (img->width & 7) == 0 ? 8 : ((img->width & 3) == 0 ? 4 : 1);
70 int i, num_pix = img->width * img->height;
71 int num_iter = num_pix / bufsz;
72 char *sptr, *dptr;
73 struct img_pixmap nimg;
75 if(img->fmt == tofmt) {
76 return 0; /* nothing to do */
77 }
79 img_init(&nimg);
80 if(img_set_pixels(&nimg, img->width, img->height, tofmt, 0) == -1) {
81 img_destroy(&nimg);
82 return -1;
83 }
85 sptr = img->pixels;
86 dptr = nimg.pixels;
88 for(i=0; i<num_iter; i++) {
89 unpack[img->fmt](pbuf, sptr, bufsz);
90 pack[tofmt](dptr, pbuf, bufsz);
92 sptr += bufsz * img->pixelsz;
93 dptr += bufsz * nimg.pixelsz;
94 }
96 img_copy(img, &nimg);
97 img_destroy(&nimg);
98 return 0;
99 }
101 /* the following functions *could* benefit from SIMD */
103 static void unpack_grey8(struct pixel *unp, void *pptr, int count)
104 {
105 int i;
106 unsigned char *pix = pptr;
108 for(i=0; i<count; i++) {
109 unp->r = unp->g = unp->b = (float)*pix++ / 255.0;
110 unp->a = 1.0;
111 unp++;
112 }
113 }
115 static void unpack_rgb24(struct pixel *unp, void *pptr, int count)
116 {
117 int i;
118 unsigned char *pix = pptr;
120 for(i=0; i<count; i++) {
121 unp->r = (float)*pix++ / 255.0;
122 unp->g = (float)*pix++ / 255.0;
123 unp->b = (float)*pix++ / 255.0;
124 unp->a = 1.0;
125 unp++;
126 }
127 }
129 static void unpack_rgba32(struct pixel *unp, void *pptr, int count)
130 {
131 memcpy(unp, pptr, count * sizeof *unp);
132 }
134 static void unpack_greyf(struct pixel *unp, void *pptr, int count)
135 {
136 int i;
137 float *pix = pptr;
139 for(i=0; i<count; i++) {
140 unp->r = unp->g = unp->b = *pix++;
141 unp->a = 1.0;
142 unp++;
143 }
144 }
146 static void unpack_rgbf(struct pixel *unp, void *pptr, int count)
147 {
148 int i;
149 float *pix = pptr;
151 for(i=0; i<count; i++) {
152 unp->r = *pix++;
153 unp->g = *pix++;
154 unp->b = *pix++;
155 unp->a = 1.0;
156 unp++;
157 }
158 }
160 static void unpack_rgbaf(struct pixel *unp, void *pptr, int count)
161 {
162 int i;
163 float *pix = pptr;
165 for(i=0; i<count; i++) {
166 unp->r = *pix++;
167 unp->g = *pix++;
168 unp->b = *pix++;
169 unp->a = *pix++;
170 unp++;
171 }
172 }
175 static void pack_grey8(void *pptr, struct pixel *unp, int count)
176 {
177 int i;
178 unsigned char *pix = pptr;
180 for(i=0; i<count; i++) {
181 int lum = (int)(255.0 * (unp->r + unp->g + unp->b) / 3.0);
182 *pix++ = CLAMP(lum, 0, 255);
183 unp++;
184 }
185 }
187 static void pack_rgb24(void *pptr, struct pixel *unp, int count)
188 {
189 int i;
190 unsigned char *pix = pptr;
192 for(i=0; i<count; i++) {
193 int r = (int)(unp->r * 255.0);
194 int g = (int)(unp->g * 255.0);
195 int b = (int)(unp->b * 255.0);
197 *pix++ = CLAMP(r, 0, 255);
198 *pix++ = CLAMP(g, 0, 255);
199 *pix++ = CLAMP(b, 0, 255);
200 unp++;
201 }
202 }
204 static void pack_rgba32(void *pptr, struct pixel *unp, int count)
205 {
206 int i;
207 unsigned char *pix = pptr;
209 for(i=0; i<count; i++) {
210 int r = (int)(unp->r * 255.0);
211 int g = (int)(unp->g * 255.0);
212 int b = (int)(unp->b * 255.0);
213 int a = (int)(unp->a * 255.0);
215 *pix++ = CLAMP(r, 0, 255);
216 *pix++ = CLAMP(g, 0, 255);
217 *pix++ = CLAMP(b, 0, 255);
218 *pix++ = CLAMP(a, 0, 255);
219 unp++;
220 }
221 }
223 static void pack_greyf(void *pptr, struct pixel *unp, int count)
224 {
225 int i;
226 float *pix = pptr;
228 for(i=0; i<count; i++) {
229 *pix++ = (unp->r + unp->g + unp->b) / 3.0;
230 unp++;
231 }
232 }
234 static void pack_rgbf(void *pptr, struct pixel *unp, int count)
235 {
236 int i;
237 float *pix = pptr;
239 for(i=0; i<count; i++) {
240 *pix++ = unp->r;
241 *pix++ = unp->g;
242 *pix++ = unp->b;
243 unp++;
244 }
245 }
247 static void pack_rgbaf(void *pptr, struct pixel *unp, int count)
248 {
249 memcpy(pptr, unp, count * sizeof *unp);
250 }