4285 lines
117 KiB
C
4285 lines
117 KiB
C
/*
|
|
*
|
|
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
|
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
|
*
|
|
* 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 Keith Packard not be used in
|
|
* advertising or publicity pertaining to distribution of the software without
|
|
* specific, written prior permission. Keith Packard makes no
|
|
* representations about the suitability of this software for any purpose. It
|
|
* is provided "as is" without express or implied warranty.
|
|
*
|
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
|
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
|
|
*/
|
|
|
|
#ifdef HAVE_DIX_CONFIG_H
|
|
#include <dix-config.h>
|
|
#endif
|
|
|
|
#include "fb.h"
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include <assert.h>
|
|
|
|
#include "picturestr.h"
|
|
#include "mipict.h"
|
|
#include "fbpict.h"
|
|
|
|
#define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
|
|
|
|
#define SCANLINE_BUFFER_LENGTH 2048
|
|
|
|
typedef FASTCALL void (*fetchProc) (const FbBits * bits, int x, int width,
|
|
CARD32 *buffer, miIndexedPtr indexed);
|
|
|
|
/*
|
|
* All of the fetch functions
|
|
*/
|
|
|
|
static FASTCALL void
|
|
fbFetch_a8r8g8b8(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
memcpy(buffer, (const CARD32 *) bits + x, width * sizeof(CARD32));
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_x8r8g8b8(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD32 *pixel = (const CARD32 *) bits + x;
|
|
|
|
const CARD32 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
*buffer++ = *pixel++ | 0xff000000;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_a8b8g8r8(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD32 *pixel = (CARD32 *) bits + x;
|
|
|
|
const CARD32 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
*buffer++ = ((*pixel & 0xff00ff00) |
|
|
((*pixel >> 16) & 0xff) | ((*pixel & 0xff) << 16));
|
|
++pixel;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_x8b8g8r8(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD32 *pixel = (CARD32 *) bits + x;
|
|
|
|
const CARD32 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
*buffer++ = 0xff000000 |
|
|
((*pixel & 0x0000ff00) |
|
|
((*pixel >> 16) & 0xff) | ((*pixel & 0xff) << 16));
|
|
++pixel;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_r8g8b8(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD8 *pixel = (const CARD8 *) bits + 3 * x;
|
|
|
|
const CARD8 *end = pixel + 3 * width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 b = Fetch24(pixel) | 0xff000000;
|
|
|
|
pixel += 3;
|
|
*buffer++ = b;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_b8g8r8(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD8 *pixel = (const CARD8 *) bits + 3 * x;
|
|
|
|
const CARD8 *end = pixel + 3 * width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 b = 0xff000000;
|
|
|
|
#if IMAGE_BYTE_ORDER == MSBFirst
|
|
b |= (*pixel++);
|
|
b |= (*pixel++ << 8);
|
|
b |= (*pixel++ << 16);
|
|
#else
|
|
b |= (*pixel++ << 16);
|
|
b |= (*pixel++ << 8);
|
|
b |= (*pixel++);
|
|
#endif
|
|
*buffer++ = b;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_r5g6b5(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD16 *pixel = (const CARD16 *) bits + x;
|
|
|
|
const CARD16 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
CARD32 r = (((p) << 3) & 0xf8) |
|
|
(((p) << 5) & 0xfc00) | (((p) << 8) & 0xf80000);
|
|
r |= (r >> 5) & 0x70007;
|
|
r |= (r >> 6) & 0x300;
|
|
*buffer++ = 0xff000000 | r;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_b5g6r5(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD16 *pixel = (const CARD16 *) bits + x;
|
|
|
|
const CARD16 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
CARD32 r, g, b;
|
|
|
|
b = ((p & 0xf800) | ((p & 0xe000) >> 5)) >> 8;
|
|
g = ((p & 0x07e0) | ((p & 0x0600) >> 6)) << 5;
|
|
r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
|
|
*buffer++ = (0xff000000 | r | g | b);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_a1r5g5b5(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD16 *pixel = (const CARD16 *) bits + x;
|
|
|
|
const CARD16 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
CARD32 r, g, b, a;
|
|
|
|
a = (CARD32) ((CARD8) (0 - ((p & 0x8000) >> 15))) << 24;
|
|
r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
|
|
g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
|
|
b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
|
|
*buffer++ = (a | r | g | b);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_x1r5g5b5(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD16 *pixel = (const CARD16 *) bits + x;
|
|
|
|
const CARD16 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
CARD32 r, g, b;
|
|
|
|
r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
|
|
g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
|
|
b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
|
|
*buffer++ = (0xff000000 | r | g | b);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_a1b5g5r5(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD16 *pixel = (const CARD16 *) bits + x;
|
|
|
|
const CARD16 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
CARD32 r, g, b, a;
|
|
|
|
a = (CARD32) ((CARD8) (0 - ((p & 0x8000) >> 15))) << 24;
|
|
b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
|
|
g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
|
|
r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
|
|
*buffer++ = (a | r | g | b);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_x1b5g5r5(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD16 *pixel = (const CARD16 *) bits + x;
|
|
|
|
const CARD16 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
CARD32 r, g, b;
|
|
|
|
b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
|
|
g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
|
|
r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
|
|
*buffer++ = (0xff000000 | r | g | b);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_a4r4g4b4(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD16 *pixel = (const CARD16 *) bits + x;
|
|
|
|
const CARD16 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
CARD32 r, g, b, a;
|
|
|
|
a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
|
|
r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
|
|
g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
|
|
b = ((p & 0x000f) | ((p & 0x000f) << 4));
|
|
*buffer++ = (a | r | g | b);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_x4r4g4b4(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD16 *pixel = (const CARD16 *) bits + x;
|
|
|
|
const CARD16 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
CARD32 r, g, b;
|
|
|
|
r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
|
|
g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
|
|
b = ((p & 0x000f) | ((p & 0x000f) << 4));
|
|
*buffer++ = (0xff000000 | r | g | b);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_a4b4g4r4(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD16 *pixel = (const CARD16 *) bits + x;
|
|
|
|
const CARD16 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
CARD32 r, g, b, a;
|
|
|
|
a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
|
|
b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
|
|
g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
|
|
r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
|
|
*buffer++ = (a | r | g | b);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_x4b4g4r4(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD16 *pixel = (const CARD16 *) bits + x;
|
|
|
|
const CARD16 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
CARD32 r, g, b;
|
|
|
|
b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
|
|
g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
|
|
r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
|
|
*buffer++ = (0xff000000 | r | g | b);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_a8(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD8 *pixel = (const CARD8 *) bits + x;
|
|
|
|
const CARD8 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
*buffer++ = (*pixel++) << 24;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_r3g3b2(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD8 *pixel = (const CARD8 *) bits + x;
|
|
|
|
const CARD8 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
CARD32 r, g, b;
|
|
|
|
r = ((p & 0xe0) | ((p & 0xe0) >> 3) | ((p & 0xc0) >> 6)) << 16;
|
|
g = ((p & 0x1c) | ((p & 0x18) >> 3) | ((p & 0x1c) << 3)) << 8;
|
|
b = (((p & 0x03)) |
|
|
((p & 0x03) << 2) | ((p & 0x03) << 4) | ((p & 0x03) << 6));
|
|
*buffer++ = (0xff000000 | r | g | b);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_b2g3r3(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD8 *pixel = (const CARD8 *) bits + x;
|
|
|
|
const CARD8 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
CARD32 r, g, b;
|
|
|
|
b = (((p & 0xc0)) |
|
|
((p & 0xc0) >> 2) | ((p & 0xc0) >> 4) | ((p & 0xc0) >> 6));
|
|
g = ((p & 0x38) | ((p & 0x38) >> 3) | ((p & 0x30) << 2)) << 8;
|
|
r = (((p & 0x07)) | ((p & 0x07) << 3) | ((p & 0x06) << 6)) << 16;
|
|
*buffer++ = (0xff000000 | r | g | b);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_a2r2g2b2(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD8 *pixel = (const CARD8 *) bits + x;
|
|
|
|
const CARD8 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
CARD32 a, r, g, b;
|
|
|
|
a = ((p & 0xc0) * 0x55) << 18;
|
|
r = ((p & 0x30) * 0x55) << 12;
|
|
g = ((p & 0x0c) * 0x55) << 6;
|
|
b = ((p & 0x03) * 0x55);
|
|
*buffer++ = a | r | g | b;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_a2b2g2r2(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD8 *pixel = (const CARD8 *) bits + x;
|
|
|
|
const CARD8 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
CARD32 a, r, g, b;
|
|
|
|
a = ((p & 0xc0) * 0x55) << 18;
|
|
b = ((p & 0x30) * 0x55) >> 6;
|
|
g = ((p & 0x0c) * 0x55) << 6;
|
|
r = ((p & 0x03) * 0x55) << 16;
|
|
*buffer++ = a | r | g | b;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_c8(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD8 *pixel = (const CARD8 *) bits + x;
|
|
|
|
const CARD8 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD32 p = *pixel++;
|
|
|
|
*buffer++ = indexed->rgba[p];
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_x4a4(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
const CARD8 *pixel = (const CARD8 *) bits + x;
|
|
|
|
const CARD8 *end = pixel + width;
|
|
|
|
while (pixel < end) {
|
|
CARD8 p = (*pixel++) & 0xf;
|
|
|
|
*buffer++ = (p | (p << 4)) << 24;
|
|
}
|
|
}
|
|
|
|
#define Fetch8(l,o) (((CARD8 *) (l))[(o) >> 2])
|
|
#if IMAGE_BYTE_ORDER == MSBFirst
|
|
#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) & 0xf : Fetch8(l,o) >> 4)
|
|
#else
|
|
#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) >> 4 : Fetch8(l,o) & 0xf)
|
|
#endif
|
|
|
|
static FASTCALL void
|
|
fbFetch_a4(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 p = Fetch4(bits, i + x);
|
|
|
|
p |= p << 4;
|
|
*buffer++ = p << 24;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_r1g2b1(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 p = Fetch4(bits, i + x);
|
|
|
|
CARD32 r, g, b;
|
|
|
|
r = ((p & 0x8) * 0xff) << 13;
|
|
g = ((p & 0x6) * 0x55) << 7;
|
|
b = ((p & 0x1) * 0xff);
|
|
*buffer++ = 0xff000000 | r | g | b;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_b1g2r1(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 p = Fetch4(bits, i + x);
|
|
|
|
CARD32 r, g, b;
|
|
|
|
b = ((p & 0x8) * 0xff) >> 3;
|
|
g = ((p & 0x6) * 0x55) << 7;
|
|
r = ((p & 0x1) * 0xff) << 16;
|
|
*buffer++ = 0xff000000 | r | g | b;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_a1r1g1b1(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 p = Fetch4(bits, i + x);
|
|
|
|
CARD32 a, r, g, b;
|
|
|
|
a = ((p & 0x8) * 0xff) << 21;
|
|
r = ((p & 0x4) * 0xff) << 14;
|
|
g = ((p & 0x2) * 0xff) << 7;
|
|
b = ((p & 0x1) * 0xff);
|
|
*buffer++ = a | r | g | b;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_a1b1g1r1(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 p = Fetch4(bits, i + x);
|
|
|
|
CARD32 a, r, g, b;
|
|
|
|
a = ((p & 0x8) * 0xff) << 21;
|
|
r = ((p & 0x4) * 0xff) >> 3;
|
|
g = ((p & 0x2) * 0xff) << 7;
|
|
b = ((p & 0x1) * 0xff) << 16;
|
|
*buffer++ = a | r | g | b;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_c4(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 p = Fetch4(bits, i + x);
|
|
|
|
*buffer++ = indexed->rgba[p];
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_a1(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 p = ((CARD32 *) bits)[(i + x) >> 5];
|
|
|
|
CARD32 a;
|
|
|
|
#if BITMAP_BIT_ORDER == MSBFirst
|
|
a = p >> (0x1f - ((i + x) & 0x1f));
|
|
#else
|
|
a = p >> ((i + x) & 0x1f);
|
|
#endif
|
|
a = a & 1;
|
|
a |= a << 1;
|
|
a |= a << 2;
|
|
a |= a << 4;
|
|
*buffer++ = a << 24;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbFetch_g1(const FbBits * bits, int x, int width, CARD32 *buffer,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 p = ((CARD32 *) bits)[(i + x) >> 5];
|
|
|
|
CARD32 a;
|
|
|
|
#if BITMAP_BIT_ORDER == MSBFirst
|
|
a = p >> (0x1f - ((i + x) & 0x1f));
|
|
#else
|
|
a = p >> ((i + x) & 0x1f);
|
|
#endif
|
|
a = a & 1;
|
|
*buffer++ = indexed->rgba[a];
|
|
}
|
|
}
|
|
|
|
static fetchProc
|
|
fetchProcForPicture(PicturePtr pict)
|
|
{
|
|
switch (pict->format) {
|
|
case PICT_a8r8g8b8:
|
|
return fbFetch_a8r8g8b8;
|
|
case PICT_x8r8g8b8:
|
|
return fbFetch_x8r8g8b8;
|
|
case PICT_a8b8g8r8:
|
|
return fbFetch_a8b8g8r8;
|
|
case PICT_x8b8g8r8:
|
|
return fbFetch_x8b8g8r8;
|
|
|
|
/* 24bpp formats */
|
|
case PICT_r8g8b8:
|
|
return fbFetch_r8g8b8;
|
|
case PICT_b8g8r8:
|
|
return fbFetch_b8g8r8;
|
|
|
|
/* 16bpp formats */
|
|
case PICT_r5g6b5:
|
|
return fbFetch_r5g6b5;
|
|
case PICT_b5g6r5:
|
|
return fbFetch_b5g6r5;
|
|
|
|
case PICT_a1r5g5b5:
|
|
return fbFetch_a1r5g5b5;
|
|
case PICT_x1r5g5b5:
|
|
return fbFetch_x1r5g5b5;
|
|
case PICT_a1b5g5r5:
|
|
return fbFetch_a1b5g5r5;
|
|
case PICT_x1b5g5r5:
|
|
return fbFetch_x1b5g5r5;
|
|
case PICT_a4r4g4b4:
|
|
return fbFetch_a4r4g4b4;
|
|
case PICT_x4r4g4b4:
|
|
return fbFetch_x4r4g4b4;
|
|
case PICT_a4b4g4r4:
|
|
return fbFetch_a4b4g4r4;
|
|
case PICT_x4b4g4r4:
|
|
return fbFetch_x4b4g4r4;
|
|
|
|
/* 8bpp formats */
|
|
case PICT_a8:
|
|
return fbFetch_a8;
|
|
case PICT_r3g3b2:
|
|
return fbFetch_r3g3b2;
|
|
case PICT_b2g3r3:
|
|
return fbFetch_b2g3r3;
|
|
case PICT_a2r2g2b2:
|
|
return fbFetch_a2r2g2b2;
|
|
case PICT_a2b2g2r2:
|
|
return fbFetch_a2b2g2r2;
|
|
case PICT_c8:
|
|
return fbFetch_c8;
|
|
case PICT_g8:
|
|
return fbFetch_c8;
|
|
case PICT_x4a4:
|
|
return fbFetch_x4a4;
|
|
|
|
/* 4bpp formats */
|
|
case PICT_a4:
|
|
return fbFetch_a4;
|
|
case PICT_r1g2b1:
|
|
return fbFetch_r1g2b1;
|
|
case PICT_b1g2r1:
|
|
return fbFetch_b1g2r1;
|
|
case PICT_a1r1g1b1:
|
|
return fbFetch_a1r1g1b1;
|
|
case PICT_a1b1g1r1:
|
|
return fbFetch_a1b1g1r1;
|
|
case PICT_c4:
|
|
return fbFetch_c4;
|
|
case PICT_g4:
|
|
return fbFetch_c4;
|
|
|
|
/* 1bpp formats */
|
|
case PICT_a1:
|
|
return fbFetch_a1;
|
|
case PICT_g1:
|
|
return fbFetch_g1;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* Pixel wise fetching
|
|
*/
|
|
|
|
typedef FASTCALL CARD32 (*fetchPixelProc) (const FbBits * bits, int offset,
|
|
miIndexedPtr indexed);
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_a8r8g8b8(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
return ((CARD32 *) bits)[offset];
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_x8r8g8b8(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
return ((CARD32 *) bits)[offset] | 0xff000000;
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_a8b8g8r8(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD32 *) bits)[offset];
|
|
|
|
return ((pixel & 0xff000000) |
|
|
((pixel >> 16) & 0xff) |
|
|
(pixel & 0x0000ff00) | ((pixel & 0xff) << 16));
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_x8b8g8r8(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD32 *) bits)[offset];
|
|
|
|
return ((0xff000000) |
|
|
((pixel >> 16) & 0xff) |
|
|
(pixel & 0x0000ff00) | ((pixel & 0xff) << 16));
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_r8g8b8(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD8 *pixel = ((CARD8 *) bits) + (offset * 3);
|
|
|
|
#if IMAGE_BYTE_ORDER == MSBFirst
|
|
return (0xff000000 | (pixel[0] << 16) | (pixel[1] << 8) | (pixel[2]));
|
|
#else
|
|
return (0xff000000 | (pixel[2] << 16) | (pixel[1] << 8) | (pixel[0]));
|
|
#endif
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_b8g8r8(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD8 *pixel = ((CARD8 *) bits) + (offset * 3);
|
|
|
|
#if IMAGE_BYTE_ORDER == MSBFirst
|
|
return (0xff000000 | (pixel[2] << 16) | (pixel[1] << 8) | (pixel[0]));
|
|
#else
|
|
return (0xff000000 | (pixel[0] << 16) | (pixel[1] << 8) | (pixel[2]));
|
|
#endif
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_r5g6b5(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD16 *) bits)[offset];
|
|
|
|
CARD32 r, g, b;
|
|
|
|
r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8;
|
|
g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
|
|
b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
|
|
return (0xff000000 | r | g | b);
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_b5g6r5(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD16 *) bits)[offset];
|
|
|
|
CARD32 r, g, b;
|
|
|
|
b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8;
|
|
g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
|
|
r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
|
|
return (0xff000000 | r | g | b);
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_a1r5g5b5(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD16 *) bits)[offset];
|
|
|
|
CARD32 a, r, g, b;
|
|
|
|
a = (CARD32) ((CARD8) (0 - ((pixel & 0x8000) >> 15))) << 24;
|
|
r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
|
|
g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
|
|
b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
|
|
return (a | r | g | b);
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_x1r5g5b5(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD16 *) bits)[offset];
|
|
|
|
CARD32 r, g, b;
|
|
|
|
r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
|
|
g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
|
|
b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
|
|
return (0xff000000 | r | g | b);
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_a1b5g5r5(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD16 *) bits)[offset];
|
|
|
|
CARD32 a, r, g, b;
|
|
|
|
a = (CARD32) ((CARD8) (0 - ((pixel & 0x8000) >> 15))) << 24;
|
|
b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
|
|
g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
|
|
r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
|
|
return (a | r | g | b);
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_x1b5g5r5(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD16 *) bits)[offset];
|
|
|
|
CARD32 r, g, b;
|
|
|
|
b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
|
|
g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
|
|
r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
|
|
return (0xff000000 | r | g | b);
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_a4r4g4b4(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD16 *) bits)[offset];
|
|
|
|
CARD32 a, r, g, b;
|
|
|
|
a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
|
|
r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
|
|
g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
|
|
b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
|
|
return (a | r | g | b);
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_x4r4g4b4(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD16 *) bits)[offset];
|
|
|
|
CARD32 r, g, b;
|
|
|
|
r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
|
|
g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
|
|
b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
|
|
return (0xff000000 | r | g | b);
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_a4b4g4r4(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD16 *) bits)[offset];
|
|
|
|
CARD32 a, r, g, b;
|
|
|
|
a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
|
|
b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
|
|
g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
|
|
r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
|
|
return (a | r | g | b);
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_x4b4g4r4(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD16 *) bits)[offset];
|
|
|
|
CARD32 r, g, b;
|
|
|
|
b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
|
|
g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
|
|
r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
|
|
return (0xff000000 | r | g | b);
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_a8(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD8 *) bits)[offset];
|
|
|
|
return pixel << 24;
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_r3g3b2(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD8 *) bits)[offset];
|
|
|
|
CARD32 r, g, b;
|
|
|
|
r = ((pixel & 0xe0) | ((pixel & 0xe0) >> 3) | ((pixel & 0xc0) >> 6)) << 16;
|
|
g = ((pixel & 0x1c) | ((pixel & 0x18) >> 3) | ((pixel & 0x1c) << 3)) << 8;
|
|
b = (((pixel & 0x03)) |
|
|
((pixel & 0x03) << 2) | ((pixel & 0x03) << 4) | ((pixel & 0x03) << 6));
|
|
return (0xff000000 | r | g | b);
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_b2g3r3(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD8 *) bits)[offset];
|
|
|
|
CARD32 r, g, b;
|
|
|
|
b = (((pixel & 0xc0)) |
|
|
((pixel & 0xc0) >> 2) | ((pixel & 0xc0) >> 4) | ((pixel & 0xc0) >> 6));
|
|
g = ((pixel & 0x38) | ((pixel & 0x38) >> 3) | ((pixel & 0x30) << 2)) << 8;
|
|
r = (((pixel & 0x07)) |
|
|
((pixel & 0x07) << 3) | ((pixel & 0x06) << 6)) << 16;
|
|
return (0xff000000 | r | g | b);
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_a2r2g2b2(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD8 *) bits)[offset];
|
|
|
|
CARD32 a, r, g, b;
|
|
|
|
a = ((pixel & 0xc0) * 0x55) << 18;
|
|
r = ((pixel & 0x30) * 0x55) << 12;
|
|
g = ((pixel & 0x0c) * 0x55) << 6;
|
|
b = ((pixel & 0x03) * 0x55);
|
|
return a | r | g | b;
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_a2b2g2r2(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD8 *) bits)[offset];
|
|
|
|
CARD32 a, r, g, b;
|
|
|
|
a = ((pixel & 0xc0) * 0x55) << 18;
|
|
b = ((pixel & 0x30) * 0x55) >> 6;
|
|
g = ((pixel & 0x0c) * 0x55) << 6;
|
|
r = ((pixel & 0x03) * 0x55) << 16;
|
|
return a | r | g | b;
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_c8(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD8 *) bits)[offset];
|
|
|
|
return indexed->rgba[pixel];
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_x4a4(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD8 *) bits)[offset];
|
|
|
|
return ((pixel & 0xf) | ((pixel & 0xf) << 4)) << 24;
|
|
}
|
|
|
|
#define Fetch8(l,o) (((CARD8 *) (l))[(o) >> 2])
|
|
#if IMAGE_BYTE_ORDER == MSBFirst
|
|
#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) & 0xf : Fetch8(l,o) >> 4)
|
|
#else
|
|
#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) >> 4 : Fetch8(l,o) & 0xf)
|
|
#endif
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_a4(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = Fetch4(bits, offset);
|
|
|
|
pixel |= pixel << 4;
|
|
return pixel << 24;
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_r1g2b1(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = Fetch4(bits, offset);
|
|
|
|
CARD32 r, g, b;
|
|
|
|
r = ((pixel & 0x8) * 0xff) << 13;
|
|
g = ((pixel & 0x6) * 0x55) << 7;
|
|
b = ((pixel & 0x1) * 0xff);
|
|
return 0xff000000 | r | g | b;
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_b1g2r1(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = Fetch4(bits, offset);
|
|
|
|
CARD32 r, g, b;
|
|
|
|
b = ((pixel & 0x8) * 0xff) >> 3;
|
|
g = ((pixel & 0x6) * 0x55) << 7;
|
|
r = ((pixel & 0x1) * 0xff) << 16;
|
|
return 0xff000000 | r | g | b;
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_a1r1g1b1(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = Fetch4(bits, offset);
|
|
|
|
CARD32 a, r, g, b;
|
|
|
|
a = ((pixel & 0x8) * 0xff) << 21;
|
|
r = ((pixel & 0x4) * 0xff) << 14;
|
|
g = ((pixel & 0x2) * 0xff) << 7;
|
|
b = ((pixel & 0x1) * 0xff);
|
|
return a | r | g | b;
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_a1b1g1r1(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = Fetch4(bits, offset);
|
|
|
|
CARD32 a, r, g, b;
|
|
|
|
a = ((pixel & 0x8) * 0xff) << 21;
|
|
r = ((pixel & 0x4) * 0xff) >> 3;
|
|
g = ((pixel & 0x2) * 0xff) << 7;
|
|
b = ((pixel & 0x1) * 0xff) << 16;
|
|
return a | r | g | b;
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_c4(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = Fetch4(bits, offset);
|
|
|
|
return indexed->rgba[pixel];
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_a1(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD32 *) bits)[offset >> 5];
|
|
|
|
CARD32 a;
|
|
|
|
#if BITMAP_BIT_ORDER == MSBFirst
|
|
a = pixel >> (0x1f - (offset & 0x1f));
|
|
#else
|
|
a = pixel >> (offset & 0x1f);
|
|
#endif
|
|
a = a & 1;
|
|
a |= a << 1;
|
|
a |= a << 2;
|
|
a |= a << 4;
|
|
return a << 24;
|
|
}
|
|
|
|
static FASTCALL CARD32
|
|
fbFetchPixel_g1(const FbBits * bits, int offset, miIndexedPtr indexed)
|
|
{
|
|
CARD32 pixel = ((CARD32 *) bits)[offset >> 5];
|
|
|
|
CARD32 a;
|
|
|
|
#if BITMAP_BIT_ORDER == MSBFirst
|
|
a = pixel >> (0x1f - (offset & 0x1f));
|
|
#else
|
|
a = pixel >> (offset & 0x1f);
|
|
#endif
|
|
a = a & 1;
|
|
return indexed->rgba[a];
|
|
}
|
|
|
|
static fetchPixelProc
|
|
fetchPixelProcForPicture(PicturePtr pict)
|
|
{
|
|
switch (pict->format) {
|
|
case PICT_a8r8g8b8:
|
|
return fbFetchPixel_a8r8g8b8;
|
|
case PICT_x8r8g8b8:
|
|
return fbFetchPixel_x8r8g8b8;
|
|
case PICT_a8b8g8r8:
|
|
return fbFetchPixel_a8b8g8r8;
|
|
case PICT_x8b8g8r8:
|
|
return fbFetchPixel_x8b8g8r8;
|
|
|
|
/* 24bpp formats */
|
|
case PICT_r8g8b8:
|
|
return fbFetchPixel_r8g8b8;
|
|
case PICT_b8g8r8:
|
|
return fbFetchPixel_b8g8r8;
|
|
|
|
/* 16bpp formats */
|
|
case PICT_r5g6b5:
|
|
return fbFetchPixel_r5g6b5;
|
|
case PICT_b5g6r5:
|
|
return fbFetchPixel_b5g6r5;
|
|
|
|
case PICT_a1r5g5b5:
|
|
return fbFetchPixel_a1r5g5b5;
|
|
case PICT_x1r5g5b5:
|
|
return fbFetchPixel_x1r5g5b5;
|
|
case PICT_a1b5g5r5:
|
|
return fbFetchPixel_a1b5g5r5;
|
|
case PICT_x1b5g5r5:
|
|
return fbFetchPixel_x1b5g5r5;
|
|
case PICT_a4r4g4b4:
|
|
return fbFetchPixel_a4r4g4b4;
|
|
case PICT_x4r4g4b4:
|
|
return fbFetchPixel_x4r4g4b4;
|
|
case PICT_a4b4g4r4:
|
|
return fbFetchPixel_a4b4g4r4;
|
|
case PICT_x4b4g4r4:
|
|
return fbFetchPixel_x4b4g4r4;
|
|
|
|
/* 8bpp formats */
|
|
case PICT_a8:
|
|
return fbFetchPixel_a8;
|
|
case PICT_r3g3b2:
|
|
return fbFetchPixel_r3g3b2;
|
|
case PICT_b2g3r3:
|
|
return fbFetchPixel_b2g3r3;
|
|
case PICT_a2r2g2b2:
|
|
return fbFetchPixel_a2r2g2b2;
|
|
case PICT_a2b2g2r2:
|
|
return fbFetchPixel_a2b2g2r2;
|
|
case PICT_c8:
|
|
return fbFetchPixel_c8;
|
|
case PICT_g8:
|
|
return fbFetchPixel_c8;
|
|
case PICT_x4a4:
|
|
return fbFetchPixel_x4a4;
|
|
|
|
/* 4bpp formats */
|
|
case PICT_a4:
|
|
return fbFetchPixel_a4;
|
|
case PICT_r1g2b1:
|
|
return fbFetchPixel_r1g2b1;
|
|
case PICT_b1g2r1:
|
|
return fbFetchPixel_b1g2r1;
|
|
case PICT_a1r1g1b1:
|
|
return fbFetchPixel_a1r1g1b1;
|
|
case PICT_a1b1g1r1:
|
|
return fbFetchPixel_a1b1g1r1;
|
|
case PICT_c4:
|
|
return fbFetchPixel_c4;
|
|
case PICT_g4:
|
|
return fbFetchPixel_c4;
|
|
|
|
/* 1bpp formats */
|
|
case PICT_a1:
|
|
return fbFetchPixel_a1;
|
|
case PICT_g1:
|
|
return fbFetchPixel_g1;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* All the store functions
|
|
*/
|
|
|
|
typedef FASTCALL void (*storeProc) (FbBits * bits, const CARD32 *values, int x,
|
|
int width, miIndexedPtr indexed);
|
|
|
|
#define Splita(v) CARD32 a = ((v) >> 24), r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
|
|
#define Split(v) CARD32 r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
|
|
|
|
static FASTCALL void
|
|
fbStore_a8r8g8b8(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
memcpy(((CARD32 *) bits) + x, values, width * sizeof(CARD32));
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_x8r8g8b8(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD32 *pixel = (CARD32 *) bits + x;
|
|
|
|
for (i = 0; i < width; ++i)
|
|
*pixel++ = values[i] & 0xffffff;
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_a8b8g8r8(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD32 *pixel = (CARD32 *) bits + x;
|
|
|
|
for (i = 0; i < width; ++i)
|
|
*pixel++ =
|
|
(values[i] & 0xff00ff00) | ((values[i] >> 16) & 0xff) |
|
|
((values[i] & 0xff) << 16);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_x8b8g8r8(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD32 *pixel = (CARD32 *) bits + x;
|
|
|
|
for (i = 0; i < width; ++i)
|
|
*pixel++ =
|
|
(values[i] & 0x0000ff00) | ((values[i] >> 16) & 0xff) |
|
|
((values[i] & 0xff) << 16);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_r8g8b8(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD8 *pixel = ((CARD8 *) bits) + 3 * x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
Store24(pixel, values[i]);
|
|
pixel += 3;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_b8g8r8(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD8 *pixel = ((CARD8 *) bits) + 3 * x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
#if IMAGE_BYTE_ORDER == MSBFirst
|
|
*pixel++ = Blue(values[i]);
|
|
*pixel++ = Green(values[i]);
|
|
*pixel++ = Red(values[i]);
|
|
#else
|
|
*pixel++ = Red(values[i]);
|
|
*pixel++ = Green(values[i]);
|
|
*pixel++ = Blue(values[i]);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_r5g6b5(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD16 *pixel = ((CARD16 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = values[i];
|
|
|
|
*pixel++ = ((s >> 3) & 0x001f) |
|
|
((s >> 5) & 0x07e0) | ((s >> 8) & 0xf800);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_b5g6r5(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD16 *pixel = ((CARD16 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
Split(values[i]);
|
|
*pixel++ = (((b << 8) & 0xf800) | ((g << 3) & 0x07e0) | ((r >> 3)));
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_a1r5g5b5(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD16 *pixel = ((CARD16 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
Splita(values[i]);
|
|
*pixel++ = (((a << 8) & 0x8000) |
|
|
((r << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((b >> 3)));
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_x1r5g5b5(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD16 *pixel = ((CARD16 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
Split(values[i]);
|
|
*pixel++ = (((r << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((b >> 3)));
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_a1b5g5r5(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD16 *pixel = ((CARD16 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
Splita(values[i]);
|
|
*pixel++ = (((a << 8) & 0x8000) |
|
|
((b << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((r >> 3)));
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_x1b5g5r5(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD16 *pixel = ((CARD16 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
Split(values[i]);
|
|
*pixel++ = (((b << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((r >> 3)));
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_a4r4g4b4(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD16 *pixel = ((CARD16 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
Splita(values[i]);
|
|
*pixel++ = (((a << 8) & 0xf000) |
|
|
((r << 4) & 0x0f00) | ((g) & 0x00f0) | ((b >> 4)));
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_x4r4g4b4(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD16 *pixel = ((CARD16 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
Split(values[i]);
|
|
*pixel++ = (((r << 4) & 0x0f00) | ((g) & 0x00f0) | ((b >> 4)));
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_a4b4g4r4(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD16 *pixel = ((CARD16 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
Splita(values[i]);
|
|
*pixel++ = (((a << 8) & 0xf000) |
|
|
((b << 4) & 0x0f00) | ((g) & 0x00f0) | ((r >> 4)));
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_x4b4g4r4(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD16 *pixel = ((CARD16 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
Split(values[i]);
|
|
*pixel++ = (((b << 4) & 0x0f00) | ((g) & 0x00f0) | ((r >> 4)));
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_a8(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD8 *pixel = ((CARD8 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
*pixel++ = values[i] >> 24;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_r3g3b2(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD8 *pixel = ((CARD8 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
Split(values[i]);
|
|
*pixel++ = (((r) & 0xe0) | ((g >> 3) & 0x1c) | ((b >> 6)));
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_b2g3r3(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD8 *pixel = ((CARD8 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
Split(values[i]);
|
|
*pixel++ = (((b) & 0xe0) | ((g >> 3) & 0x1c) | ((r >> 6)));
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_a2r2g2b2(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD8 *pixel = ((CARD8 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
Splita(values[i]);
|
|
*pixel++ = (((a) & 0xc0) |
|
|
((r >> 2) & 0x30) | ((g >> 4) & 0x0c) | ((b >> 6)));
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_c8(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD8 *pixel = ((CARD8 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
*pixel++ = miIndexToEnt24(indexed, values[i]);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_x4a4(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
CARD8 *pixel = ((CARD8 *) bits) + x;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
*pixel++ = values[i] >> 28;
|
|
}
|
|
}
|
|
|
|
#define Store8(l,o,v) (((CARD8 *) l)[(o) >> 3] = (v))
|
|
#if IMAGE_BYTE_ORDER == MSBFirst
|
|
#define Store4(l,o,v) Store8(l,o,((o) & 4 ? \
|
|
(Fetch8(l,o) & 0xf0) | (v) : \
|
|
(Fetch8(l,o) & 0x0f) | ((v) << 4)))
|
|
#else
|
|
#define Store4(l,o,v) Store8(l,o,((o) & 4 ? \
|
|
(Fetch8(l,o) & 0x0f) | ((v) << 4) : \
|
|
(Fetch8(l,o) & 0xf0) | (v)))
|
|
#endif
|
|
|
|
static FASTCALL void
|
|
fbStore_a4(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
Store4(bits, i + x, values[i] >> 28);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_r1g2b1(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 pixel;
|
|
|
|
Split(values[i]);
|
|
pixel = (((r >> 4) & 0x8) | ((g >> 5) & 0x6) | ((b >> 7)));
|
|
Store4(bits, i + x, pixel);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_b1g2r1(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 pixel;
|
|
|
|
Split(values[i]);
|
|
pixel = (((b >> 4) & 0x8) | ((g >> 5) & 0x6) | ((r >> 7)));
|
|
Store4(bits, i + x, pixel);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_a1r1g1b1(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 pixel;
|
|
|
|
Splita(values[i]);
|
|
pixel = (((a >> 4) & 0x8) |
|
|
((r >> 5) & 0x4) | ((g >> 6) & 0x2) | ((b >> 7)));
|
|
Store4(bits, i + x, pixel);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_a1b1g1r1(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 pixel;
|
|
|
|
Splita(values[i]);
|
|
pixel = (((a >> 4) & 0x8) |
|
|
((b >> 5) & 0x4) | ((g >> 6) & 0x2) | ((r >> 7)));
|
|
Store4(bits, i + x, pixel);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_c4(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 pixel;
|
|
|
|
pixel = miIndexToEnt24(indexed, values[i]);
|
|
Store4(bits, i + x, pixel);
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_a1(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 *pixel = ((CARD32 *) bits) + ((i + x) >> 5);
|
|
|
|
CARD32 mask = FbStipMask((i + x) & 0x1f, 1);
|
|
|
|
CARD32 v = values[i] & 0x80000000 ? mask : 0;
|
|
|
|
*pixel = (*pixel & ~mask) | v;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbStore_g1(FbBits * bits, const CARD32 *values, int x, int width,
|
|
miIndexedPtr indexed)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 *pixel = ((CARD32 *) bits) + ((i + x) >> 5);
|
|
|
|
CARD32 mask = FbStipMask((i + x) & 0x1f, 1);
|
|
|
|
CARD32 v = miIndexToEntY24(indexed, values[i]) ? mask : 0;
|
|
|
|
*pixel = (*pixel & ~mask) | v;
|
|
}
|
|
}
|
|
|
|
static storeProc
|
|
storeProcForPicture(PicturePtr pict)
|
|
{
|
|
switch (pict->format) {
|
|
case PICT_a8r8g8b8:
|
|
return fbStore_a8r8g8b8;
|
|
case PICT_x8r8g8b8:
|
|
return fbStore_x8r8g8b8;
|
|
case PICT_a8b8g8r8:
|
|
return fbStore_a8b8g8r8;
|
|
case PICT_x8b8g8r8:
|
|
return fbStore_x8b8g8r8;
|
|
|
|
/* 24bpp formats */
|
|
case PICT_r8g8b8:
|
|
return fbStore_r8g8b8;
|
|
case PICT_b8g8r8:
|
|
return fbStore_b8g8r8;
|
|
|
|
/* 16bpp formats */
|
|
case PICT_r5g6b5:
|
|
return fbStore_r5g6b5;
|
|
case PICT_b5g6r5:
|
|
return fbStore_b5g6r5;
|
|
|
|
case PICT_a1r5g5b5:
|
|
return fbStore_a1r5g5b5;
|
|
case PICT_x1r5g5b5:
|
|
return fbStore_x1r5g5b5;
|
|
case PICT_a1b5g5r5:
|
|
return fbStore_a1b5g5r5;
|
|
case PICT_x1b5g5r5:
|
|
return fbStore_x1b5g5r5;
|
|
case PICT_a4r4g4b4:
|
|
return fbStore_a4r4g4b4;
|
|
case PICT_x4r4g4b4:
|
|
return fbStore_x4r4g4b4;
|
|
case PICT_a4b4g4r4:
|
|
return fbStore_a4b4g4r4;
|
|
case PICT_x4b4g4r4:
|
|
return fbStore_x4b4g4r4;
|
|
|
|
/* 8bpp formats */
|
|
case PICT_a8:
|
|
return fbStore_a8;
|
|
case PICT_r3g3b2:
|
|
return fbStore_r3g3b2;
|
|
case PICT_b2g3r3:
|
|
return fbStore_b2g3r3;
|
|
case PICT_a2r2g2b2:
|
|
return fbStore_a2r2g2b2;
|
|
case PICT_c8:
|
|
return fbStore_c8;
|
|
case PICT_g8:
|
|
return fbStore_c8;
|
|
case PICT_x4a4:
|
|
return fbStore_x4a4;
|
|
|
|
/* 4bpp formats */
|
|
case PICT_a4:
|
|
return fbStore_a4;
|
|
case PICT_r1g2b1:
|
|
return fbStore_r1g2b1;
|
|
case PICT_b1g2r1:
|
|
return fbStore_b1g2r1;
|
|
case PICT_a1r1g1b1:
|
|
return fbStore_a1r1g1b1;
|
|
case PICT_a1b1g1r1:
|
|
return fbStore_a1b1g1r1;
|
|
case PICT_c4:
|
|
return fbStore_c4;
|
|
case PICT_g4:
|
|
return fbStore_c4;
|
|
|
|
/* 1bpp formats */
|
|
case PICT_a1:
|
|
return fbStore_a1;
|
|
case PICT_g1:
|
|
return fbStore_g1;
|
|
default:
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Combine src and mask
|
|
*/
|
|
static FASTCALL void
|
|
fbCombineMaskU(CARD32 *src, const CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 a = mask[i] >> 24;
|
|
|
|
CARD32 s = src[i];
|
|
|
|
FbByteMul(s, a);
|
|
src[i] = s;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* All of the composing functions
|
|
*/
|
|
|
|
static FASTCALL void
|
|
fbCombineClear(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
memset(dest, 0, width * sizeof(CARD32));
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineSrcU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
memcpy(dest, src, width * sizeof(CARD32));
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineOverU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 d = dest[i];
|
|
|
|
CARD32 ia = Alpha(~s);
|
|
|
|
FbByteMulAdd(d, ia, s);
|
|
dest[i] = d;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineOverReverseU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 d = dest[i];
|
|
|
|
CARD32 ia = Alpha(~dest[i]);
|
|
|
|
FbByteMulAdd(s, ia, d);
|
|
dest[i] = s;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineInU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 a = Alpha(dest[i]);
|
|
|
|
FbByteMul(s, a);
|
|
dest[i] = s;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineInReverseU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 d = dest[i];
|
|
|
|
CARD32 a = Alpha(src[i]);
|
|
|
|
FbByteMul(d, a);
|
|
dest[i] = d;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineOutU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 a = Alpha(~dest[i]);
|
|
|
|
FbByteMul(s, a);
|
|
dest[i] = s;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineOutReverseU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 d = dest[i];
|
|
|
|
CARD32 a = Alpha(~src[i]);
|
|
|
|
FbByteMul(d, a);
|
|
dest[i] = d;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineAtopU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 d = dest[i];
|
|
|
|
CARD32 dest_a = Alpha(d);
|
|
|
|
CARD32 src_ia = Alpha(~s);
|
|
|
|
FbByteAddMul(s, dest_a, d, src_ia);
|
|
dest[i] = s;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineAtopReverseU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 d = dest[i];
|
|
|
|
CARD32 src_a = Alpha(s);
|
|
|
|
CARD32 dest_ia = Alpha(~d);
|
|
|
|
FbByteAddMul(s, dest_ia, d, src_a);
|
|
dest[i] = s;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineXorU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 d = dest[i];
|
|
|
|
CARD32 src_ia = Alpha(~s);
|
|
|
|
CARD32 dest_ia = Alpha(~d);
|
|
|
|
FbByteAddMul(s, dest_ia, d, src_ia);
|
|
dest[i] = s;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineAddU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 d = dest[i];
|
|
|
|
FbByteAdd(d, s);
|
|
dest[i] = d;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineSaturateU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 d = dest[i];
|
|
|
|
CARD16 sa, da;
|
|
|
|
sa = s >> 24;
|
|
da = ~d >> 24;
|
|
if (sa > da) {
|
|
sa = FbIntDiv(da, sa);
|
|
FbByteMul(s, sa);
|
|
}
|
|
FbByteAdd(d, s);
|
|
dest[i] = d;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* All of the disjoint composing functions
|
|
|
|
The four entries in the first column indicate what source contributions
|
|
come from each of the four areas of the picture -- areas covered by neither
|
|
A nor B, areas covered only by A, areas covered only by B and finally
|
|
areas covered by both A and B.
|
|
|
|
Disjoint Conjoint
|
|
Fa Fb Fa Fb
|
|
(0,0,0,0) 0 0 0 0
|
|
(0,A,0,A) 1 0 1 0
|
|
(0,0,B,B) 0 1 0 1
|
|
(0,A,B,A) 1 min((1-a)/b,1) 1 max(1-a/b,0)
|
|
(0,A,B,B) min((1-b)/a,1) 1 max(1-b/a,0) 1
|
|
(0,0,0,A) max(1-(1-b)/a,0) 0 min(1,b/a) 0
|
|
(0,0,0,B) 0 max(1-(1-a)/b,0) 0 min(a/b,1)
|
|
(0,A,0,0) min(1,(1-b)/a) 0 max(1-b/a,0) 0
|
|
(0,0,B,0) 0 min(1,(1-a)/b) 0 max(1-a/b,0)
|
|
(0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0)
|
|
(0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b)
|
|
(0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0)
|
|
|
|
*/
|
|
|
|
#define CombineAOut 1
|
|
#define CombineAIn 2
|
|
#define CombineBOut 4
|
|
#define CombineBIn 8
|
|
|
|
#define CombineClear 0
|
|
#define CombineA (CombineAOut|CombineAIn)
|
|
#define CombineB (CombineBOut|CombineBIn)
|
|
#define CombineAOver (CombineAOut|CombineBOut|CombineAIn)
|
|
#define CombineBOver (CombineAOut|CombineBOut|CombineBIn)
|
|
#define CombineAAtop (CombineBOut|CombineAIn)
|
|
#define CombineBAtop (CombineAOut|CombineBIn)
|
|
#define CombineXor (CombineAOut|CombineBOut)
|
|
|
|
/* portion covered by a but not b */
|
|
static INLINE CARD8
|
|
fbCombineDisjointOutPart(CARD8 a, CARD8 b)
|
|
{
|
|
/* min (1, (1-b) / a) */
|
|
|
|
b = ~b; /* 1 - b */
|
|
if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */
|
|
return 0xff; /* 1 */
|
|
return FbIntDiv(b, a); /* (1-b) / a */
|
|
}
|
|
|
|
/* portion covered by both a and b */
|
|
static INLINE CARD8
|
|
fbCombineDisjointInPart(CARD8 a, CARD8 b)
|
|
{
|
|
/* max (1-(1-b)/a,0) */
|
|
/* = - min ((1-b)/a - 1, 0) */
|
|
/* = 1 - min (1, (1-b)/a) */
|
|
|
|
b = ~b; /* 1 - b */
|
|
if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */
|
|
return 0; /* 1 - 1 */
|
|
return ~FbIntDiv(b, a); /* 1 - (1-b) / a */
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineDisjointGeneralU(CARD32 *dest, const CARD32 *src, int width,
|
|
CARD8 combine)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 d = dest[i];
|
|
|
|
CARD32 m, n, o, p;
|
|
|
|
CARD16 Fa, Fb, t, u, v;
|
|
|
|
CARD8 sa = s >> 24;
|
|
|
|
CARD8 da = d >> 24;
|
|
|
|
switch (combine & CombineA) {
|
|
default:
|
|
Fa = 0;
|
|
break;
|
|
case CombineAOut:
|
|
Fa = fbCombineDisjointOutPart(sa, da);
|
|
break;
|
|
case CombineAIn:
|
|
Fa = fbCombineDisjointInPart(sa, da);
|
|
break;
|
|
case CombineA:
|
|
Fa = 0xff;
|
|
break;
|
|
}
|
|
|
|
switch (combine & CombineB) {
|
|
default:
|
|
Fb = 0;
|
|
break;
|
|
case CombineBOut:
|
|
Fb = fbCombineDisjointOutPart(da, sa);
|
|
break;
|
|
case CombineBIn:
|
|
Fb = fbCombineDisjointInPart(da, sa);
|
|
break;
|
|
case CombineB:
|
|
Fb = 0xff;
|
|
break;
|
|
}
|
|
m = FbGen(s, d, 0, Fa, Fb, t, u, v);
|
|
n = FbGen(s, d, 8, Fa, Fb, t, u, v);
|
|
o = FbGen(s, d, 16, Fa, Fb, t, u, v);
|
|
p = FbGen(s, d, 24, Fa, Fb, t, u, v);
|
|
s = m | n | o | p;
|
|
dest[i] = s;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineDisjointOverU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = src[i];
|
|
|
|
CARD16 a = s >> 24;
|
|
|
|
if (a != 0x00) {
|
|
if (a != 0xff) {
|
|
CARD32 d = dest[i];
|
|
|
|
a = fbCombineDisjointOutPart(d >> 24, a);
|
|
FbByteMulAdd(d, a, s);
|
|
s = d;
|
|
}
|
|
dest[i] = s;
|
|
}
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineDisjointInU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineDisjointGeneralU(dest, src, width, CombineAIn);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineDisjointInReverseU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineDisjointGeneralU(dest, src, width, CombineBIn);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineDisjointOutU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineDisjointGeneralU(dest, src, width, CombineAOut);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineDisjointOutReverseU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineDisjointGeneralU(dest, src, width, CombineBOut);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineDisjointAtopU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineDisjointGeneralU(dest, src, width, CombineAAtop);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineDisjointAtopReverseU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineDisjointGeneralU(dest, src, width, CombineBAtop);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineDisjointXorU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineDisjointGeneralU(dest, src, width, CombineXor);
|
|
}
|
|
|
|
/* portion covered by a but not b */
|
|
static INLINE CARD8
|
|
fbCombineConjointOutPart(CARD8 a, CARD8 b)
|
|
{
|
|
/* max (1-b/a,0) */
|
|
/* = 1-min(b/a,1) */
|
|
|
|
/* min (1, (1-b) / a) */
|
|
|
|
if (b >= a) /* b >= a -> b/a >= 1 */
|
|
return 0x00; /* 0 */
|
|
return ~FbIntDiv(b, a); /* 1 - b/a */
|
|
}
|
|
|
|
/* portion covered by both a and b */
|
|
static INLINE CARD8
|
|
fbCombineConjointInPart(CARD8 a, CARD8 b)
|
|
{
|
|
/* min (1,b/a) */
|
|
|
|
if (b >= a) /* b >= a -> b/a >= 1 */
|
|
return 0xff; /* 1 */
|
|
return FbIntDiv(b, a); /* b/a */
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineConjointGeneralU(CARD32 *dest, const CARD32 *src, int width,
|
|
CARD8 combine)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 d = dest[i];
|
|
|
|
CARD32 m, n, o, p;
|
|
|
|
CARD16 Fa, Fb, t, u, v;
|
|
|
|
CARD8 sa = s >> 24;
|
|
|
|
CARD8 da = d >> 24;
|
|
|
|
switch (combine & CombineA) {
|
|
default:
|
|
Fa = 0;
|
|
break;
|
|
case CombineAOut:
|
|
Fa = fbCombineConjointOutPart(sa, da);
|
|
break;
|
|
case CombineAIn:
|
|
Fa = fbCombineConjointInPart(sa, da);
|
|
break;
|
|
case CombineA:
|
|
Fa = 0xff;
|
|
break;
|
|
}
|
|
|
|
switch (combine & CombineB) {
|
|
default:
|
|
Fb = 0;
|
|
break;
|
|
case CombineBOut:
|
|
Fb = fbCombineConjointOutPart(da, sa);
|
|
break;
|
|
case CombineBIn:
|
|
Fb = fbCombineConjointInPart(da, sa);
|
|
break;
|
|
case CombineB:
|
|
Fb = 0xff;
|
|
break;
|
|
}
|
|
m = FbGen(s, d, 0, Fa, Fb, t, u, v);
|
|
n = FbGen(s, d, 8, Fa, Fb, t, u, v);
|
|
o = FbGen(s, d, 16, Fa, Fb, t, u, v);
|
|
p = FbGen(s, d, 24, Fa, Fb, t, u, v);
|
|
s = m | n | o | p;
|
|
dest[i] = s;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineConjointOverU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineConjointGeneralU(dest, src, width, CombineAOver);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineConjointOverReverseU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineConjointGeneralU(dest, src, width, CombineBOver);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineConjointInU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineConjointGeneralU(dest, src, width, CombineAIn);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineConjointInReverseU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineConjointGeneralU(dest, src, width, CombineBIn);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineConjointOutU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineConjointGeneralU(dest, src, width, CombineAOut);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineConjointOutReverseU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineConjointGeneralU(dest, src, width, CombineBOut);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineConjointAtopU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineConjointGeneralU(dest, src, width, CombineAAtop);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineConjointAtopReverseU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineConjointGeneralU(dest, src, width, CombineBAtop);
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineConjointXorU(CARD32 *dest, const CARD32 *src, int width)
|
|
{
|
|
fbCombineConjointGeneralU(dest, src, width, CombineXor);
|
|
}
|
|
|
|
static const CombineFuncU fbCombineFuncU[] = {
|
|
fbCombineClear,
|
|
fbCombineSrcU,
|
|
NULL, /* CombineDst */
|
|
fbCombineOverU,
|
|
fbCombineOverReverseU,
|
|
fbCombineInU,
|
|
fbCombineInReverseU,
|
|
fbCombineOutU,
|
|
fbCombineOutReverseU,
|
|
fbCombineAtopU,
|
|
fbCombineAtopReverseU,
|
|
fbCombineXorU,
|
|
fbCombineAddU,
|
|
fbCombineSaturateU,
|
|
NULL,
|
|
NULL,
|
|
fbCombineClear,
|
|
fbCombineSrcU,
|
|
NULL, /* CombineDst */
|
|
fbCombineDisjointOverU,
|
|
fbCombineSaturateU, /* DisjointOverReverse */
|
|
fbCombineDisjointInU,
|
|
fbCombineDisjointInReverseU,
|
|
fbCombineDisjointOutU,
|
|
fbCombineDisjointOutReverseU,
|
|
fbCombineDisjointAtopU,
|
|
fbCombineDisjointAtopReverseU,
|
|
fbCombineDisjointXorU,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
fbCombineClear,
|
|
fbCombineSrcU,
|
|
NULL, /* CombineDst */
|
|
fbCombineConjointOverU,
|
|
fbCombineConjointOverReverseU,
|
|
fbCombineConjointInU,
|
|
fbCombineConjointInReverseU,
|
|
fbCombineConjointOutU,
|
|
fbCombineConjointOutReverseU,
|
|
fbCombineConjointAtopU,
|
|
fbCombineConjointAtopReverseU,
|
|
fbCombineConjointXorU,
|
|
};
|
|
|
|
static FASTCALL void
|
|
fbCombineMaskC(CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 a = mask[i];
|
|
|
|
CARD32 x;
|
|
|
|
CARD16 xa;
|
|
|
|
if (!a) {
|
|
src[i] = 0;
|
|
continue;
|
|
}
|
|
|
|
x = src[i];
|
|
if (a == 0xffffffff) {
|
|
x = x >> 24;
|
|
x |= x << 8;
|
|
x |= x << 16;
|
|
mask[i] = x;
|
|
continue;
|
|
}
|
|
|
|
xa = x >> 24;
|
|
FbByteMulC(x, a);
|
|
src[i] = x;
|
|
FbByteMul(a, xa);
|
|
mask[i] = a;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineMaskValueC(CARD32 *src, const CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 a = mask[i];
|
|
|
|
CARD32 x;
|
|
|
|
if (!a) {
|
|
src[i] = 0;
|
|
continue;
|
|
}
|
|
|
|
if (a == 0xffffffff)
|
|
continue;
|
|
|
|
x = src[i];
|
|
FbByteMulC(x, a);
|
|
src[i] = x;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineMaskAlphaC(const CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 a = mask[i];
|
|
|
|
CARD32 x;
|
|
|
|
if (!a)
|
|
continue;
|
|
|
|
x = src[i] >> 24;
|
|
if (x == 0xff)
|
|
continue;
|
|
if (a == 0xffffffff) {
|
|
x = x >> 24;
|
|
x |= x << 8;
|
|
x |= x << 16;
|
|
mask[i] = x;
|
|
continue;
|
|
}
|
|
|
|
FbByteMul(a, x);
|
|
mask[i] = a;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineClearC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
memset(dest, 0, width * sizeof(CARD32));
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineSrcC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
fbCombineMaskValueC(src, mask, width);
|
|
memcpy(dest, src, width * sizeof(CARD32));
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineOverC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
fbCombineMaskC(src, mask, width);
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 a = ~mask[i];
|
|
|
|
if (a != 0xffffffff) {
|
|
if (a) {
|
|
CARD32 d = dest[i];
|
|
|
|
FbByteMulAddC(d, a, s);
|
|
s = d;
|
|
}
|
|
dest[i] = s;
|
|
}
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineOverReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
fbCombineMaskValueC(src, mask, width);
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 d = dest[i];
|
|
|
|
CARD32 a = ~d >> 24;
|
|
|
|
if (a) {
|
|
CARD32 s = src[i];
|
|
|
|
if (a != 0xff) {
|
|
FbByteMulAdd(s, a, d);
|
|
}
|
|
dest[i] = s;
|
|
}
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineInC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
fbCombineMaskValueC(src, mask, width);
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 d = dest[i];
|
|
|
|
CARD16 a = d >> 24;
|
|
|
|
CARD32 s = 0;
|
|
|
|
if (a) {
|
|
s = src[i];
|
|
if (a != 0xff) {
|
|
FbByteMul(s, a);
|
|
}
|
|
}
|
|
dest[i] = s;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineInReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
fbCombineMaskAlphaC(src, mask, width);
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 a = mask[i];
|
|
|
|
if (a != 0xffffffff) {
|
|
CARD32 d = 0;
|
|
|
|
if (a) {
|
|
d = dest[i];
|
|
FbByteMulC(d, a);
|
|
}
|
|
dest[i] = d;
|
|
}
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineOutC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
fbCombineMaskValueC(src, mask, width);
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 d = dest[i];
|
|
|
|
CARD16 a = ~d >> 24;
|
|
|
|
CARD32 s = 0;
|
|
|
|
if (a) {
|
|
s = src[i];
|
|
if (a != 0xff) {
|
|
FbByteMul(s, a);
|
|
}
|
|
}
|
|
dest[i] = s;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineOutReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
fbCombineMaskAlphaC(src, mask, width);
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 a = ~mask[i];
|
|
|
|
if (a != 0xffffffff) {
|
|
CARD32 d = 0;
|
|
|
|
if (a) {
|
|
d = dest[i];
|
|
FbByteMulC(d, a);
|
|
}
|
|
dest[i] = d;
|
|
}
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineAtopC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
fbCombineMaskC(src, mask, width);
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 d = dest[i];
|
|
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 ad = ~mask[i];
|
|
|
|
CARD16 as = d >> 24;
|
|
|
|
FbByteAddMulC(d, ad, s, as);
|
|
dest[i] = d;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineAtopReverseC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
fbCombineMaskC(src, mask, width);
|
|
for (i = 0; i < width; ++i) {
|
|
|
|
CARD32 d = dest[i];
|
|
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 ad = mask[i];
|
|
|
|
CARD16 as = ~d >> 24;
|
|
|
|
FbByteAddMulC(d, ad, s, as);
|
|
dest[i] = d;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineXorC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
fbCombineMaskC(src, mask, width);
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 d = dest[i];
|
|
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 ad = ~mask[i];
|
|
|
|
CARD16 as = ~d >> 24;
|
|
|
|
FbByteAddMulC(d, ad, s, as);
|
|
dest[i] = d;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineAddC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
fbCombineMaskValueC(src, mask, width);
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s = src[i];
|
|
|
|
CARD32 d = dest[i];
|
|
|
|
FbByteAdd(d, s);
|
|
dest[i] = d;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineSaturateC(CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
|
|
{
|
|
int i;
|
|
|
|
fbCombineMaskC(src, mask, width);
|
|
for (i = 0; i < width; ++i) {
|
|
CARD32 s, d;
|
|
|
|
CARD16 sa, sr, sg, sb, da;
|
|
|
|
CARD16 t, u, v;
|
|
|
|
CARD32 m, n, o, p;
|
|
|
|
d = dest[i];
|
|
s = src[i];
|
|
sa = (mask[i] >> 24);
|
|
sr = (mask[i] >> 16) & 0xff;
|
|
sg = (mask[i] >> 8) & 0xff;
|
|
sb = (mask[i]) & 0xff;
|
|
da = ~d >> 24;
|
|
|
|
if (sb <= da)
|
|
m = FbAdd(s, d, 0, t);
|
|
else
|
|
m = FbGen(s, d, 0, (da << 8) / sb, 0xff, t, u, v);
|
|
|
|
if (sg <= da)
|
|
n = FbAdd(s, d, 8, t);
|
|
else
|
|
n = FbGen(s, d, 8, (da << 8) / sg, 0xff, t, u, v);
|
|
|
|
if (sr <= da)
|
|
o = FbAdd(s, d, 16, t);
|
|
else
|
|
o = FbGen(s, d, 16, (da << 8) / sr, 0xff, t, u, v);
|
|
|
|
if (sa <= da)
|
|
p = FbAdd(s, d, 24, t);
|
|
else
|
|
p = FbGen(s, d, 24, (da << 8) / sa, 0xff, t, u, v);
|
|
|
|
dest[i] = m | n | o | p;
|
|
}
|
|
}
|
|
|
|
static FASTCALL void
|
|
fbCombineDisjointGeneralC(C |