From b64a243725747abe27cddafa873bcdae9f8939a4 Mon Sep 17 00:00:00 2001 From: sam Date: Mon, 12 Jan 2009 23:50:53 +0000 Subject: [PATCH] Create basic tile handling functions. git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@3339 92316355-f0b4-4df1-b90c-862c8a59935f --- pipi/Makefile.am | 1 + pipi/pipi.h | 8 +++ pipi/pipi_internals.h | 21 ++++++++ pipi/tiles.c | 112 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+) create mode 100644 pipi/tiles.c diff --git a/pipi/Makefile.am b/pipi/Makefile.am index adc3279..d29d426 100644 --- a/pipi/Makefile.am +++ b/pipi/Makefile.am @@ -21,6 +21,7 @@ libpipi_la_SOURCES = \ pipi_template.h \ context.c \ pixels.c \ + tiles.c \ codec.c \ stock.c \ colorstring.c \ diff --git a/pipi/pipi.h b/pipi/pipi.h index f2b218f..69d4356 100644 --- a/pipi/pipi.h +++ b/pipi/pipi.h @@ -101,6 +101,9 @@ typedef struct } pipi_pixels_t; +/* pipi_tile_t: the internal tile type */ +typedef struct pipi_tile pipi_tile_t; + /* pipi_image_t: the main image type */ typedef struct pipi_image pipi_image_t; @@ -127,6 +130,11 @@ __extern void pipi_destroy_context(pipi_context_t *); __extern pipi_command_t const *pipi_get_command_list(void); __extern int pipi_command(pipi_context_t *, char const *, ...); +__extern pipi_tile_t *pipi_get_tile(pipi_image_t *, int, int, int, + pipi_format_t, int); +__extern void pipi_release_tile(pipi_image_t *, pipi_tile_t *); +__extern pipi_tile_t *pipi_create_tile(pipi_format_t, int); + __extern pipi_image_t *pipi_load(char const *); __extern pipi_image_t *pipi_load_stock(char const *); __extern pipi_image_t *pipi_new(int, int); diff --git a/pipi/pipi_internals.h b/pipi/pipi_internals.h index 3bbb76a..ab7d47c 100644 --- a/pipi/pipi_internals.h +++ b/pipi/pipi_internals.h @@ -35,6 +35,22 @@ struct pipi_histogram unsigned int y[256]; }; +#ifdef USE_TILES +#define TILE_SIZE 128 + +struct pipi_tile +{ + int x, y; + int zoom; + + int refcount; + + pipi_format_t fmt; + int plane; + union { uint8_t *u8; float *f; double *d; } data; + union { uint8_t u8[1]; float f[1]; double d[1]; } align; +}; +#endif /* USE_TILES */ /* pipi_image_t: the image structure. This is probably going to be the most * complex structure in the library, but right now it only has fairly normal @@ -43,6 +59,11 @@ struct pipi_image { int w, h, pitch; +#ifdef USE_TILES + pipi_tile_t **tiles; + int ntiles; +#endif /* USE_TILES */ + /* A list of internal image flags. * wrap: should filters wrap around at edges? * u8: are the image samples still 8-bit per channel? */ diff --git a/pipi/tiles.c b/pipi/tiles.c new file mode 100644 index 0000000..315add7 --- /dev/null +++ b/pipi/tiles.c @@ -0,0 +1,112 @@ +/* + * libpipi Pathetic image processing interface 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. + */ + +/* + * tiles.c: the tiles system + */ + +#include "config.h" + +#include +#include +#include + +#include "pipi.h" +#include "pipi_internals.h" + +#ifdef USE_TILES +pipi_tile_t *pipi_get_tile(pipi_image_t *img, int x, int y, int zoom, + pipi_format_t fmt, int plane) +{ + pipi_tile_t * ret; + int i; + + /* If the tile already exists, return it. */ + for(i = 0; i < img->ntiles; i++) + { + if(img->tiles[i]->x == x && img->tiles[i]->y == y + && img->tiles[i]->fmt == fmt + && img->tiles[i]->zoom == zoom + && img->tiles[i]->plane == plane) + { + img->tiles[i]->refcount++; + return img->tiles[i]; + } + } + + /* Create a tile. When the image provides a tile creation function, + * we should use it. */ + ret = pipi_create_tile(fmt, plane); + ret->x = x; + ret->y = y; + ret->refcount = 1; + + /* Insert tile and return it. */ + img->ntiles++; + img->tiles = realloc(img->tiles, img->ntiles * sizeof(pipi_tile_t *)); + img->tiles[img->ntiles - 1] = ret; + + return ret; +} + +void pipi_release_tile(pipi_image_t *img, pipi_tile_t *tile) +{ + int i; + + for(i = 0; i < img->ntiles; i++) + { + if(img->tiles[i] == tile) + { + img->tiles[i]->refcount--; + if(img->tiles[i]->refcount <= 0) + { + free(img->tiles[i]); + img->tiles[i] = img->tiles[img->ntiles - 1]; + img->ntiles--; + } + return; + } + } +} + +pipi_tile_t *pipi_create_tile(pipi_format_t fmt, int plane) +{ + pipi_tile_t * ret; + size_t bytes; + + switch(fmt) + { + case PIPI_PIXELS_RGBA_C: + case PIPI_PIXELS_BGR_C: + bytes = sizeof(uint8_t) * TILE_SIZE * TILE_SIZE; + break; + case PIPI_PIXELS_RGBA_F: + case PIPI_PIXELS_Y_F: + bytes = sizeof(float) * TILE_SIZE * TILE_SIZE; + break; + default: + bytes = 0; + break; + } + + ret = malloc(sizeof(pipi_tile_t) + bytes); + ret->fmt = fmt; + ret->plane = plane; + ret->data.u8 = ret->align.u8; + + return ret; +} + +#endif /* USE_TILES */ +