3dphotoshoot
diff libs/imago/conv.c @ 14:06dc8b9b4f89
added libimago, libjpeg and libpng
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 07 Jun 2015 17:25:49 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/imago/conv.c Sun Jun 07 17:25:49 2015 +0300 1.3 @@ -0,0 +1,260 @@ 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 + int i; 1.135 + unsigned char *pix = pptr; 1.136 + 1.137 + for(i=0; i<count; i++) { 1.138 + unp->r = (float)*pix++ / 255.0; 1.139 + unp->g = (float)*pix++ / 255.0; 1.140 + unp->b = (float)*pix++ / 255.0; 1.141 + unp->a = (float)*pix++ / 255.0; 1.142 + unp++; 1.143 + } 1.144 +} 1.145 + 1.146 +static void unpack_greyf(struct pixel *unp, void *pptr, int count) 1.147 +{ 1.148 + int i; 1.149 + float *pix = pptr; 1.150 + 1.151 + for(i=0; i<count; i++) { 1.152 + unp->r = unp->g = unp->b = *pix++; 1.153 + unp->a = 1.0; 1.154 + unp++; 1.155 + } 1.156 +} 1.157 + 1.158 +static void unpack_rgbf(struct pixel *unp, void *pptr, int count) 1.159 +{ 1.160 + int i; 1.161 + float *pix = pptr; 1.162 + 1.163 + for(i=0; i<count; i++) { 1.164 + unp->r = *pix++; 1.165 + unp->g = *pix++; 1.166 + unp->b = *pix++; 1.167 + unp->a = 1.0; 1.168 + unp++; 1.169 + } 1.170 +} 1.171 + 1.172 +static void unpack_rgbaf(struct pixel *unp, void *pptr, int count) 1.173 +{ 1.174 + int i; 1.175 + float *pix = pptr; 1.176 + 1.177 + for(i=0; i<count; i++) { 1.178 + unp->r = *pix++; 1.179 + unp->g = *pix++; 1.180 + unp->b = *pix++; 1.181 + unp->a = *pix++; 1.182 + unp++; 1.183 + } 1.184 +} 1.185 + 1.186 + 1.187 +static void pack_grey8(void *pptr, struct pixel *unp, int count) 1.188 +{ 1.189 + int i; 1.190 + unsigned char *pix = pptr; 1.191 + 1.192 + for(i=0; i<count; i++) { 1.193 + int lum = (int)(255.0 * (unp->r + unp->g + unp->b) / 3.0); 1.194 + *pix++ = CLAMP(lum, 0, 255); 1.195 + unp++; 1.196 + } 1.197 +} 1.198 + 1.199 +static void pack_rgb24(void *pptr, struct pixel *unp, int count) 1.200 +{ 1.201 + int i; 1.202 + unsigned char *pix = pptr; 1.203 + 1.204 + for(i=0; i<count; i++) { 1.205 + int r = (int)(unp->r * 255.0); 1.206 + int g = (int)(unp->g * 255.0); 1.207 + int b = (int)(unp->b * 255.0); 1.208 + 1.209 + *pix++ = CLAMP(r, 0, 255); 1.210 + *pix++ = CLAMP(g, 0, 255); 1.211 + *pix++ = CLAMP(b, 0, 255); 1.212 + unp++; 1.213 + } 1.214 +} 1.215 + 1.216 +static void pack_rgba32(void *pptr, struct pixel *unp, int count) 1.217 +{ 1.218 + int i; 1.219 + unsigned char *pix = pptr; 1.220 + 1.221 + for(i=0; i<count; i++) { 1.222 + int r = (int)(unp->r * 255.0); 1.223 + int g = (int)(unp->g * 255.0); 1.224 + int b = (int)(unp->b * 255.0); 1.225 + int a = (int)(unp->a * 255.0); 1.226 + 1.227 + *pix++ = CLAMP(r, 0, 255); 1.228 + *pix++ = CLAMP(g, 0, 255); 1.229 + *pix++ = CLAMP(b, 0, 255); 1.230 + *pix++ = CLAMP(a, 0, 255); 1.231 + unp++; 1.232 + } 1.233 +} 1.234 + 1.235 +static void pack_greyf(void *pptr, struct pixel *unp, int count) 1.236 +{ 1.237 + int i; 1.238 + float *pix = pptr; 1.239 + 1.240 + for(i=0; i<count; i++) { 1.241 + *pix++ = (unp->r + unp->g + unp->b) / 3.0; 1.242 + unp++; 1.243 + } 1.244 +} 1.245 + 1.246 +static void pack_rgbf(void *pptr, struct pixel *unp, int count) 1.247 +{ 1.248 + int i; 1.249 + float *pix = pptr; 1.250 + 1.251 + for(i=0; i<count; i++) { 1.252 + *pix++ = unp->r; 1.253 + *pix++ = unp->g; 1.254 + *pix++ = unp->b; 1.255 + unp++; 1.256 + } 1.257 +} 1.258 + 1.259 +static void pack_rgbaf(void *pptr, struct pixel *unp, int count) 1.260 +{ 1.261 + memcpy(pptr, unp, count * sizeof *unp); 1.262 +} 1.263 +