diff options
author | Henry Stiles <henry.stiles@artifex.com> | 1998-07-28 06:22:20 +0000 |
---|---|---|
committer | Henry Stiles <henry.stiles@artifex.com> | 1998-07-28 06:22:20 +0000 |
commit | 5fbdbaab7335a147a3a7890b5c6fc123926815db (patch) | |
tree | 154edc89b06c38333fd6d4b9abaf0ee8740ddf6a /gs/src/gsimage.c | |
parent | 14cf10e3738f95f7864978c5a4778b50fb39524b (diff) |
This commit was generated by cvs2svn to compensate for changes in r257,
which included commits to RCS files with non-trunk default branches.
git-svn-id: http://svn.ghostscript.com/ghostpcl/trunk/ghostpcl@258 06663e23-700e-0410-b217-a244a6096597
Diffstat (limited to 'gs/src/gsimage.c')
-rw-r--r-- | gs/src/gsimage.c | 517 |
1 files changed, 260 insertions, 257 deletions
diff --git a/gs/src/gsimage.c b/gs/src/gsimage.c index acbeea046..b117a03b8 100644 --- a/gs/src/gsimage.c +++ b/gs/src/gsimage.c @@ -1,22 +1,22 @@ -/* Copyright (C) 1996, 1997 Aladdin Enterprises. All rights reserved. - - This file is part of Aladdin Ghostscript. - - Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author - or distributor accepts any responsibility for the consequences of using it, - or for whether it serves any particular purpose or works at all, unless he - or she says so in writing. Refer to the Aladdin Ghostscript Free Public - License (the "License") for full details. - - Every copy of Aladdin Ghostscript must include a copy of the License, - normally in a plain ASCII text file named PUBLIC. The License grants you - the right to copy, modify and redistribute Aladdin Ghostscript, but only - under certain conditions described in the License. Among other things, the - License requires that the copyright notice and this notice be preserved on - all copies. -*/ +/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. -/* gsimage.c */ + This file is part of Aladdin Ghostscript. + + Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author + or distributor accepts any responsibility for the consequences of using it, + or for whether it serves any particular purpose or works at all, unless he + or she says so in writing. Refer to the Aladdin Ghostscript Free Public + License (the "License") for full details. + + Every copy of Aladdin Ghostscript must include a copy of the License, + normally in a plain ASCII text file named PUBLIC. The License grants you + the right to copy, modify and redistribute Aladdin Ghostscript, but only + under certain conditions described in the License. Among other things, the + License requires that the copyright notice and this notice be preserved on + all copies. + */ + +/*Id: gsimage.c */ /* Image setup procedures for Ghostscript library */ #include "memory_.h" #include "gx.h" @@ -27,285 +27,288 @@ #include "gsimage.h" #include "gxarith.h" /* for igcd */ #include "gxdevice.h" +#include "gxiparam.h" #include "gzstate.h" -/* Define the maximum number of image components. */ -#ifdef DPNEXT -# define max_components 5 -#else -# define max_components 4 -#endif - /* Define the enumeration state for this interface layer. */ -/*typedef struct gs_image_enum_s gs_image_enum;*/ /* in gsimage.h */ + /*typedef struct gs_image_enum_s gs_image_enum; *//* in gsimage.h */ struct gs_image_enum_s { - /* The following are set at initialization time. */ - gs_memory_t *memory; - gx_device *dev; - bool skip; /* if true, just skip over the data */ - void *info; /* driver bookkeeping structure */ - int num_components; - bool multi; - int num_planes; - int width, height; - int bpp; /* bits per pixel (per plane, if multi) */ - uint raster; /* bytes per row (per plane), no padding */ - /* The following are updated dynamically. */ - int plane_index; /* index of next plane of data */ - int y; - uint pos; /* byte position within the scan line */ - gs_const_string sources[max_components]; /* source data */ - gs_string rows[max_components]; /* row buffers */ - bool error; + /* The following are set at initialization time. */ + gs_memory_t *memory; + gx_device *dev; /* if 0, just skip over the data */ + gx_image_enum_common_t *info; /* driver bookkeeping structure */ + int num_planes; + int width, height; + uint raster; /* bytes per row (per plane), no padding */ + /* The following are updated dynamically. */ + int plane_index; /* index of next plane of data */ + int y; + uint pos; /* byte position within the scan line */ + gs_const_string sources[gs_image_max_components]; /* source data */ + gs_string rows[gs_image_max_components]; /* row buffers */ + bool error; }; + gs_private_st_composite(st_gs_image_enum, gs_image_enum, "gs_image_enum", - gs_image_enum_enum_ptrs, gs_image_enum_reloc_ptrs); + gs_image_enum_enum_ptrs, gs_image_enum_reloc_ptrs); #define gs_image_enum_num_ptrs 2 /* GC procedures */ #define eptr ((gs_image_enum *)vptr) -private ENUM_PTRS_BEGIN(gs_image_enum_enum_ptrs) { - /* Enumerate the data planes. */ - index -= gs_image_enum_num_ptrs; - if ( index < eptr->plane_index ) - { *pep = (void *)&eptr->sources[index]; - return ptr_string_type; - } - index -= eptr->plane_index; - if ( index < eptr->num_planes ) - { *pep = (void *)&eptr->rows[index]; - return ptr_string_type; - } - return 0; - } - ENUM_PTR(0, gs_image_enum, dev); - ENUM_PTR(1, gs_image_enum, info); +private +ENUM_PTRS_BEGIN(gs_image_enum_enum_ptrs) +{ + /* Enumerate the data planes. */ + index -= gs_image_enum_num_ptrs; + if (index < eptr->plane_index) + ENUM_RETURN_STRING_PTR(gs_image_enum, sources[index]); + index -= eptr->plane_index; + if (index < eptr->num_planes) + ENUM_RETURN_STRING_PTR(gs_image_enum, rows[index]); + return 0; +} +ENUM_PTR(0, gs_image_enum, dev); +ENUM_PTR(1, gs_image_enum, info); ENUM_PTRS_END -private RELOC_PTRS_BEGIN(gs_image_enum_reloc_ptrs) { - int i; - RELOC_PTR(gs_image_enum, dev); - RELOC_PTR(gs_image_enum, info); - for ( i = 0; i < eptr->plane_index; i++ ) - RELOC_CONST_STRING_PTR(gs_image_enum, sources[i]); - for ( i = 0; i < eptr->num_planes; i++ ) - RELOC_STRING_PTR(gs_image_enum, rows[i]); -} RELOC_PTRS_END +private RELOC_PTRS_BEGIN(gs_image_enum_reloc_ptrs) +{ + int i; + + RELOC_PTR(gs_image_enum, dev); + RELOC_PTR(gs_image_enum, info); + for (i = 0; i < eptr->plane_index; i++) + RELOC_CONST_STRING_PTR(gs_image_enum, sources[i]); + for (i = 0; i < eptr->num_planes; i++) + RELOC_STRING_PTR(gs_image_enum, rows[i]); +} +RELOC_PTRS_END #undef eptr +/* Create an image enumerator given image parameters and a graphics state. */ +int +gs_image_begin_typed(const gs_image_common_t * pic, gs_state * pgs, + bool uses_color, gx_image_enum_common_t ** ppie) +{ + gx_device *dev = gs_currentdevice(pgs); + + if (uses_color) + gx_set_dev_color(pgs); + return gx_device_begin_typed_image(dev, (const gs_imager_state *)pgs, + NULL, pic, NULL, + pgs->dev_color, pgs->clip_path, pgs->memory, ppie); +} + /* Allocate an image enumerator. */ private void -image_enum_init(gs_image_enum *pie) -{ /* Clean pointers for GC. */ - int i; - pie->info = 0; - pie->dev = 0; - for ( i = 0; i < countof(pie->sources); ++i ) - { pie->sources[i].data = 0, pie->sources[i].size = 0; - pie->rows[i].data = 0, pie->rows[i].size = 0; - } +image_enum_init(gs_image_enum * penum) +{ /* Clean pointers for GC. */ + int i; + + penum->info = 0; + penum->dev = 0; + for (i = 0; i < countof(penum->sources); ++i) { + penum->sources[i].data = 0, penum->sources[i].size = 0; + penum->rows[i].data = 0, penum->rows[i].size = 0; + } } gs_image_enum * -gs_image_enum_alloc(gs_memory_t *mem, client_name_t cname) -{ gs_image_enum *pie = - gs_alloc_struct(mem, gs_image_enum, &st_gs_image_enum, cname); +gs_image_enum_alloc(gs_memory_t * mem, client_name_t cname) +{ + gs_image_enum *penum = + gs_alloc_struct(mem, gs_image_enum, &st_gs_image_enum, cname); - if ( pie != 0 ) - { pie->memory = mem; - image_enum_init(pie); - } - return pie; + if (penum != 0) { + penum->memory = mem; + image_enum_init(penum); + } + return penum; } -/* Start processing an image. */ +/* Start processing an ImageType 1 image. */ int -gs_image_init(gs_image_enum *pie, const gs_image_t *pim, bool multi, - gs_state *pgs) -{ gx_device *dev = gs_currentdevice_inline(pgs); - gs_image_t image; - ulong samples_per_row = pim->Width; - int code; +gs_image_init(gs_image_enum * penum, const gs_image_t * pim, bool multi, + gs_state * pgs) +{ + gs_image_t image; + gx_image_enum_common_t *pie; + int code; - if ( pim->Width == 0 || pim->Height == 0 ) - return 1; - image = *pim; - image_enum_init(pie); - pie->skip = pgs->in_charpath; - if ( image.ImageMask ) - { image.ColorSpace = NULL; - if ( pgs->in_cachedevice <= 1 ) - image.adjust = false; - pie->num_components = pie->num_planes = 1; - } - else - { if ( pgs->in_cachedevice ) - return_error(gs_error_undefined); - if ( image.ColorSpace == NULL ) - image.ColorSpace = gs_color_space_DeviceGray(); - pie->num_components = - gs_color_space_num_components(image.ColorSpace); -#ifdef DPNEXT - if ( pim->HasAlpha ) - pie->num_components++; -#endif - if ( multi ) - pie->num_planes = pie->num_components; - else - { pie->num_planes = 1; - samples_per_row *= pie->num_components; - } - } - if ( image.ImageMask | image.CombineWithColor ) - gx_set_dev_color(pgs); - if ( !pie->skip ) - { code = (*dev_proc(dev, begin_image)) - (dev, (const gs_imager_state *)pgs, &image, - (multi ? gs_image_format_component_planar : gs_image_format_chunky), - NULL, pgs->dev_color, pgs->clip_path, pie->memory, &pie->info); - if ( code < 0 ) - return code; - } - pie->dev = dev; - pie->multi = multi; - pie->bpp = - image.BitsPerComponent * pie->num_components / pie->num_planes; - pie->width = image.Width; - pie->height = image.Height; - pie->raster = (samples_per_row * image.BitsPerComponent + 7) >> 3; - /* Initialize the dynamic part of the state. */ - pie->plane_index = 0; - pie->y = 0; - pie->pos = 0; - pie->error = false; - return 0; + image = *pim; + if (image.ImageMask) { + image.ColorSpace = NULL; + if (pgs->in_cachedevice <= 1) + image.adjust = false; + } else { + if (pgs->in_cachedevice) + return_error(gs_error_undefined); + if (image.ColorSpace == NULL) + image.ColorSpace = + gs_cspace_DeviceGray((const gs_imager_state *)pgs); + } + code = gs_image_begin_typed((const gs_image_common_t *)&image, pgs, + image.ImageMask | image.CombineWithColor, + &pie); + if (code < 0) + return code; + return gs_image_common_init(penum, pie, + (const gs_data_image_t *)&image, + pgs->memory, + (pgs->in_charpath ? NULL : + gs_currentdevice_inline(pgs))); +} +/* Start processing a general image. */ +int +gs_image_common_init(gs_image_enum * penum, gx_image_enum_common_t * pie, + const gs_data_image_t * pim, gs_memory_t * mem, gx_device * dev) +{ + if (pim->Width == 0 || pim->Height == 0) + return 1; + image_enum_init(penum); + penum->memory = mem; + penum->dev = dev; + penum->info = pie; + penum->num_planes = pie->num_planes; + penum->width = pim->Width; + penum->height = pim->Height; +/****** ALL PLANES MUST HAVE SAME DEPTH FOR NOW ******/ + penum->raster = (pim->Width * pie->plane_depths[0] + 7) >> 3; + /* Initialize the dynamic part of the state. */ + penum->plane_index = 0; + penum->y = 0; + penum->pos = 0; + penum->error = false; + return 0; } /* - * Return the number of bytes of data per row - * (per plane, if MultipleDataSources is true). + * Return the number of bytes of data per row per plane. */ uint -gs_image_bytes_per_row(const gs_image_enum *pie) -{ return pie->raster; +gs_image_bytes_per_plane_row(const gs_image_enum * penum, int plane) +{ +/****** IGNORE PLANE FOR NOW ******/ + return penum->raster; } /* Process the next piece of an image. */ private int -copy_planes(gx_device *dev, gs_image_enum *pie, const byte **planes, int h) -{ int code = - (pie->skip ? (pie->y + h < pie->height ? 0 : 1) : - (*dev_proc(dev, image_data))(dev, pie->info, planes, 0, - pie->raster, h)); +copy_planes(gx_device * dev, gs_image_enum * penum, const byte ** planes, int h) +{ + int code = + (penum->dev == 0 ? (penum->y + h < penum->height ? 0 : 1) : + gx_device_image_data(dev, penum->info, planes, 0, penum->raster, h)); - if ( code < 0 ) - pie->error = true; - return code; + if (code < 0) + penum->error = true; + return code; } int -gs_image_next(gs_image_enum *pie, const byte *dbytes, uint dsize, - uint *pused) -{ gx_device *dev; - uint left; - int num_planes; - uint raster; - uint pos; - int code; +gs_image_next(gs_image_enum * penum, const byte * dbytes, uint dsize, + uint * pused) +{ + gx_device *dev; + uint left; + int num_planes; + uint raster; + uint pos; + int code; - /* - * Handle the following differences between gs_image_next and - * the device image_data procedure: - * - * - image_data requires an array of planes; gs_image_next - * expects planes in successive calls. - * - * - image_data requires that each call pass entire rows; - * gs_image_next allows arbitrary amounts of data. - */ - if ( pie->plane_index != 0 ) - if ( dsize != pie->sources[0].size ) + /* + * Handle the following differences between gs_image_next and + * the device image_data procedure: + * + * - image_data requires an array of planes; gs_image_next + * expects planes in successive calls. + * + * - image_data requires that each call pass entire rows; + * gs_image_next allows arbitrary amounts of data. + */ + if (penum->plane_index != 0) + if (dsize != penum->sources[0].size) return_error(gs_error_rangecheck); - pie->sources[pie->plane_index].data = dbytes; - pie->sources[pie->plane_index].size = dsize; - if ( ++(pie->plane_index) != pie->num_planes ) - return 0; - /* We have a full set of planes. */ - dev = pie->dev; - left = dsize; - num_planes = pie->num_planes; - raster = pie->raster; - pos = pie->pos; - code = 0; - while ( left && pie->y < pie->height ) - { const byte *planes[max_components]; - int i; + penum->sources[penum->plane_index].data = dbytes; + penum->sources[penum->plane_index].size = dsize; + if (++(penum->plane_index) != penum->num_planes) + return 0; + /* We have a full set of planes. */ + dev = penum->dev; + left = dsize; + num_planes = penum->num_planes; + raster = penum->raster; + pos = penum->pos; + code = 0; + while (left && penum->y < penum->height) { + const byte *planes[gs_image_max_components]; + int i; - for ( i = 0; i < num_planes; ++i ) - planes[i] = pie->sources[i].data + dsize - left; - if ( pos == 0 && left >= raster ) - { /* Pass (a) row(s) directly from the source. */ - int h = left / raster; - if ( h > pie->height - pie->y ) - h = pie->height - pie->y; - code = copy_planes(dev, pie, planes, h); - if ( code < 0 ) - break; - left -= raster * h; - pie->y += h; - } - else - { /* Buffer a partial row. */ - uint count = min(left, raster - pos); - if ( pie->rows[0].data == 0 ) - { /* Allocate the row buffers. */ - for ( i = 0; i < num_planes; ++i ) - { byte *row = gs_alloc_string(pie->memory, raster, - "gs_image_next(row)"); - if ( row == 0 ) - { code = gs_note_error(gs_error_VMerror); - while ( --i >= 0 ) - { gs_free_string(pie->memory, pie->rows[i].data, - raster, "gs_image_next(row)"); - pie->rows[i].data = 0; - pie->rows[i].size = 0; - } - break; - } - pie->rows[i].data = row; - pie->rows[i].size = raster; - } - if ( code < 0 ) - break; - } - for ( i = 0; i < num_planes; ++i ) - memcpy(pie->rows[i].data + pos, planes[i], count); - pos += count; - left -= count; - if ( pos == raster ) - { for ( i = 0; i < num_planes; ++i ) - planes[i] = pie->rows[i].data; - code = copy_planes(dev, pie, planes, 1); - if ( code < 0 ) - break; - pos = 0; - pie->y++; - } - } - } - pie->pos = pos; - pie->plane_index = 0; - *pused = dsize - left; - return code; + for (i = 0; i < num_planes; ++i) + planes[i] = penum->sources[i].data + dsize - left; + if (pos == 0 && left >= raster) { /* Pass (a) row(s) directly from the source. */ + int h = left / raster; + + if (h > penum->height - penum->y) + h = penum->height - penum->y; + code = copy_planes(dev, penum, planes, h); + if (code < 0) + break; + left -= raster * h; + penum->y += h; + } else { /* Buffer a partial row. */ + uint count = min(left, raster - pos); + + if (penum->rows[0].data == 0) { /* Allocate the row buffers. */ + for (i = 0; i < num_planes; ++i) { + byte *row = gs_alloc_string(penum->memory, raster, + "gs_image_next(row)"); + + if (row == 0) { + code = gs_note_error(gs_error_VMerror); + while (--i >= 0) { + gs_free_string(penum->memory, penum->rows[i].data, + raster, "gs_image_next(row)"); + penum->rows[i].data = 0; + penum->rows[i].size = 0; + } + break; + } + penum->rows[i].data = row; + penum->rows[i].size = raster; + } + if (code < 0) + break; + } + for (i = 0; i < num_planes; ++i) + memcpy(penum->rows[i].data + pos, planes[i], count); + pos += count; + left -= count; + if (pos == raster) { + for (i = 0; i < num_planes; ++i) + planes[i] = penum->rows[i].data; + code = copy_planes(dev, penum, planes, 1); + if (code < 0) + break; + pos = 0; + penum->y++; + } + } + } + penum->pos = pos; + penum->plane_index = 0; + *pused = dsize - left; + return code; } /* Clean up after processing an image. */ void -gs_image_cleanup(gs_image_enum *pie) -{ gx_device *dev = pie->dev; - int i; +gs_image_cleanup(gs_image_enum * penum) +{ + gx_device *dev = penum->dev; + int i; - for ( i = 0; i < pie->num_planes; ++i ) - gs_free_string(pie->memory, pie->rows[i].data, - pie->rows[i].size, "gs_image_cleanup(row)"); - if ( !pie->skip ) - (*dev_proc(dev, end_image))(dev, pie->info, !pie->error); - /* Don't free the local enumerator -- the client does that. */ + for (i = 0; i < penum->num_planes; ++i) + gs_free_string(penum->memory, penum->rows[i].data, + penum->rows[i].size, "gs_image_cleanup(row)"); + if (penum->dev != 0) + gx_device_end_image(dev, penum->info, !penum->error); + /* Don't free the local enumerator -- the client does that. */ } |