dbf-halloween2015

annotate libs/imago/conv.c @ 1:c3f5c32cb210

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