dungeon_crawler

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