cairo/pixman/src/icformat.c

156 lines
4.3 KiB
C

/*
* Copyright © 2000 SuSE, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of SuSE not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. SuSE makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Keith Packard, SuSE, Inc.
*/
#include "icint.h"
#define Mask(n) ((n) == 32 ? 0xffffffff : ((1 << (n))-1))
IcFormat *
IcFormatCreate (IcFormatName name)
{
switch (name) {
case IcFormatNameARGB32:
return IcFormatCreateMasks (32,
0xff000000,
0x00ff0000,
0x0000ff00,
0x000000ff);
case IcFormatNameRGB24:
return IcFormatCreateMasks (32,
0x0,
0xff0000,
0x00ff00,
0x0000ff);
case IcFormatNameA8:
return IcFormatCreateMasks (8, 0xff,
0, 0, 0);
case IcFormatNameA1:
return IcFormatCreateMasks (1, 0x1,
0, 0, 0);
}
return NULL;
}
/* XXX: There's some nonsense going on here. The macros above help
IcFormatCreateMasks to encode a format into an int, while
immediately afterwards IcFormatInit goes through the effort of
decoding it. This should all be disentagled, (it's probably
possible to just eliminate the encoding macros altogether). */
IcFormat *
IcFormatCreateMasks (int bpp,
int alpha_mask,
int red_mask,
int green_mask,
int blue_mask)
{
int type;
int format_code;
IcFormat *format;
if (red_mask == 0 && green_mask == 0 && blue_mask == 0)
type = PICT_TYPE_A;
else if (red_mask > blue_mask)
type = PICT_TYPE_ARGB;
else
type = PICT_TYPE_ABGR;
format_code = PICT_FORMAT (bpp, type,
_IcOnes (alpha_mask),
_IcOnes (red_mask),
_IcOnes (green_mask),
_IcOnes (blue_mask));
format = malloc (sizeof (IcFormat));
if (format == NULL)
return NULL;
IcFormatInit (format, format_code);
return format;
}
void
IcFormatInit (IcFormat *format, int format_code)
{
/* XXX: What do we want to lodge in here?
format->id = FakeClientID (0);
*/
format->format_code = format_code;
format->depth = PICT_FORMAT_BPP(format_code);
switch (PICT_FORMAT_TYPE(format_code)) {
case PICT_TYPE_ARGB:
format->alphaMask = Mask(PICT_FORMAT_A(format_code));
if (format->alphaMask)
format->alpha = (PICT_FORMAT_R(format_code) +
PICT_FORMAT_G(format_code) +
PICT_FORMAT_B(format_code));
format->redMask = Mask(PICT_FORMAT_R(format_code));
format->red = (PICT_FORMAT_G(format_code) +
PICT_FORMAT_B(format_code));
format->greenMask = Mask(PICT_FORMAT_G(format_code));
format->green = PICT_FORMAT_B(format_code);
format->blueMask = Mask(PICT_FORMAT_B(format_code));
format->blue = 0;
break;
case PICT_TYPE_ABGR:
format->alphaMask = Mask(PICT_FORMAT_A(format_code));
if (format->alphaMask)
format->alpha = (PICT_FORMAT_B(format_code) +
PICT_FORMAT_G(format_code) +
PICT_FORMAT_R(format_code));
format->blueMask = Mask(PICT_FORMAT_B(format_code));
format->blue = (PICT_FORMAT_G(format_code) +
PICT_FORMAT_R(format_code));
format->greenMask = Mask(PICT_FORMAT_G(format_code));
format->green = PICT_FORMAT_R(format_code);
format->redMask = Mask(PICT_FORMAT_R(format_code));
format->red = 0;
break;
case PICT_TYPE_A:
format->alpha = 0;
format->alphaMask = Mask(PICT_FORMAT_A(format_code));
/* remaining fields already set to zero */
break;
}
}
slim_hidden_def(IcFormatInit);
void
IcFormatDestroy (IcFormat *format)
{
free (format);
}