342 lines
8.6 KiB
C
342 lines
8.6 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 <signal.h>
|
|
|
|
#include "os.h"
|
|
|
|
#include "Compext.h"
|
|
|
|
#include "Clean.h"
|
|
|
|
#define PANIC
|
|
#define WARNING
|
|
#undef TEST
|
|
#undef DEBUG
|
|
|
|
int CleanXYImage(XImage *image)
|
|
{
|
|
int i, j, k, plane;
|
|
|
|
int bitsToClean = (image -> bytes_per_line << 3) - image -> width - image -> xoffset;
|
|
|
|
unsigned int bytesToClean = bitsToClean >> 3;
|
|
|
|
bitsToClean &= 7;
|
|
|
|
for (k = 0; k < image -> depth; k++)
|
|
{
|
|
plane = k * (image -> bytes_per_line * image -> height);
|
|
|
|
for (i = 1; i <= image -> height; i++)
|
|
{
|
|
if (image -> byte_order == image -> bitmap_bit_order)
|
|
{
|
|
for (j = 1; j <= bytesToClean; j++)
|
|
{
|
|
image -> data[plane + i * (image -> bytes_per_line) - j] = 0x00;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (j = bytesToClean; j >= 1; j--)
|
|
{
|
|
image -> data[plane + i * (image -> bytes_per_line) - j] = 0x00;
|
|
}
|
|
}
|
|
|
|
if (image -> bitmap_bit_order == MSBFirst)
|
|
{
|
|
image -> data[plane + i * (image -> bytes_per_line) - j] &= 0xff << bitsToClean;
|
|
}
|
|
else
|
|
{
|
|
image -> data[plane + i * (image -> bytes_per_line) - j] &= 0xff >> bitsToClean;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int CleanZImage(XImage *image)
|
|
{
|
|
unsigned int bytesToClean;
|
|
unsigned int imageLength;
|
|
|
|
#ifdef TEST
|
|
fprintf(stderr, "*****CleanZImage: Going to clean image of [%d] bits per pixel.\n",
|
|
image -> bits_per_pixel);
|
|
#endif
|
|
|
|
switch (image -> bits_per_pixel)
|
|
{
|
|
case 32:
|
|
{
|
|
/*
|
|
* The caller should pay attention at extracting
|
|
* the alpha channel prior to cleaning the image.
|
|
* Cleaning an image which is carrying the alpha
|
|
* channel will result in the image being treated
|
|
* as fully transparent.
|
|
*/
|
|
|
|
bytesToClean = image -> bytes_per_line * image -> height;
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "*****CleanZImage: Cleaning [%d] bytes with bits per pixel [%d] "
|
|
"width [%d] bytes per line [%d] height [%d].\n", bytesToClean,
|
|
image -> bits_per_pixel, image -> width, image ->
|
|
bytes_per_line, image -> height);
|
|
#endif
|
|
|
|
if (image -> byte_order == LSBFirst)
|
|
{
|
|
for (int i = 3; i < bytesToClean; i += 4)
|
|
{
|
|
((unsigned char *) image -> data)[i] = 0x00;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < bytesToClean; i += 4)
|
|
{
|
|
((unsigned char *) image -> data)[i] = 0x00;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case 24:
|
|
case 15:
|
|
case 16:
|
|
case 8:
|
|
{
|
|
bytesToClean = image -> bytes_per_line -
|
|
((image -> width * image -> bits_per_pixel) >> 3);
|
|
|
|
for (int i = 1; i <= image -> height; i++)
|
|
{
|
|
for (int j = bytesToClean; j > 0; j--)
|
|
{
|
|
((unsigned char *) image -> data)[(i * image -> bytes_per_line) - j] = 0x00;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
#ifdef PANIC
|
|
fprintf(stderr, "*****CleanZImage: PANIC! Cannot clean image with [%d] bits per pixel.\n",
|
|
image -> bits_per_pixel);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Clean the padding bytes at the real
|
|
* end of the buffer.
|
|
*/
|
|
|
|
imageLength = image -> bytes_per_line * image -> height;
|
|
|
|
bytesToClean = imageLength % 4;
|
|
|
|
for (int j = 0; j < bytesToClean; j++)
|
|
{
|
|
((unsigned char *)image -> data)[(imageLength + j)] = 0x00;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* Copy a clean version of src_image into dst_image.
|
|
* This code is not taking care of the image format.
|
|
* The agent doesn't use it and you have to consider
|
|
* it unsupported.
|
|
*/
|
|
|
|
int CopyAndCleanImage(XImage *src_image, XImage *dst_image)
|
|
{
|
|
register long data_size;
|
|
|
|
data_size = (src_image -> bytes_per_line * src_image -> height) >> 2;
|
|
|
|
#ifdef WARNING
|
|
fprintf(stderr, "******CleanImage: WARNING! Function called with image of [%d] bits per pixel.\n",
|
|
src_image -> bits_per_pixel);
|
|
#endif
|
|
|
|
switch (src_image -> bits_per_pixel)
|
|
{
|
|
case 32:
|
|
{
|
|
unsigned int mask;
|
|
|
|
if (src_image -> byte_order == MSBFirst)
|
|
{
|
|
mask = 0xffffff00;
|
|
}
|
|
else
|
|
{
|
|
mask = 0x00ffffff;
|
|
}
|
|
for (int i = 0; i < data_size; i++)
|
|
{
|
|
((unsigned int *)dst_image -> data)[i] = ((unsigned int *)src_image -> data)[i] & mask;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 24:
|
|
{
|
|
unsigned int bytes_to_clean;
|
|
|
|
for (int i = 0; i < data_size; i++)
|
|
{
|
|
((unsigned int *)dst_image -> data)[i] = ((unsigned int *)src_image -> data)[i];
|
|
}
|
|
|
|
bytes_to_clean = dst_image -> bytes_per_line - ((dst_image -> width *
|
|
dst_image -> bits_per_pixel) >> 3);
|
|
|
|
if (bytes_to_clean)
|
|
{
|
|
register unsigned int mask = 0xffffffff;
|
|
register int line_size;
|
|
|
|
line_size = dst_image -> bytes_per_line >> 2;
|
|
|
|
if (dst_image -> byte_order == MSBFirst)
|
|
{
|
|
mask = mask << (bytes_to_clean << 3);
|
|
}
|
|
else
|
|
{
|
|
mask = mask >> (bytes_to_clean << 3);
|
|
}
|
|
|
|
for (int i = 0; i < dst_image -> height;)
|
|
{
|
|
((unsigned char *)dst_image -> data)[(++i * line_size) -1] &= mask;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 15:
|
|
case 16:
|
|
{
|
|
for (int i = 0; i < data_size; i++)
|
|
{
|
|
((unsigned int *) dst_image -> data)[i] = ((unsigned int *) src_image -> data)[i];
|
|
}
|
|
|
|
if (src_image -> width & 0x00000001)
|
|
{
|
|
int card32_per_line = dst_image -> bytes_per_line >> 2;
|
|
|
|
for (int i = 0; i < dst_image -> height;)
|
|
{
|
|
((unsigned int *) dst_image -> data)[(++i * card32_per_line) -1] &= 0x0000ffff;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 8:
|
|
{
|
|
unsigned int mask = 0x00000000;
|
|
|
|
switch (dst_image -> width % 4)
|
|
{
|
|
case 3:
|
|
{
|
|
mask = 0x00ffffff;
|
|
|
|
break;
|
|
}
|
|
case 2:
|
|
{
|
|
mask = 0x0000ffff;
|
|
|
|
break;
|
|
}
|
|
case 1:
|
|
{
|
|
mask = 0x000000ff;
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
/*
|
|
* Nothing to clean.
|
|
*/
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < data_size; i++)
|
|
{
|
|
((unsigned int *) dst_image -> data)[i] = ((unsigned int *) src_image -> data)[i];
|
|
}
|
|
|
|
if (mask)
|
|
{
|
|
int card32_per_line;
|
|
|
|
card32_per_line = dst_image -> bytes_per_line >> 2;
|
|
|
|
for (int i = 0; i < dst_image -> height; i++)
|
|
{
|
|
((unsigned int *) dst_image -> data)[(++i * card32_per_line) -1] &= mask;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
#ifdef PANIC
|
|
fprintf(stderr, "******CleanImage: PANIC! Cannot clean image of [%d] bits per pixel.\n",
|
|
src_image -> bits_per_pixel);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|