3dphotoshoot

annotate libs/imago/conv.c @ 15:2d48f65da357

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