dungeon_crawler
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/prototype/imago2/conv.c Sun Oct 07 02:04:00 2012 +0300 1.3 @@ -0,0 +1,251 @@ 1.4 +/* 1.5 +libimago - a multi-format image file input/output library. 1.6 +Copyright (C) 2010 John Tsiombikas <nuclear@member.fsf.org> 1.7 + 1.8 +This program is free software: you can redistribute it and/or modify 1.9 +it under the terms of the GNU Lesser General Public License as published 1.10 +by the Free Software Foundation, either version 3 of the License, or 1.11 +(at your option) any later version. 1.12 + 1.13 +This program is distributed in the hope that it will be useful, 1.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 1.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.16 +GNU Lesser General Public License for more details. 1.17 + 1.18 +You should have received a copy of the GNU Lesser General Public License 1.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 1.20 +*/ 1.21 +#include <string.h> 1.22 +#include "imago2.h" 1.23 + 1.24 +/* pixel-format conversions are sub-optimal at the moment to avoid 1.25 + * writing a lot of code. optimize at some point ? 1.26 + */ 1.27 + 1.28 +#define CLAMP(x, a, b) ((x) < (a) ? (a) : ((x) > (b) ? (b) : (x))) 1.29 + 1.30 +struct pixel { 1.31 + float r, g, b, a; 1.32 +}; 1.33 + 1.34 +static void unpack_grey8(struct pixel *unp, void *pptr, int count); 1.35 +static void unpack_rgb24(struct pixel *unp, void *pptr, int count); 1.36 +static void unpack_rgba32(struct pixel *unp, void *pptr, int count); 1.37 +static void unpack_greyf(struct pixel *unp, void *pptr, int count); 1.38 +static void unpack_rgbf(struct pixel *unp, void *pptr, int count); 1.39 +static void unpack_rgbaf(struct pixel *unp, void *pptr, int count); 1.40 + 1.41 +static void pack_grey8(void *pptr, struct pixel *unp, int count); 1.42 +static void pack_rgb24(void *pptr, struct pixel *unp, int count); 1.43 +static void pack_rgba32(void *pptr, struct pixel *unp, int count); 1.44 +static void pack_greyf(void *pptr, struct pixel *unp, int count); 1.45 +static void pack_rgbf(void *pptr, struct pixel *unp, int count); 1.46 +static void pack_rgbaf(void *pptr, struct pixel *unp, int count); 1.47 + 1.48 +/* XXX keep in sync with enum img_fmt at imago2.h */ 1.49 +static void (*unpack[])(struct pixel*, void*, int) = { 1.50 + unpack_grey8, 1.51 + unpack_rgb24, 1.52 + unpack_rgba32, 1.53 + unpack_greyf, 1.54 + unpack_rgbf, 1.55 + unpack_rgbaf 1.56 +}; 1.57 + 1.58 +/* XXX keep in sync with enum img_fmt at imago2.h */ 1.59 +static void (*pack[])(void*, struct pixel*, int) = { 1.60 + pack_grey8, 1.61 + pack_rgb24, 1.62 + pack_rgba32, 1.63 + pack_greyf, 1.64 + pack_rgbf, 1.65 + pack_rgbaf 1.66 +}; 1.67 + 1.68 + 1.69 +int img_convert(struct img_pixmap *img, enum img_fmt tofmt) 1.70 +{ 1.71 + struct pixel pbuf[8]; 1.72 + int bufsz = (img->width & 7) == 0 ? 8 : ((img->width & 3) == 0 ? 4 : 1); 1.73 + int i, num_pix = img->width * img->height; 1.74 + int num_iter = num_pix / bufsz; 1.75 + char *sptr, *dptr; 1.76 + struct img_pixmap nimg; 1.77 + 1.78 + if(img->fmt == tofmt) { 1.79 + return 0; /* nothing to do */ 1.80 + } 1.81 + 1.82 + img_init(&nimg); 1.83 + if(img_set_pixels(&nimg, img->width, img->height, tofmt, 0) == -1) { 1.84 + img_destroy(&nimg); 1.85 + return -1; 1.86 + } 1.87 + 1.88 + sptr = img->pixels; 1.89 + dptr = nimg.pixels; 1.90 + 1.91 + for(i=0; i<num_iter; i++) { 1.92 + unpack[img->fmt](pbuf, sptr, bufsz); 1.93 + pack[tofmt](dptr, pbuf, bufsz); 1.94 + 1.95 + sptr += bufsz * img->pixelsz; 1.96 + dptr += bufsz * nimg.pixelsz; 1.97 + } 1.98 + 1.99 + img_copy(img, &nimg); 1.100 + img_destroy(&nimg); 1.101 + return 0; 1.102 +} 1.103 + 1.104 +/* the following functions *could* benefit from SIMD */ 1.105 + 1.106 +static void unpack_grey8(struct pixel *unp, void *pptr, int count) 1.107 +{ 1.108 + int i; 1.109 + unsigned char *pix = pptr; 1.110 + 1.111 + for(i=0; i<count; i++) { 1.112 + unp->r = unp->g = unp->b = (float)*pix++ / 255.0; 1.113 + unp->a = 1.0; 1.114 + unp++; 1.115 + } 1.116 +} 1.117 + 1.118 +static void unpack_rgb24(struct pixel *unp, void *pptr, int count) 1.119 +{ 1.120 + int i; 1.121 + unsigned char *pix = pptr; 1.122 + 1.123 + for(i=0; i<count; i++) { 1.124 + unp->r = (float)*pix++ / 255.0; 1.125 + unp->g = (float)*pix++ / 255.0; 1.126 + unp->b = (float)*pix++ / 255.0; 1.127 + unp->a = 1.0; 1.128 + unp++; 1.129 + } 1.130 +} 1.131 + 1.132 +static void unpack_rgba32(struct pixel *unp, void *pptr, int count) 1.133 +{ 1.134 + memcpy(unp, pptr, count * sizeof *unp); 1.135 +} 1.136 + 1.137 +static void unpack_greyf(struct pixel *unp, void *pptr, int count) 1.138 +{ 1.139 + int i; 1.140 + float *pix = pptr; 1.141 + 1.142 + for(i=0; i<count; i++) { 1.143 + unp->r = unp->g = unp->b = *pix++; 1.144 + unp->a = 1.0; 1.145 + unp++; 1.146 + } 1.147 +} 1.148 + 1.149 +static void unpack_rgbf(struct pixel *unp, void *pptr, int count) 1.150 +{ 1.151 + int i; 1.152 + float *pix = pptr; 1.153 + 1.154 + for(i=0; i<count; i++) { 1.155 + unp->r = *pix++; 1.156 + unp->g = *pix++; 1.157 + unp->b = *pix++; 1.158 + unp->a = 1.0; 1.159 + unp++; 1.160 + } 1.161 +} 1.162 + 1.163 +static void unpack_rgbaf(struct pixel *unp, void *pptr, int count) 1.164 +{ 1.165 + int i; 1.166 + float *pix = pptr; 1.167 + 1.168 + for(i=0; i<count; i++) { 1.169 + unp->r = *pix++; 1.170 + unp->g = *pix++; 1.171 + unp->b = *pix++; 1.172 + unp->a = *pix++; 1.173 + unp++; 1.174 + } 1.175 +} 1.176 + 1.177 + 1.178 +static void pack_grey8(void *pptr, struct pixel *unp, int count) 1.179 +{ 1.180 + int i; 1.181 + unsigned char *pix = pptr; 1.182 + 1.183 + for(i=0; i<count; i++) { 1.184 + int lum = (int)(255.0 * (unp->r + unp->g + unp->b) / 3.0); 1.185 + *pix++ = CLAMP(lum, 0, 255); 1.186 + unp++; 1.187 + } 1.188 +} 1.189 + 1.190 +static void pack_rgb24(void *pptr, struct pixel *unp, int count) 1.191 +{ 1.192 + int i; 1.193 + unsigned char *pix = pptr; 1.194 + 1.195 + for(i=0; i<count; i++) { 1.196 + int r = (int)(unp->r * 255.0); 1.197 + int g = (int)(unp->g * 255.0); 1.198 + int b = (int)(unp->b * 255.0); 1.199 + 1.200 + *pix++ = CLAMP(r, 0, 255); 1.201 + *pix++ = CLAMP(g, 0, 255); 1.202 + *pix++ = CLAMP(b, 0, 255); 1.203 + unp++; 1.204 + } 1.205 +} 1.206 + 1.207 +static void pack_rgba32(void *pptr, struct pixel *unp, int count) 1.208 +{ 1.209 + int i; 1.210 + unsigned char *pix = pptr; 1.211 + 1.212 + for(i=0; i<count; i++) { 1.213 + int r = (int)(unp->r * 255.0); 1.214 + int g = (int)(unp->g * 255.0); 1.215 + int b = (int)(unp->b * 255.0); 1.216 + int a = (int)(unp->a * 255.0); 1.217 + 1.218 + *pix++ = CLAMP(r, 0, 255); 1.219 + *pix++ = CLAMP(g, 0, 255); 1.220 + *pix++ = CLAMP(b, 0, 255); 1.221 + *pix++ = CLAMP(a, 0, 255); 1.222 + unp++; 1.223 + } 1.224 +} 1.225 + 1.226 +static void pack_greyf(void *pptr, struct pixel *unp, int count) 1.227 +{ 1.228 + int i; 1.229 + float *pix = pptr; 1.230 + 1.231 + for(i=0; i<count; i++) { 1.232 + *pix++ = (unp->r + unp->g + unp->b) / 3.0; 1.233 + unp++; 1.234 + } 1.235 +} 1.236 + 1.237 +static void pack_rgbf(void *pptr, struct pixel *unp, int count) 1.238 +{ 1.239 + int i; 1.240 + float *pix = pptr; 1.241 + 1.242 + for(i=0; i<count; i++) { 1.243 + *pix++ = unp->r; 1.244 + *pix++ = unp->g; 1.245 + *pix++ = unp->b; 1.246 + unp++; 1.247 + } 1.248 +} 1.249 + 1.250 +static void pack_rgbaf(void *pptr, struct pixel *unp, int count) 1.251 +{ 1.252 + memcpy(pptr, unp, count * sizeof *unp); 1.253 +} 1.254 +