added tile_manager_get_sub_preview().

2007-07-17  Sven Neumann  <sven@gimp.org>

	* app/base/tile-manager-preview.[ch]: added
	tile_manager_get_sub_preview().

	* app/core/gimpdrawable-preview.c: use the new function except 
for
	indexed drawables.


svn path=/trunk/; revision=22950
This commit is contained in:
Sven Neumann 2007-07-17 20:33:10 +00:00 committed by Sven Neumann
parent 1065f0eb85
commit 58ee85dfa6
4 changed files with 160 additions and 102 deletions

View File

@ -1,3 +1,11 @@
2007-07-17 Sven Neumann <sven@gimp.org>
* app/base/tile-manager-preview.[ch]: added
tile_manager_get_sub_preview().
* app/core/gimpdrawable-preview.c: use the new function except for
indexed drawables.
2007-07-17 Raphaël Quinet <raphael@gimp.org>
Reorganized the way JPEG comments and metadata are loaded.

View File

@ -30,33 +30,83 @@
#include "tile-manager-preview.h"
static TempBuf * tile_manager_create_preview (TileManager *tiles,
gint src_x,
gint src_y,
gint src_width,
gint src_height,
gint dest_width,
gint dest_height);
TempBuf *
tile_manager_get_preview (TileManager *tiles,
gint width,
gint height)
{
TempBuf *preview;
PixelRegion srcPR;
PixelRegion destPR;
gint subsample;
g_return_val_if_fail (tiles != NULL, NULL);
g_return_val_if_fail (width > 0 && height > 0, NULL);
pixel_region_init (&srcPR, tiles,
0, 0,
tile_manager_width (tiles), tile_manager_height (tiles),
FALSE);
return tile_manager_create_preview (tiles,
0, 0,
tile_manager_width (tiles),
tile_manager_height (tiles),
width, height);
}
preview = temp_buf_new (width, height, tile_manager_bpp (tiles), 0, 0, NULL);
TempBuf *
tile_manager_get_sub_preview (TileManager *tiles,
gint src_x,
gint src_y,
gint src_width,
gint src_height,
gint dest_width,
gint dest_height)
{
g_return_val_if_fail (tiles != NULL, NULL);
pixel_region_init_temp_buf (&destPR, preview, 0, 0, width, height);
g_return_val_if_fail (src_x >= 0 &&
src_x < tile_manager_width (tiles), NULL);
g_return_val_if_fail (src_y >= 0 &&
src_y < tile_manager_height (tiles), NULL);
g_return_val_if_fail (src_width > 0 &&
src_x + src_width <= tile_manager_width (tiles), NULL);
g_return_val_if_fail (src_height > 0 &&
src_y + src_height <= tile_manager_height (tiles),
NULL);
g_return_val_if_fail (dest_width > 0 && dest_height > 0, NULL);
return tile_manager_create_preview (tiles,
src_x, src_y, src_width, src_height,
dest_width, dest_height);
}
static TempBuf *
tile_manager_create_preview (TileManager *tiles,
gint src_x,
gint src_y,
gint src_width,
gint src_height,
gint dest_width,
gint dest_height)
{
TempBuf *preview;
PixelRegion srcPR;
PixelRegion destPR;
gint subsample = 1;
preview = temp_buf_new (dest_width, dest_height,
tile_manager_bpp (tiles), 0, 0, NULL);
pixel_region_init (&srcPR, tiles, src_x, src_y, src_width, src_height, FALSE);
pixel_region_init_temp_buf (&destPR, preview, 0, 0, dest_width, dest_height);
/* calculate 'acceptable' subsample */
subsample = 1;
while ((width * (subsample + 1) * 2 < srcPR.w) &&
(height * (subsample + 1) * 2 < srcPR.h))
while ((dest_width * (subsample + 1) * 2 < src_width) &&
(dest_height * (subsample + 1) * 2 < src_height))
subsample += 1;
subsample_region (&srcPR, &destPR, subsample);

View File

@ -20,9 +20,16 @@
#define __TILE_MANAGER_PREVIEW_H__
TempBuf * tile_manager_get_preview (TileManager *tiles,
gint width,
gint height);
TempBuf * tile_manager_get_preview (TileManager *tiles,
gint width,
gint height);
TempBuf * tile_manager_get_sub_preview (TileManager *tiles,
gint src_x,
gint src_y,
gint src_width,
gint src_height,
gint dest_width,
gint dest_height);
#endif /* __TILE_MANAGER_PREVIEW_H__ */

View File

@ -28,6 +28,7 @@
#include "base/pixel-region.h"
#include "base/temp-buf.h"
#include "base/tile-manager-preview.h"
#include "paint-funcs/scale-funcs.h"
@ -44,14 +45,22 @@
/* local function prototypes */
static TempBuf * gimp_drawable_preview_private (GimpDrawable *drawable,
gint width,
gint height);
static void gimp_drawable_preview_scale (GimpImageType type,
const guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample);
static TempBuf * gimp_drawable_preview_private (GimpDrawable *drawable,
gint width,
gint height);
static TempBuf * gimp_drawable_indexed_preview (GimpDrawable *drawable,
const guchar *cmap,
gint src_x,
gint src_y,
gint src_width,
gint src_height,
gint dest_width,
gint dest_height);
static void subsample_indexed_region (PixelRegion *srcPR,
PixelRegion *destPR,
const guchar *cmap,
gint subsample);
/* public functions */
@ -129,11 +138,6 @@ gimp_drawable_get_sub_preview (GimpDrawable *drawable,
{
GimpItem *item;
GimpImage *image;
TempBuf *preview_buf;
PixelRegion srcPR;
PixelRegion destPR;
gint bytes;
gint subsample;
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
g_return_val_if_fail (src_x >= 0, NULL);
@ -153,37 +157,15 @@ gimp_drawable_get_sub_preview (GimpDrawable *drawable,
if (! image->gimp->config->layer_previews)
return NULL;
bytes = gimp_drawable_preview_bytes (drawable);
if (GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (drawable)) == GIMP_INDEXED)
return gimp_drawable_indexed_preview (drawable,
gimp_image_get_colormap (image),
src_x, src_y, src_width, src_height,
dest_width, dest_height);
/* calculate 'acceptable' subsample */
subsample = 1;
while ((dest_width * (subsample + 1) * 2 < src_width) &&
(dest_height * (subsample + 1) * 2 < src_width))
subsample += 1;
pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
src_x, src_y, src_width, src_height,
FALSE);
preview_buf = temp_buf_new (dest_width, dest_height, bytes, 0, 0, NULL);
pixel_region_init_temp_buf (&destPR, preview_buf,
0, 0, dest_width, dest_height);
if (GIMP_IS_LAYER (drawable))
{
gimp_drawable_preview_scale (gimp_drawable_type (drawable),
gimp_image_get_colormap (image),
&srcPR, &destPR,
subsample);
}
else if (GIMP_IS_CHANNEL (drawable))
{
subsample_region (&srcPR, &destPR, subsample);
}
return preview_buf;
return tile_manager_get_sub_preview (gimp_drawable_get_tiles (drawable),
src_x, src_y, src_width, src_height,
dest_width, dest_height);
}
@ -220,12 +202,46 @@ gimp_drawable_preview_private (GimpDrawable *drawable,
return ret_buf;
}
static TempBuf *
gimp_drawable_indexed_preview (GimpDrawable *drawable,
const guchar *cmap,
gint src_x,
gint src_y,
gint src_width,
gint src_height,
gint dest_width,
gint dest_height)
{
TempBuf *preview_buf;
PixelRegion srcPR;
PixelRegion destPR;
gint bytes = gimp_drawable_preview_bytes (drawable);
gint subsample = 1;
/* calculate 'acceptable' subsample */
while ((dest_width * (subsample + 1) * 2 < src_width) &&
(dest_height * (subsample + 1) * 2 < src_width))
subsample += 1;
pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
src_x, src_y, src_width, src_height,
FALSE);
preview_buf = temp_buf_new (dest_width, dest_height, bytes, 0, 0, NULL);
pixel_region_init_temp_buf (&destPR, preview_buf,
0, 0, dest_width, dest_height);
subsample_indexed_region (&srcPR, &destPR, cmap, subsample);
return preview_buf;
}
static void
gimp_drawable_preview_scale (GimpImageType type,
const guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample)
subsample_indexed_region (PixelRegion *srcPR,
PixelRegion *destPR,
const guchar *cmap,
gint subsample)
{
#define EPSILON 0.000001
guchar *src, *s;
@ -245,7 +261,7 @@ gimp_drawable_preview_scale (GimpImageType type,
gboolean advance_dest;
gboolean has_alpha;
g_return_if_fail (! GIMP_IMAGE_TYPE_IS_INDEXED (type) || cmap != NULL);
g_return_if_fail (cmap != NULL);
orig_width = srcPR->w / subsample;
orig_height = srcPR->h / subsample;
@ -256,7 +272,7 @@ gimp_drawable_preview_scale (GimpImageType type,
bytes = destPR->bytes;
destwidth = destPR->rowstride;
has_alpha = GIMP_IMAGE_TYPE_HAS_ALPHA (type);
has_alpha = pixel_region_has_alpha (srcPR);
/* the data pointers... */
src = g_new (guchar, orig_width * bytes);
@ -333,51 +349,28 @@ gimp_drawable_preview_scale (GimpImageType type,
j = width;
while (j)
{
gint index = *s * 3;
tot_frac = x_frac[frac++] * y_frac;
/* If indexed, transform the color to RGB */
if (GIMP_IMAGE_TYPE_IS_INDEXED (type))
/* transform the color to RGB */
if (has_alpha)
{
gint index = *s * 3;
if (has_alpha)
{
if (s[ALPHA_I_PIX] & 0x80)
{
r[RED_PIX] += cmap[index++] * tot_frac;
r[GREEN_PIX] += cmap[index++] * tot_frac;
r[BLUE_PIX] += cmap[index++] * tot_frac;
r[ALPHA_PIX] += tot_frac;
}
/* else the pixel contributes nothing and needs
* not to be added
*/
}
else
if (s[ALPHA_I_PIX] & 0x80)
{
r[RED_PIX] += cmap[index++] * tot_frac;
r[GREEN_PIX] += cmap[index++] * tot_frac;
r[BLUE_PIX] += cmap[index++] * tot_frac;
r[ALPHA_PIX] += tot_frac;
}
/* else the pixel contributes nothing and needs not to be added
*/
}
else
{
if (has_alpha)
{
/* premultiply */
gdouble local_frac = tot_frac * (gdouble) s[bytes - 1] / 255.0;
for (b = 0; b < (bytes - 1); b++)
r[b] += s[b] * local_frac;
r[bytes - 1] += local_frac;
}
else
{
for (b = 0; b < bytes; b++)
r[b] += s[b] * tot_frac;
}
r[RED_PIX] += cmap[index++] * tot_frac;
r[GREEN_PIX] += cmap[index++] * tot_frac;
r[BLUE_PIX] += cmap[index++] * tot_frac;
}
/* increment the destination */