istereo
diff libs/imago2/imago2.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 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/imago2/imago2.c Thu Sep 08 06:28:38 2011 +0300 1.3 @@ -0,0 +1,343 @@ 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 + 1.22 +#include <stdio.h> 1.23 +#include <stdlib.h> 1.24 +#include <string.h> 1.25 +#include "imago2.h" 1.26 +#include "ftype_module.h" 1.27 + 1.28 +static int pixel_size(enum img_fmt fmt); 1.29 +static size_t def_read(void *buf, size_t bytes, void *uptr); 1.30 +static size_t def_write(void *buf, size_t bytes, void *uptr); 1.31 +static long def_seek(long offset, int whence, void *uptr); 1.32 + 1.33 + 1.34 +void img_init(struct img_pixmap *img) 1.35 +{ 1.36 + img->pixels = 0; 1.37 + img->width = img->height = 0; 1.38 + img->fmt = IMG_FMT_RGBA32; 1.39 + img->pixelsz = pixel_size(img->fmt); 1.40 + img->name = 0; 1.41 +} 1.42 + 1.43 + 1.44 +void img_destroy(struct img_pixmap *img) 1.45 +{ 1.46 + free(img->pixels); 1.47 + img->pixels = 0; /* just in case... */ 1.48 + img->width = img->height = 0xbadbeef; 1.49 + free(img->name); 1.50 +} 1.51 + 1.52 +struct img_pixmap *img_create(void) 1.53 +{ 1.54 + struct img_pixmap *p; 1.55 + 1.56 + if(!(p = malloc(sizeof *p))) { 1.57 + return 0; 1.58 + } 1.59 + img_init(p); 1.60 + return p; 1.61 +} 1.62 + 1.63 +void img_free(struct img_pixmap *img) 1.64 +{ 1.65 + img_destroy(img); 1.66 + free(img); 1.67 +} 1.68 + 1.69 +int img_set_name(struct img_pixmap *img, const char *name) 1.70 +{ 1.71 + char *tmp; 1.72 + 1.73 + if(!(tmp = malloc(strlen(name) + 1))) { 1.74 + return -1; 1.75 + } 1.76 + strcpy(tmp, name); 1.77 + img->name = tmp; 1.78 + return 0; 1.79 +} 1.80 + 1.81 +int img_set_format(struct img_pixmap *img, enum img_fmt fmt) 1.82 +{ 1.83 + if(img->pixels) { 1.84 + return img_convert(img, fmt); 1.85 + } 1.86 + img->fmt = fmt; 1.87 + return 0; 1.88 +} 1.89 + 1.90 +int img_copy(struct img_pixmap *dest, struct img_pixmap *src) 1.91 +{ 1.92 + return img_set_pixels(dest, src->width, src->height, src->fmt, src->pixels); 1.93 +} 1.94 + 1.95 +int img_set_pixels(struct img_pixmap *img, int w, int h, enum img_fmt fmt, void *pix) 1.96 +{ 1.97 + void *newpix; 1.98 + int pixsz = pixel_size(fmt); 1.99 + 1.100 + if(!(newpix = malloc(w * h * pixsz))) { 1.101 + return -1; 1.102 + } 1.103 + 1.104 + if(pix) { 1.105 + memcpy(newpix, pix, w * h * pixsz); 1.106 + } else { 1.107 + memset(newpix, 0, w * h * pixsz); 1.108 + } 1.109 + 1.110 + free(img->pixels); 1.111 + img->pixels = newpix; 1.112 + img->width = w; 1.113 + img->height = h; 1.114 + img->pixelsz = pixsz; 1.115 + img->fmt = fmt; 1.116 + return 0; 1.117 +} 1.118 + 1.119 +void *img_load_pixels(const char *fname, int *xsz, int *ysz, enum img_fmt fmt) 1.120 +{ 1.121 + struct img_pixmap img; 1.122 + 1.123 + img_init(&img); 1.124 + 1.125 + if(img_load(&img, fname) == -1) { 1.126 + return 0; 1.127 + } 1.128 + if(img.fmt != fmt) { 1.129 + if(img_convert(&img, fmt) == -1) { 1.130 + img_destroy(&img); 1.131 + return 0; 1.132 + } 1.133 + } 1.134 + 1.135 + *xsz = img.width; 1.136 + *ysz = img.height; 1.137 + return img.pixels; 1.138 +} 1.139 + 1.140 +int img_save_pixels(const char *fname, void *pix, int xsz, int ysz, enum img_fmt fmt) 1.141 +{ 1.142 + struct img_pixmap img; 1.143 + 1.144 + img_init(&img); 1.145 + img.fmt = fmt; 1.146 + img.name = (char*)fname; 1.147 + img.width = xsz; 1.148 + img.height = ysz; 1.149 + img.pixels = pix; 1.150 + 1.151 + return img_save(&img, fname); 1.152 +} 1.153 + 1.154 +void img_free_pixels(void *pix) 1.155 +{ 1.156 + free(pix); 1.157 +} 1.158 + 1.159 +int img_load(struct img_pixmap *img, const char *fname) 1.160 +{ 1.161 + int res; 1.162 + FILE *fp; 1.163 + 1.164 + if(!(fp = fopen(fname, "rb"))) { 1.165 + return -1; 1.166 + } 1.167 + res = img_read_file(img, fp); 1.168 + fclose(fp); 1.169 + return res; 1.170 +} 1.171 + 1.172 +/* TODO implement filetype selection */ 1.173 +int img_save(struct img_pixmap *img, const char *fname) 1.174 +{ 1.175 + int res; 1.176 + FILE *fp; 1.177 + 1.178 + img_set_name(img, fname); 1.179 + 1.180 + if(!(fp = fopen(fname, "wb"))) { 1.181 + return -1; 1.182 + } 1.183 + res = img_write_file(img, fp); 1.184 + fclose(fp); 1.185 + return res; 1.186 +} 1.187 + 1.188 +int img_read_file(struct img_pixmap *img, FILE *fp) 1.189 +{ 1.190 + struct img_io io = {0, def_read, def_write, def_seek}; 1.191 + 1.192 + io.uptr = fp; 1.193 + return img_read(img, &io); 1.194 +} 1.195 + 1.196 +int img_write_file(struct img_pixmap *img, FILE *fp) 1.197 +{ 1.198 + struct img_io io = {0, def_read, def_write, def_seek}; 1.199 + 1.200 + io.uptr = fp; 1.201 + return img_write(img, &io); 1.202 +} 1.203 + 1.204 +int img_read(struct img_pixmap *img, struct img_io *io) 1.205 +{ 1.206 + struct ftype_module *mod; 1.207 + 1.208 + if((mod = img_find_format_module(io))) { 1.209 + return mod->read(img, io); 1.210 + } 1.211 + return -1; 1.212 +} 1.213 + 1.214 +int img_write(struct img_pixmap *img, struct img_io *io) 1.215 +{ 1.216 + struct ftype_module *mod; 1.217 + 1.218 + if(!img->name || !(mod = img_guess_format(img->name))) { 1.219 + /* TODO throw some sort of warning? */ 1.220 + /* TODO implement some sort of module priority or let the user specify? */ 1.221 + if(!(mod = img_get_module(0))) { 1.222 + return -1; 1.223 + } 1.224 + } 1.225 + 1.226 + return mod->write(img, io); 1.227 +} 1.228 + 1.229 +int img_to_float(struct img_pixmap *img) 1.230 +{ 1.231 + enum img_fmt targ_fmt; 1.232 + 1.233 + switch(img->fmt) { 1.234 + case IMG_FMT_GREY8: 1.235 + targ_fmt = IMG_FMT_GREYF; 1.236 + break; 1.237 + 1.238 + case IMG_FMT_RGB24: 1.239 + targ_fmt = IMG_FMT_RGBF; 1.240 + break; 1.241 + 1.242 + case IMG_FMT_RGBA32: 1.243 + targ_fmt = IMG_FMT_RGBAF; 1.244 + break; 1.245 + 1.246 + default: 1.247 + return 0; /* already float */ 1.248 + } 1.249 + 1.250 + return img_convert(img, targ_fmt); 1.251 +} 1.252 + 1.253 +int img_to_integer(struct img_pixmap *img) 1.254 +{ 1.255 + enum img_fmt targ_fmt; 1.256 + 1.257 + switch(img->fmt) { 1.258 + case IMG_FMT_GREYF: 1.259 + targ_fmt = IMG_FMT_GREY8; 1.260 + break; 1.261 + 1.262 + case IMG_FMT_RGBF: 1.263 + targ_fmt = IMG_FMT_RGB24; 1.264 + break; 1.265 + 1.266 + case IMG_FMT_RGBAF: 1.267 + targ_fmt = IMG_FMT_RGBA32; 1.268 + break; 1.269 + 1.270 + default: 1.271 + return 0; /* already integer */ 1.272 + } 1.273 + 1.274 + return img_convert(img, targ_fmt); 1.275 +} 1.276 + 1.277 +int img_is_float(struct img_pixmap *img) 1.278 +{ 1.279 + return img->fmt >= IMG_FMT_GREYF && img->fmt <= IMG_FMT_RGBAF; 1.280 +} 1.281 + 1.282 +int img_has_alpha(struct img_pixmap *img) 1.283 +{ 1.284 + return img->fmt >= IMG_FMT_GREY8 && img->fmt <= IMG_FMT_RGBA32; 1.285 +} 1.286 + 1.287 +void img_io_set_user_data(struct img_io *io, void *uptr) 1.288 +{ 1.289 + io->uptr = uptr; 1.290 +} 1.291 + 1.292 +void img_io_set_read_func(struct img_io *io, size_t (*read)(void*, size_t, void*)) 1.293 +{ 1.294 + io->read = read; 1.295 +} 1.296 + 1.297 +void img_io_set_write_func(struct img_io *io, size_t (*write)(void*, size_t, void*)) 1.298 +{ 1.299 + io->write = write; 1.300 +} 1.301 + 1.302 +void img_io_set_seek_func(struct img_io *io, long (*seek)(long, int, void*)) 1.303 +{ 1.304 + io->seek = seek; 1.305 +} 1.306 + 1.307 + 1.308 +static int pixel_size(enum img_fmt fmt) 1.309 +{ 1.310 + switch(fmt) { 1.311 + case IMG_FMT_GREY8: 1.312 + return 1; 1.313 + case IMG_FMT_RGB24: 1.314 + return 3; 1.315 + case IMG_FMT_RGBA32: 1.316 + return 4; 1.317 + case IMG_FMT_GREYF: 1.318 + return sizeof(float); 1.319 + case IMG_FMT_RGBF: 1.320 + return 3 * sizeof(float); 1.321 + case IMG_FMT_RGBAF: 1.322 + return 4 * sizeof(float); 1.323 + default: 1.324 + break; 1.325 + } 1.326 + return 0; 1.327 +} 1.328 + 1.329 +static size_t def_read(void *buf, size_t bytes, void *uptr) 1.330 +{ 1.331 + return uptr ? fread(buf, 1, bytes, uptr) : 0; 1.332 +} 1.333 + 1.334 +static size_t def_write(void *buf, size_t bytes, void *uptr) 1.335 +{ 1.336 + return uptr ? fwrite(buf, 1, bytes, uptr) : 0; 1.337 +} 1.338 + 1.339 +static long def_seek(long offset, int whence, void *uptr) 1.340 +{ 1.341 + if(!uptr || fseek(uptr, offset, whence) == -1) { 1.342 + return -1; 1.343 + } 1.344 + return ftell(uptr); 1.345 +} 1.346 +