istereo

annotate libs/imago2/conv.c @ 26:862a3329a8f0

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