18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful,
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/skin/image.h"
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/resource.h"
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <assert.h>
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <limits.h>
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  DEBUG  0
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if DEBUG
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void D(const char*  fmt, ...)
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_list  args;
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_start(args, fmt);
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    vfprintf(stderr, fmt, args);
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_end(args);
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  D(...)  do{}while(0)
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************/
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************/
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                      *****/
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****            U T I L I T Y   F U N C T I O N S                         *****/
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                      *****/
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************/
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************/
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSDL_Surface*
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsdl_surface_from_argb32( void*  base, int  w, int  h )
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return SDL_CreateRGBSurfaceFrom(
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        base, w, h, 32, w*4,
4420894ae3fa98f82da925fbeb72e616eef509758aDavid 'Digit' Turner#if HOST_WORDS_BIGENDIAN
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        );
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void*
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectrotate_image( void*  data, unsigned  width, unsigned  height,  SkinRotation  rotation )
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    void*  result;
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result = malloc( width*height*4 );
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (result == NULL)
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (rotation & 3)
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SKIN_ROTATION_0:
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy( (char*)result, (const char*)data, width*height*4 );
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SKIN_ROTATION_270:
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned*  start    = (unsigned*)data;
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned*  src_line = start + (width-1);
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned*  dst_line = (unsigned*)result;
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned   hh;
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (hh = width; hh > 0; hh--)
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                unsigned*  src   = src_line;
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                unsigned*  dst   = dst_line;
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                unsigned   count = height;
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                for ( ; count > 0; count-- ) {
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst[0] = src[0];
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst   += 1;
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    src   += width;
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                src_line -= 1;
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                dst_line += height;
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SKIN_ROTATION_180:
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned*  start    = (unsigned*)data;
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned*  src_line = start + width*(height-1);
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned*  dst_line = (unsigned*)result;
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned   hh;
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (hh = height; hh > 0; hh--)
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                unsigned*  src = src_line + (width-1);
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                unsigned*  dst = dst_line;
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                while (src >= src_line)
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    *dst++ = *src--;
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                dst_line += width;
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                src_line -= width;
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SKIN_ROTATION_90:
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned*  start    = (unsigned*)data;
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned*  src_line = start + width*(height-1);
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned*  dst_line = (unsigned*)result ;
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned   hh;
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (hh = width; hh > 0; hh--)
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                unsigned*  src = src_line;
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                unsigned*  dst = dst_line;
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                unsigned   count;
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                for (count = height; count > 0; count--) {
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst[0] = src[0];
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst   += 1;
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    src   -= width;
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                dst_line += height;
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                src_line += 1;
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ;
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectblend_image( unsigned*  dst_pixels,
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             unsigned*  src_pixels,
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             unsigned   w,
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             unsigned   h,
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             int        alpha )
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned*  dst     = dst_pixels;
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned*  dst_end = dst + w*h;
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned*  src     = src_pixels;
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for ( ; dst < dst_end; dst++, src++ )
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned  ag = (src[0] >> 8) & 0xff00ff;
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned  rb =  src[0]       & 0xff00ff;
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ag = (ag*alpha) & 0xff00ff00;
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            rb = ((rb*alpha) >> 8) & 0x00ff00ff;
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst[0] = ag | rb;
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_desc_hash( SkinImageDesc*  desc )
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned  h = 0;
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int       n;
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (n = 0; desc->path[n] != 0; n++) {
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  c = desc->path[n];
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        h = h*33 + c;
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    h += desc->rotation*1573;
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    h += desc->blend * 7;
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return  h;
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_desc_equal( SkinImageDesc*  a,
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       SkinImageDesc*  b )
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (a->rotation == b->rotation &&
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->blend    == b->blend    &&
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            !strcmp(a->path, b->path));
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************/
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************/
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                      *****/
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****            S K I N   I M A G E S                                     *****/
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*****                                                                      *****/
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************/
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/********************************************************************************/
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectenum {
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SKIN_IMAGE_CLONE = (1 << 0)   /* this image is a clone */
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct SkinImage {
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned         hash;
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage*       link;
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int              ref_count;
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage*       next;
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage*       prev;
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SDL_Surface*     surface;
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned         flags;
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned         w, h;
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    void*            pixels;  /* 32-bit ARGB */
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImageDesc    desc;
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const SkinImage  _no_image[1] = {
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { 0, NULL, 0, NULL, NULL, NULL, 0, 0, 0, NULL, { "<none>", SKIN_ROTATION_0, 0 } }
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinImage*  SKIN_IMAGE_NONE = (SkinImage*)&_no_image;
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_free( SkinImage*  image )
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (image && image != _no_image)
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (image->surface) {
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SDL_FreeSurface(image->surface);
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            image->surface = NULL;
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (image->pixels) {
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            free( image->pixels );
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            image->pixels = NULL;
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        free(image);
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SkinImage*
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_alloc( SkinImageDesc*  desc, unsigned  hash )
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int         len   = strlen(desc->path);
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage*  image = calloc(1, sizeof(*image) + len + 1);
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (image) {
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        image->desc = desc[0];
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        image->desc.path = (const char*)(image + 1);
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy( (char*)image->desc.path, desc->path, len );
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ((char*)image->desc.path)[len] = 0;
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        image->hash      = hash;
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        image->next      = image->prev = image;
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        image->ref_count = 1;
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return image;
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void *loadpng(const char *fn, unsigned *_width, unsigned *_height);
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void *readpng(const unsigned char*  base, size_t  size, unsigned *_width, unsigned *_height);
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_load( SkinImage*  image )
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    void*     data;
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned  w, h;
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*  path = image->desc.path;
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (path[0] == ':') {
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        size_t                size;
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const unsigned char*  base;
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (path[1] == '/' || path[1] == '\\')
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            path += 1;
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        base = android_resource_find( path+1, &size );
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (base == NULL) {
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "failed to locate built-in image file '%s'\n", path );
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        data = readpng(base, size, &w, &h);
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (data == NULL) {
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "failed to load built-in image file '%s'\n", path );
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        data = loadpng(path, &w, &h);
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (data == NULL) {
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "failed to load image file '%s'\n", path );
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* the data is loaded into memory as RGBA bytes by libpng. we want to manage
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * the values as 32-bit ARGB pixels, so swap the bytes accordingly depending
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * on our CPU endianess
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    */
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        unsigned*  d     = data;
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        unsigned*  d_end = d + w*h;
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for ( ; d < d_end; d++ ) {
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unsigned  pix = d[0];
31820894ae3fa98f82da925fbeb72e616eef509758aDavid 'Digit' Turner#if HOST_WORDS_BIGENDIAN
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* R,G,B,A read as RGBA => ARGB */
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pix = ((pix >> 8) & 0xffffff) | (pix << 24);
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* R,G,B,A read as ABGR => ARGB */
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pix = (pix & 0xff00ff00) | ((pix >> 16) & 0xff) | ((pix & 0xff) << 16);
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            d[0] = pix;
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image->pixels = data;
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image->w      = w;
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image->h      = h;
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image->surface = sdl_surface_from_argb32( image->pixels, w, h );
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (image->surface == NULL) {
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(stderr, "failed to create SDL surface for '%s' image\n", path);
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* simple hash table for images */
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  NUM_BUCKETS  64
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct {
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage*     buckets[ NUM_BUCKETS ];
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage      mru_head;
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int            num_images;
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long  total_pixels;
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long  max_pixels;
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long  total_images;
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} SkinImageCache;
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_cache_init( SkinImageCache*  cache )
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(cache, 0, sizeof(*cache));
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if DEBUG
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cache->max_pixels = 1;
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cache->max_pixels = 4*1024*1024;  /* limit image cache to 4 MB */
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cache->mru_head.next = cache->mru_head.prev = &cache->mru_head;
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_cache_remove( SkinImageCache*  cache,
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         SkinImage*       image )
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* remove from hash table */
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage**  pnode = cache->buckets + (image->hash & (NUM_BUCKETS-1));
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage*   node;
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (;;) {
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        node = *pnode;
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        assert(node != NULL);
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (node == NULL)  /* should not happen */
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (node == image) {
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *pnode = node->link;
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pnode = &node->link;
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    D( "skin_image_cache: remove '%s' (rot=%d), %d pixels\n",
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       node->desc.path, node->desc.rotation, node->w*node->h );
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* remove from mru list */
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image->prev->next = image->next;
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image->next->prev = image->prev;
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cache->total_pixels -= image->w*image->h;
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cache->total_images -= 1;
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SkinImage*
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_cache_raise( SkinImageCache*  cache,
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        SkinImage*       image )
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (image != cache->mru_head.next) {
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SkinImage*  prev = image->prev;
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SkinImage*  next = image->next;
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* remove from mru list */
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        prev->next = next;
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        next->prev = prev;
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* add to top */
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        image->prev = &cache->mru_head;
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        image->next = image->prev->next;
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        image->prev->next = image;
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        image->next->prev = image;
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return image;
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_cache_flush( SkinImageCache*  cache )
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage*     image = cache->mru_head.prev;
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int            count = 0;
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    D("skin_image_cache_flush: starting\n");
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (cache->total_pixels > cache->max_pixels &&
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           image != &cache->mru_head)
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SkinImage*  prev = image->prev;
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (image->ref_count == 0) {
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_image_cache_remove(cache, image);
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            count += 1;
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        image = prev;
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    D("skin_image_cache_flush: finished, %d images flushed\n", count);
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SkinImage**
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_lookup_p( SkinImageCache*   cache,
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     SkinImageDesc*    desc,
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     unsigned         *phash )
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned     h     = skin_image_desc_hash(desc);
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned     index = h & (NUM_BUCKETS-1);
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage**  pnode = &cache->buckets[index];
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (;;) {
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SkinImage*  node = *pnode;
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (node == NULL)
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (node->hash == h && skin_image_desc_equal(desc, &node->desc))
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pnode = &node->link;
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *phash = h;
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return  pnode;
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SkinImage*
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_create( SkinImageDesc*  desc, unsigned  hash )
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage*  node;
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    node = skin_image_alloc( desc, hash );
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (node == NULL)
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return SKIN_IMAGE_NONE;
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (desc->rotation == SKIN_ROTATION_0 &&
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        desc->blend    == SKIN_BLEND_FULL)
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (skin_image_load(node) < 0) {
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_image_free(node);
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return SKIN_IMAGE_NONE;
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SkinImageDesc  desc0 = desc[0];
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SkinImage*     parent;
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        desc0.rotation = SKIN_ROTATION_0;
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        desc0.blend    = SKIN_BLEND_FULL;
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        parent = skin_image_find( &desc0 );
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (parent == SKIN_IMAGE_NONE)
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return SKIN_IMAGE_NONE;
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SDL_LockSurface(parent->surface);
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (desc->rotation == SKIN_ROTATION_90 ||
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            desc->rotation == SKIN_ROTATION_270)
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            node->w = parent->h;
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            node->h = parent->w;
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            node->w = parent->w;
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            node->h = parent->h;
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        node->pixels = rotate_image( parent->pixels, parent->w, parent->h,
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    desc->rotation );
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SDL_UnlockSurface(parent->surface);
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_image_unref(&parent);
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (node->pixels  == NULL) {
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_image_free(node);
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return SKIN_IMAGE_NONE;
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (desc->blend != SKIN_BLEND_FULL)
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            blend_image( node->pixels, node->pixels, node->w, node->h, desc->blend );
5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        node->surface = sdl_surface_from_argb32( node->pixels, node->w, node->h );
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (node->surface == NULL) {
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            skin_image_free(node);
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return SKIN_IMAGE_NONE;
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return node;
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SkinImageCache   _image_cache[1];
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int              _image_cache_init;
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinImage*
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_find( SkinImageDesc*  desc )
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImageCache*  cache = _image_cache;
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned         hash;
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage**      pnode = skin_image_lookup_p( cache, desc, &hash );
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage*       node  = *pnode;
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!_image_cache_init) {
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        _image_cache_init = 1;
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_image_cache_init(cache);
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (node) {
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        node->ref_count += 1;
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return skin_image_cache_raise( cache, node );
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    node = skin_image_create( desc, hash );
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (node == SKIN_IMAGE_NONE)
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return node;
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* add to hash table */
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    node->link = *pnode;
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *pnode     = node;
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* add to mru list */
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_image_cache_raise( cache, node );
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    D( "skin_image_cache: add '%s' (rot=%d), %d pixels\n",
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       node->desc.path, node->desc.rotation, node->w*node->h );
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cache->total_pixels += node->w*node->h;
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cache->total_pixels > cache->max_pixels)
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_image_cache_flush( cache );
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return node;
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinImage*
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_find_simple( const char*  path )
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImageDesc  desc;
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    desc.path     = path;
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    desc.rotation = SKIN_ROTATION_0;
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    desc.blend    = SKIN_BLEND_FULL;
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return skin_image_find( &desc );
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinImage*
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_ref( SkinImage*  image )
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (image && image != _no_image)
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        image->ref_count += 1;
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return image;
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_unref( SkinImage**  pimage )
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage*  image = *pimage;
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (image) {
6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (image != _no_image && --image->ref_count == 0) {
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ((image->flags & SKIN_IMAGE_CLONE) != 0) {
6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                skin_image_free(image);
6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *pimage = NULL;
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinImage*
6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_rotate( SkinImage*  source, SkinRotation  rotation )
6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImageDesc  desc;
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage*     image;
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (source == _no_image || source->desc.rotation == rotation)
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return source;
6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    desc          = source->desc;
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    desc.rotation = rotation;
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image         = skin_image_find( &desc );
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_image_unref( &source );
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return image;
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinImage*
6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_clone( SkinImage*  source )
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage*   image;
6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (source == NULL || source == _no_image)
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return SKIN_IMAGE_NONE;
6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image = calloc(1,sizeof(*image));
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (image == NULL)
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto Fail;
6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image->desc  = source->desc;
6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image->hash  = source->hash;
6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image->flags = SKIN_IMAGE_CLONE;
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image->w     = source->w;
6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image->h     = source->h;
6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image->pixels = rotate_image( source->pixels, source->w, source->h,
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                  SKIN_ROTATION_0 );
6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (image->pixels == NULL)
6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto Fail;
6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    image->surface = sdl_surface_from_argb32( image->pixels, image->w, image->h );
6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (image->surface == NULL)
6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto Fail;
6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return image;
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFail:
6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (image != NULL)
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_image_free(image);
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return SKIN_IMAGE_NONE;
6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinImage*
6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_clone_full( SkinImage*    source,
6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       SkinRotation  rotation,
6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       int           blend )
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImageDesc   desc;
6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinImage*      clone;
6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (source == NULL || source == SKIN_IMAGE_NONE)
6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return SKIN_IMAGE_NONE;
6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (rotation == SKIN_ROTATION_0 &&
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        blend    == SKIN_BLEND_FULL)
6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return skin_image_clone(source);
6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    desc.path     = source->desc.path;
6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    desc.rotation = rotation;
6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    desc.blend    = blend;
6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    clone = skin_image_create( &desc, 0 );
6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (clone != SKIN_IMAGE_NONE)
6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        clone->flags |= SKIN_IMAGE_CLONE;
6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return clone;
6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* apply blending to a source skin image and copy the result to a target clone image */
6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_blend_clone( SkinImage*  clone, SkinImage*  source, int  blend )
6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SDL_LockSurface( clone->surface );
6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    blend_image( clone->pixels, source->pixels, source->w, source->h, blend );
6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SDL_UnlockSurface( clone->surface );
6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SDL_SetAlpha( clone->surface, SDL_SRCALPHA, 255 );
6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_w( SkinImage*  image )
7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return  image ? image->w : 0;
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_h( SkinImage*  image )
7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return  image ? image->h : 0;
7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_org_w( SkinImage*  image )
7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (image) {
7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (image->desc.rotation == SKIN_ROTATION_90 ||
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            image->desc.rotation == SKIN_ROTATION_270)
7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return image->h;
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return image->w;
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_org_h( SkinImage*  image )
7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (image) {
7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (image->desc.rotation == SKIN_ROTATION_90 ||
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            image->desc.rotation == SKIN_ROTATION_270)
7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return image->w;
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return image->h;
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSDL_Surface*
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_image_surface( SkinImage*  image )
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return image ? image->surface : NULL;
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
743