/**************************************************************************/ /* */ /* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ /* Copyright (c) 2008-2014 Oleksandr Shneyder */ /* Copyright (c) 2014-2016 Ulrich Sibiller */ /* Copyright (c) 2014-2016 Mihai Moldovan */ /* Copyright (c) 2011-2016 Mike Gabriel */ /* 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 #include #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; }