Home | History | Annotate | Download | only in deimage
      1 /*-------------------------------------------------------------------------
      2  * drawElements Image Library
      3  * --------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Image library.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "deImage.h"
     25 #include "deMemory.h"
     26 #include "deInt32.h"
     27 #include "deMath.h"
     28 
     29 static int deImageFormat_getBytesPerPixel (deImageFormat format)
     30 {
     31 	DE_ASSERT(format == DE_IMAGEFORMAT_XRGB8888 || format == DE_IMAGEFORMAT_ARGB8888);
     32 	DE_UNREF(format);
     33 	return 4;
     34 }
     35 
     36 static void* getPixelAddress (const deImage* image, int x, int y)
     37 {
     38 	int offset = ((y*image->width) + x) * deImageFormat_getBytesPerPixel(image->format);
     39 	DE_ASSERT(deInBounds32(x, 0, image->width));
     40 	DE_ASSERT(deInBounds32(y, 0, image->height));
     41 	return (void*)((deUint8*)image->pixels + offset);
     42 }
     43 
     44 deImage* deImage_create (int width, int height, deImageFormat format)
     45 {
     46 	deImage*	image	= DE_NEW(deImage);
     47 	int			bpp		= deImageFormat_getBytesPerPixel(format);
     48 	if (!image)
     49 		return DE_NULL;
     50 
     51 	image->width	= width;
     52 	image->height	= height;
     53 	image->format	= format;
     54 	image->pixels	= deMalloc(width * height * bpp);
     55 	if (!image->pixels)
     56 	{
     57 		deFree(image);
     58 		return DE_NULL;
     59 	}
     60 	memset(image->pixels, 0, width * height * bpp);
     61 
     62 	return image;
     63 }
     64 
     65 void deImage_destroy (deImage* image)
     66 {
     67 	deFree(image->pixels);
     68 	deFree(image);
     69 }
     70 
     71 deARGB deImage_getPixel (const deImage* image, int x, int y)
     72 {
     73 	void* addr = getPixelAddress(image, x, y);
     74 	switch (image->format)
     75 	{
     76 		case DE_IMAGEFORMAT_XRGB8888:	return *(deARGB*)addr;
     77 		case DE_IMAGEFORMAT_ARGB8888:	return *(deARGB*)addr;
     78 		default:
     79 			DE_FATAL("deImage_getPixel(): invalid format");
     80 			return deARGB_black();
     81 	}
     82 }
     83 
     84 void deImage_setPixel (deImage* image, int x, int y, deARGB argb)
     85 {
     86 	void* addr = getPixelAddress(image, x, y);
     87 	switch (image->format)
     88 	{
     89 		case DE_IMAGEFORMAT_XRGB8888:	*(deARGB*)addr = argb;	break;
     90 		case DE_IMAGEFORMAT_ARGB8888:	*(deARGB*)addr = argb;	break;
     91 		default:
     92 			DE_FATAL("deImage_getPixel(): invalid format");
     93 	}
     94 }
     95 
     96 deImage* deImage_convertFormat (const deImage* image, deImageFormat format)
     97 {
     98 	int			width		= image->width;
     99 	int			height		= image->height;
    100 	deImage*	converted	= deImage_create(width, height, format);
    101 	if (!converted)
    102 		return DE_NULL;
    103 
    104 	if (format == image->format)
    105 		memcpy(converted->pixels, image->pixels, width * height * deImageFormat_getBytesPerPixel(format));
    106 	else
    107 	{
    108 		int x, y;
    109 		for (y = 0; y < height; y++)
    110 			for (x = 0; x < width; x++)
    111 				deImage_setPixel(converted, x, y, deImage_getPixel(image, x, y));
    112 	}
    113 
    114 	return converted;
    115 }
    116 
    117 deImage* deImage_scale (const deImage* srcImage, int dstWidth, int dstHeight)
    118 {
    119 	int			srcWidth	= srcImage->width;
    120 	int			srcHeight	= srcImage->height;
    121 	deImage*	result		= deImage_create(dstWidth, dstHeight, srcImage->format);
    122 	int			x, y;
    123 
    124 	for (y = 0; y < dstHeight; y++)
    125 	{
    126 		for (x = 0; x < dstWidth; x++)
    127 		{
    128 			float	xFloat	= ((float)x + 0.5f) / (float)dstWidth * (float)srcImage->width - 0.5f;
    129 			float	yFloat	= ((float)y + 0.5f) / (float)dstHeight * (float)srcImage->height - 0.5f;
    130 			int		xFixed	= deFloorFloatToInt32(xFloat * 256.0f);
    131 			int		yFixed	= deFloorFloatToInt32(yFloat * 256.0f);
    132 			int		xFactor	= (xFixed & 0xFF);
    133 			int		yFactor	= (yFixed & 0xFF);
    134 			int		f00		= ((256-xFactor) * (256-yFactor)) >> 8;
    135 			int		f10		= ((256-xFactor) * yFactor) >> 8;
    136 			int		f01		= (xFactor * (256-yFactor)) >> 8;
    137 			int		f11		= (xFactor * yFactor) >> 8;
    138 			int		x0		= (xFixed >> 8);
    139 			int		y0		= (yFixed >> 8);
    140 			int		x1		= deClamp32(x0+1, 0, srcWidth-1);
    141 			int		y1		= deClamp32(y0+1, 0, srcHeight-1);
    142 			DE_ASSERT(deInBounds32(x0, 0, srcWidth));
    143 			DE_ASSERT(deInBounds32(y0, 0, srcHeight));
    144 
    145 			/* Filtering. */
    146 			{
    147 				deARGB p00 = deImage_getPixel(srcImage, x0, y0);
    148 				deARGB p10 = deImage_getPixel(srcImage, x1, y0);
    149 				deARGB p01 = deImage_getPixel(srcImage, x0, y1);
    150 				deARGB p11 = deImage_getPixel(srcImage, x1, y1);
    151 				deARGB pix = deARGB_add(deARGB_add(deARGB_multiply(p00, f00), deARGB_multiply(p10, f10)),
    152 										deARGB_add(deARGB_multiply(p01, f01), deARGB_multiply(p11, f11)));
    153 				deImage_setPixel(result, x, y, pix);
    154 			}
    155 		}
    156 	}
    157 
    158 	return result;
    159 }
    160 
    161 void deImage_copyToUint8RGBA (const deImage* image, deUint8* pixels)
    162 {
    163 	int width	= image->width;
    164 	int height	= image->height;
    165 	int x,y;
    166 
    167 	for (y = 0; y < height; y++)
    168 	for (x = 0; x < width; x++)
    169 	{
    170 		deARGB	pixel	= deImage_getPixel(image, x, y);
    171 		int		ndx		= (y * width) + x;
    172 		pixels[4*ndx+0] = (deUint8)deARGB_getRed(pixel);
    173 		pixels[4*ndx+1] = (deUint8)deARGB_getGreen(pixel);
    174 		pixels[4*ndx+2] = (deUint8)deARGB_getBlue(pixel);
    175 		pixels[4*ndx+3] = (deUint8)deARGB_getAlpha(pixel);
    176 	}
    177 }
    178 
    179 void* deImage_getPixelPtr (const deImage* image)
    180 {
    181 	return image->pixels;
    182 }
    183 
    184 int deImage_getWidth (const deImage* image)
    185 {
    186 	return image->width;
    187 }
    188 
    189 int deImage_getHeight (const deImage* image)
    190 {
    191 	return image->height;
    192 }
    193