brender-v1.1.2/FW/PIXELMAP.C

187 lines
4.2 KiB
C++
Raw Permalink Normal View History

2022-05-04 20:14:23 -05:00
/*
* Copyright (c) 1992,1993-1995 Argonaut Technologies Limited. All rights reserved.
*
* $Id: pixelmap.c 1.17 1995/08/31 16:29:37 sam Exp $
* $Locker: $
*
* Manipulating pixelmaps
*/
#include "fw.h"
#include "brassert.h"
static char rscid[] = "$Id: pixelmap.c 1.17 1995/08/31 16:29:37 sam Exp $";
/*
* Useful info about each pixelmap type
*/
static struct pm_type_info {
/*
* Size, in bits, of each pixel (including padding)
*/
br_uint_16 bits;
/*
* Size, in bytes, that should be used for saving/loading
*/
br_uint_16 file_size;
/*
* Alignment of rows, in pixels
*/
br_uint_16 align;
/*
* Mask of channels in pixelmap
*/
br_uint_16 channels;
} pm_type_info[] = {
{ 1, 1, 32, BR_PMCHAN_INDEX, }, /* BR_PMT_INDEX_1 */
{ 2, 1, 16, BR_PMCHAN_INDEX, }, /* BR_PMT_INDEX_2 */
{ 4, 1, 8, BR_PMCHAN_INDEX, }, /* BR_PMT_INDEX_4 */
{ 8, 1, 4, BR_PMCHAN_INDEX, }, /* BR_PMT_INDEX_8 */
{ 16, 2, 2, BR_PMCHAN_RGB, }, /* BR_PMT_RGB_555 */
{ 16, 2, 2, BR_PMCHAN_RGB, }, /* BR_PMT_RGB_565 */
{ 24, 3, 4, BR_PMCHAN_RGB, }, /* BR_PMT_RGB_888 */
{ 32, 4, 1, BR_PMCHAN_RGB, }, /* BR_PMT_RGBX_888 */
{ 32, 4, 1, BR_PMCHAN_RGB | BR_PMCHAN_ALPHA, }, /* BR_PMT_RGBA_8888 */
{ 16, 1, 2, BR_PMCHAN_YUV, }, /* BR_PMT_YUYV_8888 */
{ 32, 1, 1, BR_PMCHAN_YUV, }, /* BR_PMT_YUV_888 */
{ 16, 2, 4, BR_PMCHAN_DEPTH, }, /* BR_PMT_DEPTH_16 */
{ 32, 4, 4, BR_PMCHAN_DEPTH, }, /* BR_PMT_DEPTH_32 */
{ 8, 1, 4, BR_PMCHAN_ALPHA, }, /* BR_PMT_ALPHA_8 */
{ 16, 2, 2, BR_PMCHAN_INDEX | BR_PMCHAN_ALPHA }, /* BR_PMT_INDEXA_88 */
};
/*
* Allocate a new, pixelmap of the given type and size
*
* If the 'pixels' pointer is NULL, an appropriate area of memeory will be allocated
*
*/
br_pixelmap * BR_PUBLIC_ENTRY BrPixelmapAllocate(br_uint_8 type,br_uint_16 w,br_uint_16 h, void *pixels, int flags)
{
br_pixelmap *pm;
struct pm_type_info *tip = pm_type_info+type;
pm = BrResAllocate(fw.res,sizeof(*pm),BR_MEMORY_PIXELMAP);
UASSERT(type < BR_ASIZE(pm_type_info));
/*
* Fill in base structure
*/
pm->identifier = NULL;
pm->type = type;
pm->map = NULL;
pm->flags = BR_PMF_LINEAR;
pm->base_x = 0;
pm->base_y = 0;
pm->width = w;
pm->height = h;
pm->origin_x = 0;
pm->origin_y = 0;
/*
* Work out size of a row
*/
pm->row_bytes = tip->bits * tip->align * ((w+tip->align-1) / tip->align) / 8;
if(((pm->row_bytes * 8) % tip->bits) == 0)
pm->flags |= BR_PMF_ROW_WHOLEPIXELS;
/*
* Allocate pixels
*/
if(pixels)
pm->pixels = pixels;
else
pm->pixels = BrResAllocate(pm,pm->row_bytes * pm->height,BR_MEMORY_PIXELS);
/*
* Make it a bottom up bitmap if required
*/
if(flags & BR_PMAF_INVERTED) {
pm->pixels = (char *)pm->pixels + pm->row_bytes * (pm->height-1);
pm->row_bytes = -pm->row_bytes;
}
return pm;
}
/*
* Create a new pixelmap that references a sub-rectangle of another pixelmap
*/
br_pixelmap * BR_PUBLIC_ENTRY BrPixelmapAllocateSub(br_pixelmap *pm,
br_uint_16 x, br_uint_16 y,
br_uint_16 w, br_uint_16 h)
{
br_pixelmap *npm;
/*
* Create the new structure and copy
*/
npm = BrResAllocate(fw.res,sizeof(*pm),BR_MEMORY_PIXELMAP);
*npm = *pm;
/*
* Pixel rows are not contiguous
*/
npm->flags &= ~BR_PMF_LINEAR;
/*
* Create sub-window (clipped against original)
*/
x = (x <= pm->width)?x:pm->width;
y = (y <= pm->height)?y:pm->height;
npm->base_x += x;
npm->base_y += y;
npm->origin_x = 0;
npm->origin_y = 0;
npm->width = ((x+w) <= pm->width)? w : (pm->width - x);
npm->height = ((y+h) <= pm->height)? h : (pm->height - y);
return npm;
}
/*
* Return the load/save size for a given pixelmap
*/
br_uint_16 BR_PUBLIC_ENTRY BrPixelmapFileSize(br_pixelmap *pm)
{
ASSERT(pm && (pm->type < BR_ASIZE(pm_type_info)));
return pm_type_info[pm->type].file_size;
}
/*
* Return the pixel size in bits
*/
br_uint_16 BR_PUBLIC_ENTRY BrPixelmapPixelSize(br_pixelmap *pm)
{
ASSERT(pm && (pm->type < BR_ASIZE(pm_type_info)));
return pm_type_info[pm->type].bits;
}
/*
* Return a mask of the channels that a pixelmap has
*/
br_uint_16 BR_PUBLIC_ENTRY BrPixelmapChannels(br_pixelmap *pm)
{
ASSERT(pm && (pm->type < BR_ASIZE(pm_type_info)));
return pm_type_info[pm->type].channels;
}