803 lines
21 KiB
C
803 lines
21 KiB
C
/**************************************************************************/
|
|
/* */
|
|
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
|
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
|
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
|
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
|
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
|
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
|
/* */
|
|
/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
|
|
/* are copyright of the aforementioned persons and companies. */
|
|
/* */
|
|
/* Redistribution and use of the present software is allowed according */
|
|
/* to terms specified in the file LICENSE which comes in the source */
|
|
/* distribution. */
|
|
/* */
|
|
/* All rights reserved. */
|
|
/* */
|
|
/* NOTE: This software has received contributions from various other */
|
|
/* contributors, only the core maintainers and supporters are listed as */
|
|
/* copyright holders. Please contact us, if you feel you should be listed */
|
|
/* as copyright holder, as well. */
|
|
/* */
|
|
/**************************************************************************/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <nx-X11/Xlib.h>
|
|
|
|
#include <nx/NXpack.h>
|
|
|
|
#include "Mask.h"
|
|
|
|
#define PANIC
|
|
#define WARNING
|
|
#undef TEST
|
|
#undef DEBUG
|
|
|
|
/*
|
|
* Try first to reduce to a white or black
|
|
* pixel. If not possible, apply the mask.
|
|
* Note that correction is applied at the
|
|
* time pixel is unpacked.
|
|
*/
|
|
|
|
#define MaskPixel(red, green, blue, mask) \
|
|
\
|
|
if (red > mask -> white_threshold && \
|
|
green > mask -> white_threshold && \
|
|
blue > mask -> white_threshold) \
|
|
{ \
|
|
red = green = blue = 0xff; \
|
|
} \
|
|
else if (red < mask -> black_threshold && \
|
|
green < mask -> black_threshold && \
|
|
blue < mask -> black_threshold) \
|
|
{ \
|
|
red = green = blue = 0x00; \
|
|
} \
|
|
else \
|
|
{ \
|
|
red = red & mask -> color_mask; \
|
|
green = green & mask -> color_mask; \
|
|
blue = blue & mask -> color_mask; \
|
|
}
|
|
|
|
int MaskImage(const ColorMask *mask, XImage *src_image, XImage *dst_image)
|
|
{
|
|
unsigned long pixel;
|
|
|
|
register unsigned int red;
|
|
register unsigned int green;
|
|
register unsigned int blue;
|
|
|
|
register unsigned long data_size;
|
|
|
|
register unsigned int i;
|
|
|
|
data_size = (src_image -> bytes_per_line * src_image -> height) >> 2;
|
|
|
|
#ifdef TEST
|
|
fprintf(stderr, "******MaskImage: Going to mask image with [%d] bits per pixel.\n",
|
|
src_image -> bits_per_pixel);
|
|
#endif
|
|
|
|
if (src_image -> bits_per_pixel == 24 || src_image -> bits_per_pixel == 32)
|
|
{
|
|
register unsigned char *pixel_addr;
|
|
|
|
for (i = 0; i < data_size; i++)
|
|
{
|
|
pixel = ((unsigned long *) src_image -> data)[i];
|
|
|
|
pixel_addr = (unsigned char *) &pixel;
|
|
|
|
red = pixel_addr[2];
|
|
green = pixel_addr[1];
|
|
blue = pixel_addr[0];
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskImage: 24/32 bits original R [%d] G [%d] B [%d] A [%d].\n",
|
|
red, green, blue, pixel_addr[3]);
|
|
#endif
|
|
|
|
MaskPixel(red, green, blue, mask);
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskImage: 24/32 bits masked R [%d] G [%d] B [%d] A [%d].\n",
|
|
red, green, blue, pixel_addr[3]);
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskImage: 24/32 bits pixel 0x%lx", pixel);
|
|
#endif
|
|
|
|
pixel_addr[2] = red;
|
|
pixel_addr[1] = green;
|
|
pixel_addr[0] = blue;
|
|
|
|
((unsigned long*)dst_image -> data)[i] = pixel;
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, " -> 0x%lx\n", pixel);
|
|
#endif
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
else if (src_image -> bits_per_pixel == 16)
|
|
{
|
|
/*
|
|
* FIXME: Masking doesn't work in 16 bpp.
|
|
*
|
|
|
|
unsigned long src_addr, *dst_addr;
|
|
unsigned short *src_pixels_addr, *dst_pixels_addr;
|
|
|
|
for (i = 0; i < data_size; i++)
|
|
{
|
|
src_addr = ((unsigned long *)src_image -> data)[i];
|
|
dst_addr = (unsigned long *)((unsigned long *)dst_image -> data + i);
|
|
|
|
src_pixels_addr = ((unsigned short *) &src_addr);
|
|
dst_pixels_addr = ((unsigned short *) dst_addr);
|
|
|
|
red = (src_pixels_addr[0] & src_image -> red_mask) >> 8;
|
|
green = (src_pixels_addr[0] & src_image -> green_mask) >> 3;
|
|
blue = (src_pixels_addr[0] & src_image -> blue_mask) << 3;
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskImage: 16 bits original R [%d] G [%d] B [%d].\n",
|
|
red, green, blue);
|
|
#endif
|
|
|
|
MaskPixel(red, green, blue, mask);
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskImage: 16 bits masked R [%d] G [%d] B [%d].\n",
|
|
red, green, blue);
|
|
#endif
|
|
|
|
dst_pixels_addr[0] = ((red << 8) & src_image -> red_mask) |
|
|
((green << 3) & src_image -> green_mask) |
|
|
((blue >> 3) & src_image -> blue_mask);
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskImage: 16 bits pixel 0x%x", dst_pixels_addr[0]);
|
|
#endif
|
|
|
|
red = (src_pixels_addr[1] & src_image -> red_mask) >> 8;
|
|
green = (src_pixels_addr[1] & src_image -> green_mask) >> 3;
|
|
blue = (src_pixels_addr[1] & src_image -> blue_mask) << 3;
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskImage: 16 bits original R [%d] G [%d] B [%d].\n",
|
|
red, green, blue);
|
|
#endif
|
|
|
|
MaskPixel(red, green, blue, mask);
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskImage: 16 bits masked R [%d] G [%d] B [%d].\n",
|
|
red, green, blue);
|
|
#endif
|
|
|
|
dst_pixels_addr[1] = ((red << 8) & src_image -> red_mask) |
|
|
((green << 3) & src_image -> green_mask) |
|
|
((blue >> 3) & src_image -> blue_mask);
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskImage: 16 bits pixel 0x%x", dst_pixels_addr[0]);
|
|
#endif
|
|
}
|
|
|
|
if (dst_image -> width & 0x00000001)
|
|
{
|
|
int card32_per_line;
|
|
int i;
|
|
|
|
card32_per_line = dst_image -> bytes_per_line >> 2;
|
|
|
|
for (i = 0; i < dst_image -> height;)
|
|
{
|
|
((CARD32 *) dst_image -> data)[(++i * card32_per_line) - 1] &= 0x0000ffff;
|
|
}
|
|
}
|
|
|
|
*
|
|
* End of FIXME.
|
|
*/
|
|
}
|
|
else
|
|
{
|
|
#ifdef TEST
|
|
fprintf(stderr, "******MaskImage: PANIC! Cannot apply mask with [%d] bits per pixel.\n",
|
|
src_image -> bits_per_pixel);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int MaskInPlaceImage(const ColorMask *mask, XImage *image)
|
|
{
|
|
unsigned long pixel;
|
|
|
|
register unsigned int red;
|
|
register unsigned int green;
|
|
register unsigned int blue;
|
|
|
|
register unsigned int i;
|
|
|
|
register unsigned long data_size;
|
|
|
|
data_size = (image -> bytes_per_line * image -> height)>>2;
|
|
|
|
#ifdef TEST
|
|
fprintf(stderr, "******MaskInPlaceImage: Going to mask image with [%d] bits per pixel.\n",
|
|
image -> bits_per_pixel);
|
|
#endif
|
|
|
|
if (image -> bits_per_pixel == 24 || image -> bits_per_pixel == 32)
|
|
{
|
|
register unsigned char *pixel_addr;
|
|
|
|
for (i = 0; i < data_size; i++)
|
|
{
|
|
pixel = ((unsigned long *) image -> data)[i];
|
|
|
|
pixel_addr = (unsigned char *) &pixel;
|
|
|
|
red = pixel_addr[2];
|
|
green = pixel_addr[1];
|
|
blue = pixel_addr[0];
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskInPlaceImage: 24/32 bits original R [%d] G [%d] B [%d] A [%d].\n",
|
|
red, green, blue, pixel_addr[3]);
|
|
#endif
|
|
|
|
MaskPixel(red, green, blue, mask);
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskInPlaceImage: 24/32 bits masked R [%d] G [%d] B [%d] A [%d].\n",
|
|
red, green, blue, pixel_addr[3]);
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskInPlaceImage: 24/32 bits pixel 0x%lx", pixel);
|
|
#endif
|
|
|
|
pixel_addr[2] = red;
|
|
pixel_addr[1] = green;
|
|
pixel_addr[0] = blue;
|
|
|
|
((unsigned long *) image -> data)[i] = pixel;
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, " -> 0x%lx\n", pixel);
|
|
#endif
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
else if (image -> bits_per_pixel == 16)
|
|
{
|
|
/*
|
|
* FIXME: Mask doesn't still work for 16 bits.
|
|
*
|
|
|
|
unsigned long addr;
|
|
register unsigned short *pixels_addr;
|
|
|
|
for (i = 0; i < data_size; i++)
|
|
{
|
|
addr = ((unsigned long *) image -> data)[i];
|
|
|
|
pixels_addr = ((unsigned short *) &addr);
|
|
|
|
red = (pixels_addr[0] & image -> red_mask) >> 8;
|
|
green = (pixels_addr[0] & image -> green_mask) >> 3;
|
|
blue = (pixels_addr[0] & image -> blue_mask) << 3;
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskInPlaceImage: 16 bits original R [%d] G [%d] B [%d].\n",
|
|
red, green, blue);
|
|
#endif
|
|
|
|
MaskPixel(red, green, blue, mask);
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskInPlaceImage: 16 bits masked R [%d] G [%d] B [%d].\n",
|
|
red, green, blue);
|
|
#endif
|
|
|
|
pixels_addr[0] = ((red << 8) & image -> red_mask) |
|
|
((green << 3) & image -> green_mask) |
|
|
((blue >> 3) & image -> blue_mask);
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskInPlaceImage: 16 bits pixel 0x%x", pixels_addr[0]);
|
|
#endif
|
|
|
|
red = (pixels_addr[1] & image -> red_mask) >> 8;
|
|
green = (pixels_addr[1] & image -> green_mask) >> 3;
|
|
blue = (pixels_addr[1] & image -> blue_mask) << 3;
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskInPlaceImage: 16 bits original R [%d] G [%d] B [%d].\n",
|
|
red, green, blue);
|
|
#endif
|
|
|
|
MaskPixel(red, green, blue, mask);
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskInPlaceImage: 16 bits masked R [%d] G [%d] B [%d].\n",
|
|
red, green, blue);
|
|
#endif
|
|
|
|
pixels_addr[1] = ((red << 8) & image -> red_mask) |
|
|
((green << 3) & image -> green_mask) |
|
|
((blue >> 3) & image -> blue_mask);
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******MaskInPlaceImage: 16 bits pixel 0x%x", pixels_addr[1]);
|
|
#endif
|
|
}
|
|
|
|
if (image -> width & 0x00000001)
|
|
{
|
|
int card32_per_line;
|
|
int i;
|
|
|
|
card32_per_line = image -> bytes_per_line >> 2;
|
|
|
|
for (i = 0; i < image -> height;)
|
|
{
|
|
((CARD32 *) image -> data)[(++i * card32_per_line) - 1] &= 0x0000ffff;
|
|
}
|
|
}
|
|
|
|
*
|
|
* End of FIXME.
|
|
*/
|
|
}
|
|
else
|
|
{
|
|
#ifdef TEST
|
|
fprintf(stderr, "******MaskImage: PANIC! Cannot apply mask with [%d] bits per pixel.\n",
|
|
image -> bits_per_pixel);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int Pack16To8(unsigned int src_data_size, XImage *src_image, XImage *dst_image)
|
|
{
|
|
unsigned short *src_pixel = (unsigned short *) src_image -> data;
|
|
unsigned char *dst_pixel = (unsigned char *) dst_image -> data;
|
|
|
|
#ifdef DEBUG
|
|
unsigned int counter = 0;
|
|
#endif
|
|
|
|
while (src_pixel < ((unsigned short *) (src_image -> data + src_data_size)))
|
|
{
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******PackImage: Pixel [%d] value [0x%x] red [0x%x] green [0x%x] blue [0x%x].\n",
|
|
counter, *src_pixel, (*src_pixel & 0xc000) >> 8,
|
|
((*src_pixel & 0x600) >> 3), (*src_pixel & 0x18) << 3);
|
|
#endif
|
|
|
|
if (*src_pixel == 0x0)
|
|
{
|
|
*dst_pixel = 0x0;
|
|
}
|
|
else if (*src_pixel == 0xffff)
|
|
{
|
|
*dst_pixel = 0xff;
|
|
}
|
|
else
|
|
{
|
|
*dst_pixel = ((*src_pixel & 0xc000) >> 10) |
|
|
((*src_pixel & 0x600) >> 7) |
|
|
((*src_pixel & 0x18) >> 3);
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******PackImage: Pixel [%d] destination [0x%x].\n",
|
|
counter++, *dst_pixel);
|
|
#endif
|
|
|
|
src_pixel++;
|
|
dst_pixel++;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int Pack24To8(unsigned int src_data_size, XImage *src_image, XImage *dst_image)
|
|
{
|
|
unsigned char *src_pixel = (unsigned char *) src_image -> data;
|
|
unsigned char *dst_pixel = (unsigned char *) dst_image -> data;
|
|
|
|
int i;
|
|
|
|
unsigned int bytes_per_line = src_image -> bytes_per_line;
|
|
|
|
unsigned char *end_of_line = (unsigned char *) (src_pixel + bytes_per_line);
|
|
|
|
|
|
#ifdef DEBUG
|
|
unsigned int counter = 0;
|
|
#endif
|
|
|
|
for (i = 0; i < src_image -> height; i++ )
|
|
{
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******PackImage: Pixel [%d] value [0x%x%x%x] red [0x%x] green [0x%x] blue [0x%x].\n",
|
|
counter, src_pixel[0], src_pixel[1], src_pixel[2], src_pixel[0] & 0xc0,
|
|
src_pixel[1] & 0xc0, src_pixel[2] & 0xc0);
|
|
#endif
|
|
|
|
while(src_pixel < end_of_line - 2)
|
|
{
|
|
if (src_pixel[0] == 0x00 &&
|
|
src_pixel[1] == 0x00 &&
|
|
src_pixel[2] == 0x00)
|
|
{
|
|
*dst_pixel = 0x0;
|
|
}
|
|
else if (src_pixel[0] == 0xff &&
|
|
src_pixel[1] == 0xff &&
|
|
src_pixel[2] == 0xff)
|
|
{
|
|
*dst_pixel = 0xff;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* Pixel layout:
|
|
*
|
|
* 24 bit RRRRR000 GGGGG000 BBBBB000 -> 8 bit 00RRGGBB
|
|
*/
|
|
|
|
*dst_pixel = (src_pixel[0] & 0xc0) >> 2 |
|
|
((src_pixel[1] & 0xc0) >> 4) |
|
|
((src_pixel[2] & 0xc0) >> 6);
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******PackImage: Pixel [%d] destination [0x%x].\n",
|
|
counter++, *dst_pixel);
|
|
#endif
|
|
|
|
src_pixel += 3;
|
|
dst_pixel += 1;
|
|
}
|
|
|
|
src_pixel = end_of_line;
|
|
end_of_line += bytes_per_line;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int Pack24To16(unsigned int src_data_size, XImage *src_image, XImage *dst_image)
|
|
{
|
|
unsigned char *src_pixel = (unsigned char *) src_image -> data;
|
|
unsigned short *dst_pixel = (unsigned short *) dst_image -> data;
|
|
|
|
int i;
|
|
|
|
unsigned int bytes_per_line = src_image -> bytes_per_line;
|
|
|
|
unsigned char *end_of_line = (unsigned char *) (src_pixel + bytes_per_line);
|
|
|
|
#ifdef DEBUG
|
|
unsigned int counter = 0;
|
|
#endif
|
|
|
|
for (i = 0; i < src_image -> height; i++ )
|
|
{
|
|
while(src_pixel < end_of_line - 2)
|
|
{
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******PackImage: Pixel [%d] value [0x%x%x%x] red [0x%x] green [0x%x] blue [0x%x].\n",
|
|
counter, src_pixel[0], src_pixel[1], src_pixel[2], src_pixel[0] & 0xf8,
|
|
src_pixel[1] & 0xf8, src_pixel[2] & 0xf8);
|
|
#endif
|
|
|
|
if (src_pixel[0] == 0x00 &&
|
|
src_pixel[1] == 0x00 &&
|
|
src_pixel[2] == 0x00)
|
|
{
|
|
*dst_pixel = 0x0;
|
|
}
|
|
else if (src_pixel[0] == 0xff &&
|
|
src_pixel[1] == 0xff &&
|
|
src_pixel[2] == 0xff)
|
|
{
|
|
*dst_pixel = 0xffff;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* Pixel layout:
|
|
*
|
|
* 24 bit RRRRR000 GGGGG000 BBBBB000 -> 16 bit 0RRRRRGG GGGBBBBB
|
|
*/
|
|
|
|
*dst_pixel = ((src_pixel[0] & 0xf8) << 7) |
|
|
((src_pixel[1] & 0xf8) << 2) |
|
|
((src_pixel[2] & 0xf8) >> 3);
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******PackImage: Pixel [%d] destination [0x%x].\n",
|
|
counter++, *dst_pixel);
|
|
#endif
|
|
|
|
src_pixel += 3;
|
|
dst_pixel += 1;
|
|
}
|
|
|
|
src_pixel = end_of_line;
|
|
end_of_line += bytes_per_line;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int Pack32To8(unsigned int src_data_size, XImage *src_image, XImage *dst_image)
|
|
{
|
|
unsigned int *src_pixel = (unsigned int *) src_image -> data;
|
|
unsigned char *dst_pixel = (unsigned char *) dst_image -> data;
|
|
|
|
#ifdef DEBUG
|
|
unsigned int counter = 0;
|
|
#endif
|
|
|
|
while (src_pixel < ((unsigned int *) (src_image -> data + src_data_size)))
|
|
{
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******PackImage: Pixel [%d] value [0x%x] red [0x%x] green [0x%x] blue [0x%x].\n",
|
|
counter, *src_pixel, (*src_pixel & 0xc00000),
|
|
(*src_pixel & 0xc000), (*src_pixel & 0xc0));
|
|
#endif
|
|
|
|
if (*src_pixel == 0x0)
|
|
{
|
|
*dst_pixel = 0x0;
|
|
}
|
|
else if (*src_pixel == 0xffffff)
|
|
{
|
|
*dst_pixel = 0xff;
|
|
}
|
|
else
|
|
{
|
|
*dst_pixel = ((*src_pixel & 0xc00000) >> 18) |
|
|
((*src_pixel & 0xc000) >> 12) |
|
|
((*src_pixel & 0xc0) >> 6);
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******PackImage: Pixel [%d] destination [0x%x].\n",
|
|
counter++, *dst_pixel);
|
|
#endif
|
|
|
|
src_pixel++;
|
|
dst_pixel++;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int Pack32To16(unsigned int src_data_size, XImage *src_image, XImage *dst_image)
|
|
{
|
|
unsigned int *src_pixel = (unsigned int *) src_image -> data;
|
|
unsigned short *dst_pixel = (unsigned short *) dst_image -> data;
|
|
|
|
#ifdef DEBUG
|
|
unsigned int counter = 0;
|
|
#endif
|
|
|
|
while (src_pixel < ((unsigned int *) (src_image -> data + src_data_size)))
|
|
{
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******PackImage: Pixel [%d] value [0x%x] red [0x%x] green [0x%x] blue [0x%x].\n",
|
|
counter, *src_pixel, (*src_pixel & 0xf80000),
|
|
(*src_pixel & 0xf800), (*src_pixel & 0xf8));
|
|
#endif
|
|
|
|
if (*src_pixel == 0x0)
|
|
{
|
|
*dst_pixel = 0x0;
|
|
}
|
|
else if (*src_pixel == 0xffffff)
|
|
{
|
|
*dst_pixel = 0xffff;
|
|
}
|
|
else
|
|
{
|
|
*dst_pixel = ((*src_pixel & 0xf80000) >> 9) |
|
|
((*src_pixel & 0xf800) >> 6) |
|
|
((*src_pixel & 0xf8) >> 3);
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******PackImage: Pixel [%d] destination [0x%x].\n",
|
|
counter++, *dst_pixel);
|
|
#endif
|
|
|
|
src_pixel++;
|
|
dst_pixel++;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int Pack32To24(unsigned int src_data_size, XImage *src_image, XImage *dst_image)
|
|
{
|
|
unsigned int *src_pixel = (unsigned int *) src_image -> data;
|
|
unsigned char *dst_pixel = (unsigned char *) dst_image -> data;
|
|
|
|
#ifdef DEBUG
|
|
unsigned int counter = 0;
|
|
#endif
|
|
|
|
while (src_pixel < ((unsigned int *) (src_image -> data + src_data_size)))
|
|
{
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******PackImage: Pixel [%d] value [0x%x] red [0x%x] green [0x%x] blue [0x%x].\n",
|
|
counter, *src_pixel, ((*src_pixel & 0xff0000) >> 16),
|
|
((*src_pixel & 0x00ff00) >> 8), (*src_pixel & 0xff));
|
|
#endif
|
|
|
|
if (*src_pixel == 0x0)
|
|
{
|
|
dst_pixel[0] = dst_pixel[1] = dst_pixel[2] = 0x0;
|
|
}
|
|
else if (*src_pixel == 0xffffff)
|
|
{
|
|
dst_pixel[0] = dst_pixel[1] = dst_pixel[2] = 0xff;
|
|
}
|
|
else
|
|
{
|
|
dst_pixel[0] = (*src_pixel & 0xff0000) >> 16;
|
|
dst_pixel[1] = (*src_pixel & 0x00ff00) >> 8;
|
|
dst_pixel[2] = (*src_pixel & 0x0000ff);
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "******PackImage: Pixel [%d] destination [0x%x], [0x%x], [0x%x].\n",
|
|
counter++, dst_pixel[0], dst_pixel[1], dst_pixel[2]);
|
|
#endif
|
|
|
|
src_pixel += 1;
|
|
dst_pixel += 3;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int PackImage(unsigned int method, unsigned int src_data_size, XImage *src_image,
|
|
unsigned int dst_data_size, XImage *dst_image)
|
|
{
|
|
unsigned int src_bits_per_pixel;
|
|
unsigned int dst_bits_per_pixel;
|
|
|
|
src_bits_per_pixel = src_image -> bits_per_pixel;
|
|
dst_bits_per_pixel = MethodBitsPerPixel(method);
|
|
|
|
#ifdef TEST
|
|
fprintf(stderr, "******PackImage: Source bits per pixel [%d], destination bits per pixel [%d].\n",
|
|
src_bits_per_pixel, dst_bits_per_pixel);
|
|
|
|
fprintf(stderr, "******PackImage: Source data size [%d], destination data size [%d].\n",
|
|
src_data_size, dst_data_size);
|
|
#endif
|
|
|
|
if (dst_bits_per_pixel >= src_bits_per_pixel)
|
|
{
|
|
#ifdef PANIC
|
|
fprintf(stderr, "******PackImage: PANIC! Cannot pack image from [%d] to [%d] bytes per pixel.\n",
|
|
src_bits_per_pixel, dst_bits_per_pixel);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
switch (src_bits_per_pixel)
|
|
{
|
|
case 16:
|
|
{
|
|
switch (dst_bits_per_pixel)
|
|
{
|
|
case 8:
|
|
{
|
|
return Pack16To8(src_data_size, src_image, dst_image);
|
|
}
|
|
default:
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
case 24:
|
|
{
|
|
switch (dst_bits_per_pixel)
|
|
{
|
|
case 8:
|
|
{
|
|
return Pack24To8(src_data_size, src_image, dst_image);
|
|
}
|
|
case 16:
|
|
{
|
|
return Pack24To16(src_data_size, src_image, dst_image);
|
|
}
|
|
default:
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
case 32:
|
|
{
|
|
switch (dst_bits_per_pixel)
|
|
{
|
|
case 8:
|
|
{
|
|
return Pack32To8(src_data_size, src_image, dst_image);
|
|
}
|
|
case 16:
|
|
{
|
|
return Pack32To16(src_data_size, src_image, dst_image);
|
|
}
|
|
case 24:
|
|
{
|
|
return Pack32To24(src_data_size, src_image, dst_image);
|
|
}
|
|
default:
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
default:
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Replace the ffs() call that may be not
|
|
* present on some systems.
|
|
*/
|
|
|
|
int FindLSB(int word)
|
|
{
|
|
int t = word;
|
|
|
|
int m = 1;
|
|
int i = 0;
|
|
|
|
for (; i < sizeof(word) << 3; i++, m <<= 1)
|
|
{
|
|
if (t & m)
|
|
{
|
|
return i + 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|