istereo2

annotate libs/imago2/conv.c @ 13:ea928c313344

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