/* * libpipi Proper image processing implementation library * Copyright (c) 2004-2008 Sam Hocevar * All Rights Reserved * * $Id$ * * This library is free software. It comes without any warranty, to * the extent permitted by applicable law. You can redistribute it * and/or modify it under the terms of the Do What The Fuck You Want * To Public License, Version 2, as published by Sam Hocevar. See * http://sam.zoy.org/wtfpl/COPYING for more details. */ /* * pixels.c: pixel-level image manipulation */ #include "config.h" #include "common.h" #include #include #include #include #include "pipi.h" #include "pipi_internals.h" static void init_tables(void); static float u8tof32_table[256]; static inline float u8tof32(uint8_t p) { return u8tof32_table[(int)p]; } /* Return a direct pointer to an image's pixels. */ pipi_pixels_t *pipi_getpixels(pipi_image_t *img, pipi_format_t type) { size_t bytes = 0; int x, y, i; if(type < 0 || type >= PIPI_PIXELS_MAX) return NULL; if(img->last_modified == type) return &img->p[type]; /* Allocate pixels if necessary */ if(!img->p[type].pixels) { switch(type) { case PIPI_PIXELS_RGBA32: bytes = img->w * img->h * 4 * sizeof(uint8_t); break; case PIPI_PIXELS_RGBA_F: bytes = img->w * img->h * 4 * sizeof(float); break; default: return NULL; } img->p[type].pixels = malloc(bytes); } /* Convert pixels */ if(img->last_modified == PIPI_PIXELS_RGBA32 && type == PIPI_PIXELS_RGBA_F) { uint8_t *src = (uint8_t *)img->p[PIPI_PIXELS_RGBA32].pixels; float *dest = (float *)img->p[type].pixels; init_tables(); for(y = 0; y < img->h; y++) for(x = 0; x < img->w; x++) for(i = 0; i < 4; i++) dest[4 * (y * img->w + x) + i] = u8tof32(src[4 * (y * img->w + x) + i]); } else if(img->last_modified == PIPI_PIXELS_RGBA_F && type == PIPI_PIXELS_RGBA32) { float *src = (float *)img->p[PIPI_PIXELS_RGBA_F].pixels; uint8_t *dest = (uint8_t *)img->p[type].pixels; for(y = 0; y < img->h; y++) for(x = 0; x < img->w; x++) for(i = 0; i < 4; i++) { double p = src[4 * (y * img->w + x) + i]; dest[4 * (y * img->w + x) + i] = (int)(255.999 * pow(p, 1. / 2.2)); } } else { memset(img->p[type].pixels, 0, bytes); } img->last_modified = type; return &img->p[type]; } static void init_tables(void) { static int done = 0; int i; if(done) return; for(i = 0; i < 256; i++) u8tof32_table[i] = pow((double)i / 255., 2.2); done = 1; }