diff options
Diffstat (limited to 'nxcompext/Pgn.c')
-rw-r--r-- | nxcompext/Pgn.c | 730 |
1 files changed, 0 insertions, 730 deletions
diff --git a/nxcompext/Pgn.c b/nxcompext/Pgn.c deleted file mode 100644 index 3099a248c..000000000 --- a/nxcompext/Pgn.c +++ /dev/null @@ -1,730 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */ -/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */ -/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */ -/* Copyright (c) 2011-2016 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 <stdlib.h> -#include <string.h> - -#include "Xutil.h" - -#include "NXlib.h" - -#include "Mask.h" -#include "Pgn.h" - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -/* - * Selected ZLIB compression level. - */ - -#define PNG_Z_LEVEL 4 - -/* - * Local function prototypes. - */ - -static void PrepareRowForPng(CARD8 *dst, int y, int count); -static void PrepareRowForPng24(CARD8 *dst, int y, int count); -static void PrepareRowForPng16(CARD8 *dst, int y, int count); -static void PrepareRowForPng32(CARD8 *dst, int y, int count); - -static void PngWriteData(png_structp png_ptr, png_bytep data, png_size_t length); -static void PngFlushData(png_structp png_ptr); - -/* - * Image characteristics. - */ - -static int bytesPerLine; -static int byteOrder; - -static CARD8 bitsPerPixel; -static CARD16 redMax, greenMax, blueMax; -static CARD8 redShift, greenShift, blueShift; - -/* - * Other variables used for the Png - * encoding. - */ - -png_byte color_type; -png_structp png_ptr; -png_infop info_ptr; -png_colorp palette; -static char *pngCompBuf; -static int pngDataLen; -static char *pngBeforeBuf = NULL; - -/* - * Allocate data for the compressed image. - * We need to ensure that there is enough - * space to include the palette and the - * header. - */ - -#define PNG_DEST_SIZE(width, height) ((width) * 3 * (height) + 1024 + 256) - -/* - * Just for debug purposes. - */ - -#ifdef DEBUG - -static int pngId; -static char pngName[10]; -static FILE *pngFile; - -#endif - -int PngCompareColorTable(NXColorTable *c1, NXColorTable *c2) -{ - return (c1 -> pixel - c2 -> pixel); -} - -#define NB_COLOR_MAX 256 - -int NXCreatePalette32(XImage *src_image, NXColorTable *color_table, CARD8 *image_index, int nb_max) -{ - int x, y, t, p; - CARD8 *fbptr; - CARD32 pixel; - - fbptr = (CARD8 *) (src_image -> data); - - /* - * TODO: Find a more intelligent way to - * estimate the number of colors. - */ - - memset(color_table, 0, nb_max * sizeof(NXColorTable)); - - for (x = 0, p = 0; x < src_image -> height; x++) - { - for (y = 0; y < src_image -> width; y++) - { - if (byteOrder == LSBFirst) - { - pixel = (CARD32) *(fbptr + 3); - pixel = (pixel << 8) | (CARD32) *(fbptr + 2); - pixel = (pixel << 8) | (CARD32) *(fbptr + 1); - pixel = (pixel << 8) | (CARD32) *fbptr; - } - else - { - pixel = (CARD32) *fbptr; - pixel = (pixel << 8) | (CARD32) *(fbptr + 1); - pixel = (pixel << 8) | (CARD32) *(fbptr + 2); - pixel = (pixel << 8) | (CARD32) *(fbptr + 3); - } - - fbptr += 4; - - for (t = 0; t < nb_max; t++) - { - if (color_table[t].found == 0) - { - color_table[t].pixel = pixel; - color_table[t].found = 1; - p++; - image_index[((x * src_image -> width) + y)] = t; - - break; - } - else if ((CARD32)(color_table[t].pixel) == pixel) - { - image_index[((x * src_image -> width) + y)] = t; - - break; - } - } - - if (p == nb_max) - { - return nb_max + 1; - } - } - } - return p; -} - -int NXCreatePalette16(XImage *src_image, NXColorTable *color_table, CARD8 *image_index, int nb_max) -{ - int x, y, t, p; - CARD8 *fbptr; - CARD16 pixel; - - fbptr = (CARD8 *) (src_image -> data); - - /* - * TODO: Find a more intelligent way to - * estimate the number of colors. - */ - - memset(color_table, 0, nb_max * sizeof(NXColorTable)); - - for (x = 0, p = 0; x < src_image -> height; x++) - { - for (y = 0; y < src_image -> width; y++) - { - if (byteOrder == LSBFirst) - { - pixel = (CARD16) *(fbptr + 1); - pixel = (pixel << 8) | (CARD16) *fbptr; - } - else - { - pixel = (CARD16) *fbptr; - pixel = (pixel << 8) | (CARD16) *(fbptr + 1); - } - - fbptr += 2; - - for (t = 0; t < nb_max; t++) - { - if (color_table[t].found == 0) - { - color_table[t].pixel = pixel; - color_table[t].found = 1; - p++; - image_index[((x * src_image -> width) + y)] = t; - - break; - } - else if ((color_table[t].pixel) == pixel) - { - image_index[((x * src_image -> width) + y)] = t; - - break; - } - } - - /* - * In case the number of 16bit words is not even - * we have 2 padding bytes that we have to skip. - */ - - if ((y == src_image -> width - 1) && (src_image -> width % 2 == 1)) fbptr += 2; - - if (p == nb_max) - { - return nb_max + 1; - } - } - } - - return p; -} - -char *PngCompressData(XImage *image, int *compressed_size) -{ - unsigned int num = 0; - CARD8 *srcBuf; - - int dy, w, h; - - int nb_colors; - - NXColorTable color_table[NB_COLOR_MAX]; - CARD8 *image_index; - - image_index = (CARD8 *) malloc((image -> height) * (image -> width) * sizeof(CARD8)); - - /* - * TODO: Be sure the padded bytes are cleaned. - * It would be better to set to zero the bytes - * that are not alligned to the word boundary - * at the end of the procedure. - */ - - memset(image_index, 0, (image -> height) * (image -> width) * sizeof(CARD8)); - - *compressed_size = 0; - - pngDataLen = 0; - - /* - * Initialize the image stuff. - */ - - bitsPerPixel = image -> bits_per_pixel; - bytesPerLine = image -> bytes_per_line; - byteOrder = image -> byte_order; - - if (bitsPerPixel < 15) - { - #ifdef PANIC - fprintf(stderr, "******PngCompressData: PANIC! Can't compress images with [%d] bits per pixel.\n", - bitsPerPixel); - #endif - - return NULL; - } - - redShift = FindLSB(image -> red_mask) - 1; - greenShift = FindLSB(image -> green_mask) - 1; - blueShift = FindLSB(image -> blue_mask) - 1; - - redMax = image -> red_mask >> redShift; - greenMax = image -> green_mask >> greenShift; - blueMax = image -> blue_mask >> blueShift; - - w = image -> width; - h = image -> height; - pngBeforeBuf = image -> data; - - #ifdef DEBUG - fprintf(stderr, "******PngCompressData: Compressing image with width [%d] height [%d].\n", - w, h ); - #endif - - /* - * Initialize the PNG stuff. - */ - - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - - if (png_ptr == NULL) - { - #ifdef PANIC - fprintf(stderr, "******PngCompressData: PANIC! Failed creating the png_create_write_struct.\n"); - #endif - - return NULL; - } - - info_ptr = png_create_info_struct(png_ptr); - - if (info_ptr == NULL) - { - #ifdef PANIC - fprintf(stderr, "******PngCompressData: PANIC! Failed creating the png_create_info_struct.\n"); - #endif - - png_destroy_write_struct(&png_ptr, NULL); - - return NULL; - } - - if (setjmp(png_jmpbuf(png_ptr))) - { - #ifdef PANIC - fprintf(stderr, "******PngCompressData: PANIC! Error during compression initialization.\n"); - #endif - - png_destroy_write_struct(&png_ptr, &info_ptr); - - return NULL; - } - - /* - * Be sure we allocate enough data. - */ - - #ifdef TEST - fprintf(stderr, "******PngCompressData: Allocating [%d] bytes for the destination data.\n", - PNG_DEST_SIZE(w, h)); - #endif - - pngCompBuf = malloc(PNG_DEST_SIZE(w, h)); - - if (pngCompBuf == NULL) - { - #ifdef PANIC - fprintf(stderr, "******PngCompressData: PANIC! Error allocating [%d] bytes for the Png data.\n", - PNG_DEST_SIZE(w, h)); - #endif - - return NULL; - } - - png_set_write_fn(png_ptr, (void *) pngCompBuf, PngWriteData, PngFlushData); - - if (setjmp(png_jmpbuf(png_ptr))) - { - #ifdef PANIC - fprintf(stderr, "******PngCompressData: PANIC! Error writing the header.\n"); - #endif - - png_destroy_write_struct(&png_ptr, &info_ptr); - - free(pngCompBuf); - - return NULL; - } - - png_set_compression_level(png_ptr, PNG_Z_LEVEL); - - if (bitsPerPixel == 16) - { - nb_colors = NXCreatePalette16(image, color_table, image_index, NB_COLOR_MAX); - } - else - { - nb_colors = NXCreatePalette32(image, color_table, image_index, NB_COLOR_MAX); - } - - if (nb_colors <= NB_COLOR_MAX) - { - color_type = PNG_COLOR_TYPE_PALETTE; - } - else - { - color_type = PNG_COLOR_TYPE_RGB; - } - - png_set_IHDR(png_ptr, info_ptr, w, h, - 8, color_type, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - if (color_type == PNG_COLOR_TYPE_PALETTE) - { - palette = png_malloc(png_ptr, sizeof(*palette) * 256); - - /* - * TODO: Do we need to clean these bytes? - * - * memset(palette, 0, sizeof(*palette) * 256); - */ - - for (num = 0; num < 256 && color_table[num].found != 0; num++) - { - if (bitsPerPixel == 24) - { - palette[num].red = (color_table[num].pixel >> redShift) & redMax; - palette[num].green = (color_table[num].pixel >> greenShift) & greenMax; - palette[num].blue = color_table[num].pixel >> blueShift & blueMax; - } - else - { - int inRed, inGreen, inBlue; - - inRed = (color_table[num].pixel >> redShift) & redMax; - inGreen = (color_table[num].pixel >> greenShift) & greenMax; - inBlue = color_table[num].pixel >> blueShift & blueMax; - - palette[num].red = (CARD8)((inRed * 255 + redMax / 2) / redMax); - palette[num].green = (CARD8)((inGreen * 255 + greenMax / 2) / greenMax); - palette[num].blue = (CARD8)((inBlue * 255 + blueMax / 2) / blueMax); - } - - #ifdef DEBUG - fprintf(stderr, "******PngCompressData: pixel[%d] r[%d] g[%d] b[%d].\n", - (int) color_table[num].pixel,palette[num].red,palette[num].green,palette[num].blue); - #endif - } - - png_set_PLTE(png_ptr, info_ptr, palette, num); - - #ifdef DEBUG - fprintf(stderr, "******PngCompressedData: Setting palette.\n"); - #endif - } - - /* - * End of palette. - */ - - png_write_info(png_ptr, info_ptr); - - /* - * Allocate space for one line of - * the image, 3 bytes per pixel. - */ - - #ifdef DEBUG - fprintf(stderr, "******PngCompressedData: Initialization finished.\n"); - #endif - - if (setjmp(png_jmpbuf(png_ptr))) - { - #ifdef PANIC - fprintf(stderr, "******PngCompressData: PANIC! Error while writing the image rows.\n"); - #endif - - png_destroy_write_struct(&png_ptr, &info_ptr); - - free(pngCompBuf); - - return NULL; - } - - if (color_type == PNG_COLOR_TYPE_PALETTE) - { - srcBuf = (CARD8 *) malloc(w * sizeof(CARD8)); - - if (srcBuf == NULL) - { - #ifdef PANIC - fprintf(stderr, "******PngCompressData: PANIC! Cannot allocate [%d] bytes.\n", - (int) (w * sizeof(CARD8))); - #endif - - return NULL; - } - - /* - * TODO: Be sure the padded bytes are cleaned. - * It would be better to set to zero the bytes - * that are not alligned to the word boundary - * at the end of the procedure. - */ - - memset(srcBuf, 0, w * sizeof(CARD8)); - } - else - { - srcBuf = (CARD8 *) malloc(w * 3 * sizeof(CARD8)); - - /* - * TODO: See above. - */ - - memset(srcBuf, 0, w * 3 * sizeof(CARD8)); - } - - if (srcBuf == NULL) - { - #ifdef PANIC - fprintf(stderr, "******PngCompressData: PANIC! Cannot allocate [%d] bytes.\n", - w * 3); - #endif - - free(pngCompBuf); - - return NULL; - } - - for (dy = 0; dy < h; dy++) - { - if (color_type == PNG_COLOR_TYPE_RGB) - { - PrepareRowForPng(srcBuf, dy, w); - } - else - { - memcpy(srcBuf, image_index + (dy * w), w); - } - - png_write_row(png_ptr, srcBuf); - } - - #ifdef DEBUG - fprintf(stderr, "******PngCompressedData: Compression finished. Lines handled [%d,%d].\n", - dy, h); - #endif - - free(srcBuf); - free(image_index); - - if (setjmp(png_jmpbuf(png_ptr))) - { - #ifdef PANIC - fprintf(stderr, "******PngCompressData: PANIC! error during end of write.\n"); - #endif - - png_destroy_write_struct(&png_ptr, &info_ptr); - - free(pngCompBuf); - - return NULL; - } - - png_write_end(png_ptr, NULL); - - if (color_type == PNG_COLOR_TYPE_PALETTE) - { - png_free(png_ptr, palette); - } - - png_destroy_write_struct(&png_ptr, &info_ptr); - - /* - * Check the size of the resulting data. - */ - - if (pngDataLen > 0) - { - #ifdef DEBUG - - int i = 0; - - fprintf(stderr, "******PngCompressedData: Compressed size [%d].\n", - pngDataLen); - - pngId++; - sprintf(pngName, "png%d", pngId); - pngFile = fopen(pngName, "w"); - - for (i = 0; i < pngDataLen; i++) - { - fprintf(pngFile, "%c", *(pngCompBuf + i)); - } - - fclose(pngFile); - - #endif - - *compressed_size = pngDataLen; - - return pngCompBuf; - } - else - { - #ifdef DEBUG - fprintf(stderr, "******PngCompressedData: PANIC! Invalid size of the compressed data [%d].\n", - pngDataLen); - #endif - - free(pngCompBuf); - - return NULL; - } -} - -static void PngWriteData(png_structp png_ptr, png_bytep data, png_size_t length) -{ - memcpy(((char *) png_get_io_ptr(png_ptr) + pngDataLen), data, length); - - pngDataLen += length; -} - -static void PngFlushData(png_structp png_ptr) -{ -} - -void PrepareRowForPng(CARD8 *dst, int y, int count) -{ - if (bitsPerPixel == 32) - { - if (redMax == 0xff && - greenMax == 0xff && - blueMax == 0xff) - { - PrepareRowForPng24(dst, y, count); - } - else - { - PrepareRowForPng32(dst, y, count); - } - } - else if (bitsPerPixel == 24) - { - memcpy(dst, pngBeforeBuf + y * bytesPerLine, count * 3); - } - else - { - /* - * 16 bpp assumed. - */ - - PrepareRowForPng16(dst, y, count); - } -} - - - -void PrepareRowForPng24(CARD8 *dst, int y, int count) -{ - CARD8 *fbptr; - CARD32 pix; - - fbptr = (CARD8 *) (pngBeforeBuf + y * bytesPerLine); - - while (count--) - { - if (byteOrder == LSBFirst) - { - pix = (CARD32) *(fbptr + 2); - pix = (pix << 8) | (CARD32) *(fbptr+1); - pix = (pix << 8) | (CARD32) *fbptr; - } - else - { - pix = (CARD32) *(fbptr + 1); - pix = (pix << 8) | (CARD32) *(fbptr + 2); - pix = (pix << 8) | (CARD32) *(fbptr + 3); - } - - *dst++ = (CARD8)(pix >> redShift); - *dst++ = (CARD8)(pix >> greenShift); - *dst++ = (CARD8)(pix >> blueShift); - - fbptr+=4; - } -} - -#define DEFINE_PNG_GET_ROW_FUNCTION(bpp) \ - \ -void PrepareRowForPng##bpp(CARD8 *dst, int y, int count) \ -{ \ - CARD8 *fbptr; \ - CARD##bpp pix; \ - int inRed, inGreen, inBlue; \ - int i; \ - \ - fbptr = (CARD8 *) (pngBeforeBuf + y * bytesPerLine); \ - \ - while (count--) \ - { \ - pix = 0; \ - \ - if (byteOrder == LSBFirst) \ - { \ - for (i = (bpp >> 3) - 1; i >= 0; i--) \ - { \ - pix = (pix << 8) | (CARD32) *(fbptr + i); \ - } \ - } \ - else \ - { \ - for (i = 0; i < (bpp >> 3); i++) \ - { \ - pix = (pix << 8) | (CARD32) *(fbptr + i); \ - } \ - } \ - \ - fbptr += (bpp >> 3); \ - \ - inRed = (int) \ - (pix >> redShift & redMax); \ - inGreen = (int) \ - (pix >> greenShift & greenMax); \ - inBlue = (int) \ - (pix >> blueShift & blueMax); \ - *dst++ = (CARD8)((inRed * 255 + redMax / 2) / \ - redMax); \ - *dst++ = (CARD8)((inGreen * 255 + greenMax / 2) / \ - greenMax); \ - *dst++ = (CARD8)((inBlue * 255 + blueMax / 2) / \ - blueMax); \ - } \ -} - -DEFINE_PNG_GET_ROW_FUNCTION(16) -DEFINE_PNG_GET_ROW_FUNCTION(32) |