New upstream version 3.5.99.27
This commit is contained in:
50
nx-X11/programs/Xserver/hw/nxagent/compext/Alpha.c
Normal file
50
nx-X11/programs/Xserver/hw/nxagent/compext/Alpha.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 <zlib.h>
|
||||
|
||||
#include "Compext.h"
|
||||
|
||||
#include "Alpha.h"
|
||||
#include "Z.h"
|
||||
|
||||
#define PANIC
|
||||
#define WARNING
|
||||
#undef TEST
|
||||
#undef DEBUG
|
||||
|
||||
#define ALPHA_COMPRESSION_LEVEL 1
|
||||
#define ALPHA_COMPRESSION_THRESHOLD 32
|
||||
#define ALPHA_COMPRESSION_STRATEGY Z_RLE
|
||||
|
||||
static int alphaCompressionLevel = ALPHA_COMPRESSION_LEVEL;
|
||||
static int alphaCompressionThreshold = ALPHA_COMPRESSION_THRESHOLD;
|
||||
static int alphaCompressionStrategy = ALPHA_COMPRESSION_STRATEGY;
|
||||
|
||||
char *AlphaCompressData(const char *data, unsigned int size, unsigned int *compressed_size)
|
||||
{
|
||||
return ZCompressData(data, size, alphaCompressionThreshold, alphaCompressionLevel,
|
||||
alphaCompressionStrategy, compressed_size);
|
||||
}
|
||||
45
nx-X11/programs/Xserver/hw/nxagent/compext/Alpha.h
Normal file
45
nx-X11/programs/Xserver/hw/nxagent/compext/Alpha.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Alpha_H
|
||||
#define Alpha_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char *AlphaCompressData(
|
||||
#if NeedFunctionPrototypes
|
||||
const char* /* data */,
|
||||
unsigned int /* size */,
|
||||
unsigned int* /* compressed_size */
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* Alpha_H */
|
||||
120
nx-X11/programs/Xserver/hw/nxagent/compext/Bitmap.c
Normal file
120
nx-X11/programs/Xserver/hw/nxagent/compext/Bitmap.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 <stdlib.h>
|
||||
|
||||
#include "Compext.h"
|
||||
|
||||
#include "Bitmap.h"
|
||||
|
||||
#define PANIC
|
||||
#define WARNING
|
||||
#undef TEST
|
||||
#undef DEBUG
|
||||
|
||||
char *BitmapCompressData(XImage *image, unsigned int *size)
|
||||
{
|
||||
if (image -> bits_per_pixel != 32)
|
||||
{
|
||||
#ifdef TEST
|
||||
fprintf(stderr, "******BitmapCompressData: Nothing to do with image of [%d] bpp and size [%d].\n",
|
||||
image -> bits_per_pixel, image -> bytes_per_line * image -> height);
|
||||
#endif
|
||||
|
||||
*size = image -> bytes_per_line * image -> height;
|
||||
|
||||
return image -> data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Remove the 4th byte from the bitmap.
|
||||
*/
|
||||
|
||||
char *data;
|
||||
|
||||
char *next_src;
|
||||
char *next_dst;
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
if (image -> bytes_per_line != 4 * image -> width)
|
||||
{
|
||||
fprintf(stderr, "******BitmapCompressData: PANIC! Image as [%d] bytes per line with expected [%d].\n",
|
||||
image -> bytes_per_line, 4 * image -> width);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
*size = image -> width * image -> height * 3;
|
||||
|
||||
data = malloc(*size);
|
||||
|
||||
if (data == NULL)
|
||||
{
|
||||
#ifdef PANIC
|
||||
fprintf(stderr, "******BitmapCompressData: PANIC! Failed to allocate [%d] bytes for the destination.\n",
|
||||
*size);
|
||||
#endif
|
||||
|
||||
*size = image -> bytes_per_line * image -> height;
|
||||
|
||||
return image -> data;
|
||||
}
|
||||
|
||||
next_src = image -> data;
|
||||
next_dst = data;
|
||||
|
||||
if (image -> byte_order == LSBFirst)
|
||||
{
|
||||
while (next_src < image -> data +
|
||||
image -> bytes_per_line * image -> height)
|
||||
{
|
||||
*next_dst++ = *next_src++;
|
||||
*next_dst++ = *next_src++;
|
||||
*next_dst++ = *next_src++;
|
||||
|
||||
next_src++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (next_src < image -> data +
|
||||
image -> bytes_per_line * image -> height)
|
||||
{
|
||||
next_src++;
|
||||
|
||||
*next_dst++ = *next_src++;
|
||||
*next_dst++ = *next_src++;
|
||||
*next_dst++ = *next_src++;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
44
nx-X11/programs/Xserver/hw/nxagent/compext/Bitmap.h
Normal file
44
nx-X11/programs/Xserver/hw/nxagent/compext/Bitmap.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Bitmap_H
|
||||
#define Bitmap_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char *BitmapCompressData(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage* /* image */,
|
||||
unsigned int* /* compressed_size */
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* Bitmap_H */
|
||||
341
nx-X11/programs/Xserver/hw/nxagent/compext/Clean.c
Normal file
341
nx-X11/programs/Xserver/hw/nxagent/compext/Clean.c
Normal file
@@ -0,0 +1,341 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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;
|
||||
}
|
||||
44
nx-X11/programs/Xserver/hw/nxagent/compext/Clean.h
Normal file
44
nx-X11/programs/Xserver/hw/nxagent/compext/Clean.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Clean_H
|
||||
#define Clean_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <nx-X11/Xlib.h>
|
||||
|
||||
int CleanXYImage(XImage *image);
|
||||
int CleanZImage(XImage *image);
|
||||
|
||||
int CopyAndCleanImage(XImage *src_image, XImage *dst_image);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* Clean_H */
|
||||
50
nx-X11/programs/Xserver/hw/nxagent/compext/Colormap.c
Normal file
50
nx-X11/programs/Xserver/hw/nxagent/compext/Colormap.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 <zlib.h>
|
||||
|
||||
#include "Compext.h"
|
||||
|
||||
#include "Colormap.h"
|
||||
#include "Z.h"
|
||||
|
||||
#define PANIC
|
||||
#define WARNING
|
||||
#undef TEST
|
||||
#undef DEBUG
|
||||
|
||||
#define COLORMAP_COMPRESSION_LEVEL 4
|
||||
#define COLORMAP_COMPRESSION_THRESHOLD 32
|
||||
#define COLORMAP_COMPRESSION_STRATEGY Z_DEFAULT_STRATEGY
|
||||
|
||||
static int colormapCompressionLevel = COLORMAP_COMPRESSION_LEVEL;
|
||||
static int colormapCompressionThreshold = COLORMAP_COMPRESSION_THRESHOLD;
|
||||
static int colormapCompressionStrategy = COLORMAP_COMPRESSION_STRATEGY;
|
||||
|
||||
char *ColormapCompressData(const char *data, unsigned int size, unsigned int *compressed_size)
|
||||
{
|
||||
return ZCompressData(data, size, colormapCompressionThreshold, colormapCompressionLevel,
|
||||
colormapCompressionStrategy, compressed_size);
|
||||
}
|
||||
45
nx-X11/programs/Xserver/hw/nxagent/compext/Colormap.h
Normal file
45
nx-X11/programs/Xserver/hw/nxagent/compext/Colormap.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef ColormapComp_H
|
||||
#define ColormapComp_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char *ColormapCompressData(
|
||||
#if NeedFunctionPrototypes
|
||||
const char* /* data */,
|
||||
unsigned int /* size */,
|
||||
unsigned int* /* compressed_size */
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ColormapComp_H */
|
||||
4789
nx-X11/programs/Xserver/hw/nxagent/compext/Compext.c
Normal file
4789
nx-X11/programs/Xserver/hw/nxagent/compext/Compext.c
Normal file
File diff suppressed because it is too large
Load Diff
917
nx-X11/programs/Xserver/hw/nxagent/compext/Compext.h
Normal file
917
nx-X11/programs/Xserver/hw/nxagent/compext/Compext.h
Normal file
@@ -0,0 +1,917 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef NXlib_H
|
||||
#define NXlib_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xlib.h>
|
||||
|
||||
#include <nx/NX.h>
|
||||
#include <nx/NXpack.h>
|
||||
#include <nx/NXproto.h>
|
||||
#include <nx/NXvars.h>
|
||||
|
||||
/*
|
||||
* Maximum number of supported pack methods.
|
||||
*/
|
||||
|
||||
#define NXNumberOfPackMethods 128
|
||||
|
||||
/*
|
||||
* Assume this as the limit of resources that
|
||||
* can be provided to the split and unpack
|
||||
* requests.
|
||||
*/
|
||||
|
||||
#define NXNumberOfResources 256
|
||||
|
||||
#define NXNoResource 256 + 1
|
||||
#define NXAnyResource 256 + 2
|
||||
|
||||
/*
|
||||
* Initialize the internal structures used by
|
||||
* the library. Should be executed again after
|
||||
* having reopened the display.
|
||||
*/
|
||||
|
||||
extern int NXInitDisplay(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Reset all the internal structures. Should be
|
||||
* executed after closing the display.
|
||||
*/
|
||||
|
||||
extern int NXResetDisplay(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Set the NX display flush policy. The policy can
|
||||
* be either NXFlushDeferred or NXFlushImmediate.
|
||||
*/
|
||||
|
||||
extern int NXSetDisplayPolicy(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
int /* policy */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Set the display output buffer size.
|
||||
*/
|
||||
|
||||
extern int NXSetDisplayBuffer(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
int /* size */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* If set, the Popen() function in the X server
|
||||
* will remove the LD_LIBRARY_PATH variable from
|
||||
* the environment before calling the execl()
|
||||
* function on the child process. The function
|
||||
* returns the previous value.
|
||||
*/
|
||||
|
||||
extern int NXUnsetLibraryPath(
|
||||
#if NeedFunctionPrototypes
|
||||
int /* value */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* If the parameter is true, the Xlib I/O error
|
||||
* handler will return, instead of quitting the
|
||||
* program. The function returns the previous
|
||||
* value.
|
||||
*/
|
||||
|
||||
extern int NXHandleDisplayError(
|
||||
#if NeedFunctionPrototypes
|
||||
int /* value */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Shutdown the display descriptor and force Xlib
|
||||
* to set the I/O error flag.
|
||||
*/
|
||||
|
||||
extern Bool NXForceDisplayError(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Check the value of the XlibDisplayIOError flag.
|
||||
* If not set, try to call the display error hand-
|
||||
* ler to give to the application a chance to see
|
||||
* whether it needs to close the connection.
|
||||
*/
|
||||
|
||||
extern int NXDisplayError(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Query the number of bytes readable from the
|
||||
* display connection.
|
||||
*/
|
||||
|
||||
extern int NXDisplayReadable(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Query the number of the outstanding bytes to
|
||||
* flush to the display connection.
|
||||
*/
|
||||
|
||||
extern int NXDisplayFlushable(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Return a value between 0 and 9 indicating the
|
||||
* congestion level of the NX transport based on
|
||||
* the tokens remaining. A value of 9 means that
|
||||
* the link is congested and no further data can
|
||||
* be sent.
|
||||
*/
|
||||
|
||||
extern int NXDisplayCongestion(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Flush the Xlib display buffer and/or the
|
||||
* outstanding data accumulated by the NX
|
||||
* transport.
|
||||
*/
|
||||
|
||||
extern int NXFlushDisplay(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
int /* what */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Public interfaces used to set the handlers.
|
||||
* They all return the previous handler.
|
||||
*/
|
||||
|
||||
extern NXDisplayErrorPredicate NXSetDisplayErrorPredicate(
|
||||
#if NeedFunctionPrototypes
|
||||
NXDisplayErrorPredicate /* predicate */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Called when the display blocks waiting to read or
|
||||
* write more data.
|
||||
*/
|
||||
|
||||
extern NXDisplayBlockHandler NXSetDisplayBlockHandler(
|
||||
#if NeedFunctionPrototypes
|
||||
NXDisplayBlockHandler /* handler */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Called after more data is written to the display.
|
||||
* When the NX transport is running, data may be queued
|
||||
* until an explicit flush.
|
||||
*/
|
||||
|
||||
extern NXDisplayWriteHandler NXSetDisplayWriteHandler(
|
||||
#if NeedFunctionPrototypes
|
||||
NXDisplayWriteHandler /* handler */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Called after more data is sent to the remote proxy.
|
||||
*
|
||||
* Here the display pointer is passed as the second
|
||||
* parameter to make clear that the function does not
|
||||
* tie the callback to the display, but, similarly to
|
||||
* all the Xlib error handlers, to a global variable
|
||||
* shared by all the Xlib functions. The display
|
||||
* pointer will be passed back by nxcomp at the time
|
||||
* it will call the handler. This is because nxcomp
|
||||
* doesn't have access to the display structure.
|
||||
*/
|
||||
|
||||
extern NXDisplayFlushHandler NXSetDisplayFlushHandler(
|
||||
#if NeedFunctionPrototypes
|
||||
NXDisplayFlushHandler /* handler */,
|
||||
Display* /* display */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Get an arbitrary null terminated buffer to be added
|
||||
* to the NX statistics.
|
||||
*/
|
||||
|
||||
extern NXDisplayStatisticsHandler NXSetDisplayStatisticsHandler(
|
||||
#if NeedFunctionPrototypes
|
||||
NXDisplayStatisticsHandler /* handler */,
|
||||
char ** /* buffer */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Redefine the function called by Xlib in the case of
|
||||
* an out-of-order sequence number received in the X
|
||||
* protocol stream.
|
||||
*/
|
||||
|
||||
extern NXLostSequenceHandler NXSetLostSequenceHandler(
|
||||
#if NeedFunctionPrototypes
|
||||
NXLostSequenceHandler /* handler */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* The agent should get the NX parameters at startup, just after
|
||||
* having opened the display. If the agent is not able to satisfy
|
||||
* the pack method set by user (because a method is not applica-
|
||||
* ble, it is not supported by the remote or it simply requires a
|
||||
* screen depth greater than the depth available), it should fall
|
||||
* back to the nearest method of the same type.
|
||||
*/
|
||||
|
||||
extern Status NXGetControlParameters(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int* /* link_type */,
|
||||
unsigned int* /* local_major */,
|
||||
unsigned int* /* local_minor */,
|
||||
unsigned int* /* local_patch */,
|
||||
unsigned int* /* remote_major */,
|
||||
unsigned int* /* remote_minor */,
|
||||
unsigned int* /* remote_patch */,
|
||||
int* /* frame_timeout */,
|
||||
int* /* ping_timeout */,
|
||||
int* /* split_mode */,
|
||||
int* /* split_size */,
|
||||
unsigned int* /* pack_method */,
|
||||
unsigned int* /* pack_quality */,
|
||||
int* /* data_level */,
|
||||
int* /* stream_level */,
|
||||
int* /* delta_level */,
|
||||
unsigned int* /* load_cache */,
|
||||
unsigned int* /* save_cache */,
|
||||
unsigned int* /* startup_cache */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Which unpack methods are supported by the remote proxy?
|
||||
*/
|
||||
|
||||
extern Status NXGetUnpackParameters(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int* /* entries */,
|
||||
unsigned char[] /* supported_methods */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Query and enable shared memory support on path agent to X
|
||||
* client proxy and X server proxy to real X server. At the
|
||||
* moment only the path proxy to real X server is implemented.
|
||||
* On return flags will say if support has been successfully
|
||||
* activated. Segments will contain the XID associated to the
|
||||
* shared memory blocks. A MIT-SHM compliant protocol is used
|
||||
* between proxy and the real server, while a simplified
|
||||
* version is used between the agent and the client proxy to
|
||||
* accommodate both packed images and plain X bitmaps.
|
||||
*/
|
||||
|
||||
extern Status NXGetShmemParameters(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int* /* enable_client */,
|
||||
unsigned int* /* enable_server */,
|
||||
unsigned int* /* client_segment */,
|
||||
unsigned int* /* server_segment */,
|
||||
unsigned int* /* client_size */,
|
||||
unsigned int* /* server_size */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Get the path to the font server that can be used by the X
|
||||
* server to tunnel the font connections across the NX link.
|
||||
* The path actually represents the TCP port where the proxy
|
||||
* on the NX client side is listening. The agent can tempora-
|
||||
* rily enable the tunneling when it needs a font that is not
|
||||
* available on the client, for example when the session is
|
||||
* migrated from a different X server.
|
||||
*/
|
||||
|
||||
extern Status NXGetFontParameters(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* path_length */,
|
||||
char[] /* path_data */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* This set of functions is used to leverage the image stream-
|
||||
* ing capabilities built in nxcomp. An image can be streamed
|
||||
* by sending a start-split message, followed by the X messages
|
||||
* that will have to be split by the proxy, followed by an end-
|
||||
* split closure. Usually, in the middle of a start-split/end-
|
||||
* split sequence there will be a single PutImage() or PutPack-
|
||||
* edImage(), that, in turn, can generate multiple partial
|
||||
* requests, like a SetUnpackColormap() and SetUnpackAlpha()
|
||||
* that will be later used to decompress the image to its ori-
|
||||
* ginal form. Multiple requests may be also generated because
|
||||
* of the maximum size of a X request being exceeded, so that
|
||||
* Xlib has to divide the single image in multiple sub-image re-
|
||||
* quests. The agent doesn't need to take care of these details
|
||||
* but will rather have to track the result of the split opera-
|
||||
* tion. By monitoring the notify events sent by the proxy, the
|
||||
* agent will have to implement its own strategy to deal with
|
||||
* the resources. For example, it will be able to:
|
||||
*
|
||||
* - Mark a drawable as dirty, if the image was not sent
|
||||
* synchronously, in the main X oputput stream.
|
||||
*
|
||||
* - Choose to commit or discard the original image, at the
|
||||
* time it will be recomposed at the remote side. This may
|
||||
* include all the messages that were part of the split
|
||||
* (the colormap, the alpha channel, etc.)
|
||||
*
|
||||
* - Mark the drawable as clean again, if the image was
|
||||
* committed and the drawable didn't change in the mean-
|
||||
* while.
|
||||
*
|
||||
* At the time the proxy receives the end-split, it reports the
|
||||
* result of the operation to the agent. The agent will be able
|
||||
* to identify the original split operation (the one referenced
|
||||
* in the start-split/end-split sequence) by the small integer
|
||||
* number (0-255) named 'resource' sent in the events.
|
||||
*
|
||||
* One of the following cases may be encountered:
|
||||
*
|
||||
*
|
||||
* NXNoSplitNotify All messages were sent in the main out-
|
||||
* put stream, so that no split actually
|
||||
* took place.
|
||||
*
|
||||
* NXStartSplitNotify One or more messages were split, so,
|
||||
* at discrection of the agent, the client
|
||||
* may be suspended until the transferral
|
||||
* is completed.
|
||||
*
|
||||
* NXCommitSplitNotify One of the requests that made up the
|
||||
* split was recomposed. The agent should
|
||||
* either commit the given request or tell
|
||||
* the proxy to discard it.
|
||||
*
|
||||
* NXEndSplitNotify The split was duly completed. The agent
|
||||
* can restart the client.
|
||||
*
|
||||
* NXEmptySplitNotify No more split operation are pending.
|
||||
* The agent can use this information to
|
||||
* implement specific strategies requiring
|
||||
* that all messages have been recomposed
|
||||
* at the remote end, like updating the
|
||||
* drawables that were not synchronized
|
||||
* because of the lazy encoding.
|
||||
*
|
||||
* The 'mode' field that is sent by the agent in the start-split
|
||||
* request, determines the strategy that the proxy will adopt to
|
||||
* deal with the image. If set to 'eager', the proxy will only
|
||||
* split the messages whose size exceeds the split threshold (the
|
||||
* current threshold can be found in the NXGetControlParameters()
|
||||
* reply). If the mode is set to lazy, the proxy will split any
|
||||
* image that would have generated an actual transfer of the data
|
||||
* part (in practice all images that are not found in the cache).
|
||||
* This second strategy can be leveraged by an agent to further
|
||||
* reduce the bandwidth requirements. For example, by setting the
|
||||
* mode to lazy and by monitoring the result, an agent can easi-
|
||||
* ly verify if the drawable was successfully updated, mark the
|
||||
* drawable if not, and synchronize it at later time.
|
||||
*
|
||||
* See NXproto.h for the definition of the available modes.
|
||||
*/
|
||||
|
||||
extern unsigned int NXAllocSplit(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXStartSplit(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
unsigned int /* mode */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXEndSplit(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXCommitSplit(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
unsigned int /* propagate */,
|
||||
unsigned char /* request */,
|
||||
unsigned int /* position */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXAbortSplit(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXFinishSplit(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXFreeSplit(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXSetExposeParameters(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
int /* expose */,
|
||||
int /* graphics_expose */,
|
||||
int /* no_expose */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXSetCacheParameters(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
int /* enable_cache */,
|
||||
int /* enable_split */,
|
||||
int /* enable_save */,
|
||||
int /* enable_load */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern unsigned int NXAllocUnpack(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXSetUnpackGeometry(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
Visual* /* visual */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXSetUnpackColormap(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
unsigned int /* method */,
|
||||
unsigned int /* entries */,
|
||||
const char* /* data */,
|
||||
unsigned int /* data_length */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXSetUnpackAlpha(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
unsigned int /* method */,
|
||||
unsigned int /* entries */,
|
||||
const char* /* data */,
|
||||
unsigned int /* data_length */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXSetUnpackColormapCompat(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
unsigned int /* entries */,
|
||||
const char* /* data */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXSetUnpackAlphaCompat(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
unsigned int /* entries */,
|
||||
const char* /* data */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXFreeUnpack(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* A packed image is a XImage but with
|
||||
* offset field containing total amount
|
||||
* of packed image data.
|
||||
*/
|
||||
|
||||
typedef XImage NXPackedImage;
|
||||
|
||||
NXPackedImage *NXCreatePackedImage(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
Visual* /* visual */,
|
||||
unsigned int /* method */,
|
||||
unsigned int /* depth */,
|
||||
int /* format */,
|
||||
char* /* data */,
|
||||
int /* data_length */,
|
||||
unsigned int /* width */,
|
||||
unsigned int /* height */,
|
||||
int /* bitmap_pad */,
|
||||
int /* bytes_per_line */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXDestroyPackedImage(
|
||||
#if NeedFunctionPrototypes
|
||||
NXPackedImage* /* image */
|
||||
#endif
|
||||
);
|
||||
|
||||
NXPackedImage *NXPackImage(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
XImage* /* src_image */,
|
||||
unsigned int /* method */
|
||||
#endif
|
||||
);
|
||||
|
||||
NXPackedImage *NXInPlacePackImage(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
XImage* /* src_image */,
|
||||
unsigned int /* method */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* GC is declared void * to get rid of mess
|
||||
* with different GC definitions in some X
|
||||
* server code (like in nxagent).
|
||||
*/
|
||||
|
||||
extern int NXPutPackedImage(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
Drawable /* drawable */,
|
||||
void* /* gc */,
|
||||
NXPackedImage* /* image */,
|
||||
unsigned int /* method */,
|
||||
unsigned int /* depth */,
|
||||
int /* src_x */,
|
||||
int /* src_y */,
|
||||
int /* dst_x */,
|
||||
int /* dst_y */,
|
||||
unsigned int /* width */,
|
||||
unsigned int /* height */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Get multiple colors with a single call by
|
||||
* pipelining X_AllocColor requests/replies.
|
||||
*/
|
||||
|
||||
extern int NXAllocColors(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
Colormap /* colormap */,
|
||||
unsigned int /* entries */,
|
||||
XColor[] /* screens_in_out */,
|
||||
Bool [] /* flags allocation errors */
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Encode the data in the given format.
|
||||
*/
|
||||
|
||||
extern char *NXEncodeColormap(
|
||||
#if NeedFunctionPrototypes
|
||||
const char* /* src_data */,
|
||||
unsigned int /* src_size */,
|
||||
unsigned int* /* dst_size */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern char *NXEncodeAlpha(
|
||||
#if NeedFunctionPrototypes
|
||||
const char* /* src_data */,
|
||||
unsigned int /* src_size */,
|
||||
unsigned int* /* dst_size */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern NXPackedImage *NXEncodeRgb(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage* /* src_image */,
|
||||
unsigned int /* method */,
|
||||
unsigned int /* quality */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern NXPackedImage *NXEncodeRle(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage* /* src_image */,
|
||||
unsigned int /* method */,
|
||||
unsigned int /* quality */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern NXPackedImage *NXEncodeJpeg(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage* /* src_image */,
|
||||
unsigned int /* method */,
|
||||
unsigned int /* quality */
|
||||
#endif
|
||||
);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
long pixel;
|
||||
int found;
|
||||
|
||||
} NXColorTable;
|
||||
|
||||
extern int NXEncodeColors(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage* /* src_image */,
|
||||
NXColorTable* /* color_table */,
|
||||
int /* nb_max */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern NXPackedImage *NXEncodePng(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage* /* src_image */,
|
||||
unsigned int /* method */,
|
||||
unsigned int /* quality */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern NXPackedImage *NXEncodeBitmap(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage* /* src_image */,
|
||||
unsigned int /* method */,
|
||||
unsigned int /* quality */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXCleanImage(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage*
|
||||
#endif
|
||||
);
|
||||
|
||||
extern void NXMaskImage(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage* /* pointer to image to mask */ ,
|
||||
unsigned int /* method */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXImageCacheSize;
|
||||
|
||||
extern void NXInitCache(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
int /* entries in image cache */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern void NXFreeCache(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern XImage *NXCacheFindImage(
|
||||
#if NeedFunctionPrototypes
|
||||
NXPackedImage* /* packed image to find */,
|
||||
unsigned int* /* pointer to the pack method if found */,
|
||||
unsigned char** /* pointer to the calculated MD5 if found */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXCacheAddImage(
|
||||
#if NeedFunctionPrototypes
|
||||
NXPackedImage* /* packed image to be added to the cache */,
|
||||
unsigned int /* pack method of the image to add */,
|
||||
unsigned char* /* pointer to MD5 of the original unpacked image */
|
||||
#endif
|
||||
);
|
||||
|
||||
|
||||
extern int NXGetCollectImageResource(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXCollectImage(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
Drawable /* drawable */,
|
||||
int /* src_x */,
|
||||
int /* src_y */,
|
||||
unsigned int /* width */,
|
||||
unsigned int /* height */,
|
||||
unsigned long /* plane_mask */,
|
||||
int /* format */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXGetCollectedImage(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
XImage** /* image */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXGetCollectPropertyResource(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXCollectProperty(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
Window /* window */,
|
||||
#ifdef XlibAtom
|
||||
XlibAtom /* property */,
|
||||
#else
|
||||
Atom /* property */,
|
||||
#endif
|
||||
long /* long_offset */,
|
||||
long /* long_length */,
|
||||
Bool /* delete */,
|
||||
#ifdef XlibAtom
|
||||
XlibAtom /* req_type */
|
||||
#else
|
||||
Atom /* req_type */
|
||||
#endif
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXGetCollectedProperty(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
#ifdef XlibAtom
|
||||
XlibAtom* /* actual_type_return */,
|
||||
#else
|
||||
Atom* /* actual_type_return */,
|
||||
#endif
|
||||
int* /* actual_format_return */,
|
||||
unsigned long* /* nitems_return */,
|
||||
unsigned long* /* bytes_after_return */,
|
||||
unsigned char** /* data */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXGetCollectGrabPointerResource(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXCollectGrabPointer(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
Window /* grab_window */,
|
||||
Bool /* owner_events */,
|
||||
unsigned int /* event_mask */,
|
||||
int /* pointer_mode */,
|
||||
int /* keyboard_mode */,
|
||||
Window /* confine_to */,
|
||||
Cursor /* cursor */,
|
||||
Time /* time */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXGetCollectedGrabPointer(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
int* /* status */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXGetCollectInputFocusResource(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXCollectInputFocus(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern int NXGetCollectedInputFocus(
|
||||
#if NeedFunctionPrototypes
|
||||
Display* /* display */,
|
||||
unsigned int /* resource */,
|
||||
Window* /* focus_return */,
|
||||
int* /* revert_to_return */
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NXlib_H */
|
||||
49
nx-X11/programs/Xserver/hw/nxagent/compext/Imakefile
Normal file
49
nx-X11/programs/Xserver/hw/nxagent/compext/Imakefile
Normal file
@@ -0,0 +1,49 @@
|
||||
NULL =
|
||||
|
||||
#include <Server.tmpl>
|
||||
|
||||
SRCS = \
|
||||
Alpha.c \
|
||||
Bitmap.c \
|
||||
Clean.c \
|
||||
Colormap.c \
|
||||
Compext.c \
|
||||
Jpeg.c \
|
||||
Mask.c \
|
||||
Png.c \
|
||||
Rgb.c \
|
||||
Rle.c \
|
||||
Z.c \
|
||||
$(NULL)
|
||||
|
||||
OBJS = \
|
||||
Alpha.o \
|
||||
Bitmap.o \
|
||||
Clean.o \
|
||||
Colormap.o \
|
||||
Compext.o \
|
||||
Jpeg.o \
|
||||
Mask.o \
|
||||
Png.o \
|
||||
Rgb.o \
|
||||
Rle.o \
|
||||
Z.o \
|
||||
$(NULL)
|
||||
|
||||
INCLUDES = -I$(SERVERSRC)/include \
|
||||
-I$(XBUILDINCDIR) \
|
||||
-I../../../../../lib/include/X11 \
|
||||
`pkg-config --cflags-only-I pixman-1` \
|
||||
$$(pkg-config --exists 'zlib' >/dev/null 2>&1 && pkg-config --cflags-only-I 'zlib') \
|
||||
`pkg-config --cflags-only-I libpng` \
|
||||
$(NULL)
|
||||
|
||||
LINTLIBS = $(SERVERSRC)/dix/llib-ldix.ln \
|
||||
$(NULL)
|
||||
|
||||
NormalLibraryObjectRule()
|
||||
NormalLibraryTarget(compext,$(OBJS))
|
||||
LintLibraryTarget(compext,$(SRCS))
|
||||
NormalLintTarget($(SRCS))
|
||||
|
||||
DependTarget()
|
||||
482
nx-X11/programs/Xserver/hw/nxagent/compext/Jpeg.c
Normal file
482
nx-X11/programs/Xserver/hw/nxagent/compext/Jpeg.c
Normal file
@@ -0,0 +1,482 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xlib.h>
|
||||
#include <nx-X11/Xmd.h>
|
||||
|
||||
#include <jpeglib.h>
|
||||
|
||||
#include "Compext.h"
|
||||
|
||||
#include "Mask.h"
|
||||
#include "Jpeg.h"
|
||||
|
||||
#include "../Utils.h"
|
||||
|
||||
#define PANIC
|
||||
#define WARNING
|
||||
#undef TEST
|
||||
#undef DEBUG
|
||||
|
||||
#define JPEG_DEST_SIZE(width, height) ((width) * 3 * (height) + 1024)
|
||||
|
||||
/*
|
||||
* Local function prototypes.
|
||||
*/
|
||||
|
||||
static void PrepareRowForJpeg(CARD8 *dst, int y, int count);
|
||||
static void PrepareRowForJpeg24(CARD8 *dst, int y, int count);
|
||||
static void PrepareRowForJpeg16(CARD8 *dst, int y, int count);
|
||||
static void PrepareRowForJpeg32(CARD8 *dst, int y, int count);
|
||||
|
||||
static int JpegEmptyOutputBuffer(j_compress_ptr cinfo);
|
||||
|
||||
static void JpegInitDestination(j_compress_ptr cinfo);
|
||||
static void JpegTermDestination(j_compress_ptr cinfo);
|
||||
static void JpegSetDstManager(j_compress_ptr cinfo);
|
||||
|
||||
/*
|
||||
* Quality levels.
|
||||
*/
|
||||
|
||||
static int jpegQuality[10] = {20, 30, 40, 50, 55, 60, 65, 70, 75, 80};
|
||||
|
||||
/*
|
||||
* Image characteristics.
|
||||
*/
|
||||
|
||||
static int bytesPerLine;
|
||||
|
||||
static CARD8 bitsPerPixel;
|
||||
static CARD16 redMax, greenMax, blueMax;
|
||||
static CARD8 redShift, greenShift, blueShift;
|
||||
static int byteOrder;
|
||||
|
||||
/*
|
||||
* Other variables used for the Jpeg
|
||||
* encoding.
|
||||
*/
|
||||
|
||||
static char *jpegBeforeBuf = NULL;
|
||||
static char *jpegCompBuf;
|
||||
static int jpegCompBufSize;
|
||||
static int jpegError;
|
||||
static int jpegDstDataLen;
|
||||
|
||||
static struct jpeg_destination_mgr jpegDstManager;
|
||||
|
||||
/*
|
||||
* Just for debugging purpose.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
static int jpegId;
|
||||
static char jpegName[10];
|
||||
static FILE *jpegFile;
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Function declarations
|
||||
*/
|
||||
|
||||
char *JpegCompressData(XImage *image, int level, int *compressed_size)
|
||||
{
|
||||
struct jpeg_compress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
|
||||
CARD8 *srcBuf;
|
||||
JSAMPROW rowPointer[1];
|
||||
|
||||
int dy, w, h;
|
||||
|
||||
*compressed_size = 0;
|
||||
|
||||
/*
|
||||
* Initialize the image stuff
|
||||
*/
|
||||
|
||||
bitsPerPixel = image -> bits_per_pixel;
|
||||
bytesPerLine = image -> bytes_per_line;
|
||||
byteOrder = image -> byte_order;
|
||||
|
||||
#ifdef TEST
|
||||
fprintf(stderr, "******JpegCompressData: Image byte order [%d] bitmap bit order [%d].\n",
|
||||
image -> byte_order, image -> bitmap_bit_order);
|
||||
|
||||
fprintf(stderr, "******JpegCompressData: Bits per pixel [%d] bytes per line [%d].\n",
|
||||
bitsPerPixel, bytesPerLine);
|
||||
#endif
|
||||
|
||||
redShift = FindLSB(image -> red_mask) - 1;
|
||||
greenShift = FindLSB(image -> green_mask) - 1;
|
||||
blueShift = FindLSB(image -> blue_mask) - 1;
|
||||
|
||||
#ifdef TEST
|
||||
fprintf(stderr, "******JpegCompressData: Red mask [0x%lx] green mask [0x%lx] blue mask [0x%lx].\n",
|
||||
image -> red_mask, image -> green_mask, image -> blue_mask);
|
||||
|
||||
fprintf(stderr, "******JpegCompressData: Red shift [%d] green shift [%d] blue shift [%d].\n",
|
||||
redShift, greenShift, blueShift);
|
||||
#endif
|
||||
|
||||
redMax = image -> red_mask >> redShift;
|
||||
greenMax = image -> green_mask >> greenShift;
|
||||
blueMax = image -> blue_mask >> blueShift;
|
||||
|
||||
#ifdef TEST
|
||||
fprintf(stderr, "******JpegCompressData: Red max [0x%x] green max [0x%x] blue max [0x%x].\n",
|
||||
redMax, greenMax, blueMax);
|
||||
#endif
|
||||
|
||||
w = image -> width;
|
||||
h = image -> height;
|
||||
|
||||
jpegBeforeBuf = image -> data;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "******JpegCompressData: Width [%d] height [%d] level [%d].\n",
|
||||
w, h, level);
|
||||
#endif
|
||||
|
||||
if (bitsPerPixel == 1 ||
|
||||
bitsPerPixel == 8)
|
||||
{
|
||||
#ifdef PANIC
|
||||
fprintf(stderr, "******JpegCompressData: PANIC! Invalid bits per pixel [%d].\n",
|
||||
bitsPerPixel);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate space for one line of the
|
||||
* resulting image, 3 bytes per pixel.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "******JpegCompressData: Allocating [%d] bytes for the scanline.\n",
|
||||
w * 3);
|
||||
#endif
|
||||
|
||||
srcBuf = (CARD8 *) malloc(w * 3);
|
||||
|
||||
if (srcBuf == NULL)
|
||||
{
|
||||
#ifdef PANIC
|
||||
fprintf(stderr, "******JpegCompressData: PANIC! Cannot allocate [%d] bytes.\n",
|
||||
w * 3);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rowPointer[0] = srcBuf;
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
|
||||
jpeg_create_compress(&cinfo);
|
||||
|
||||
cinfo.image_width = w;
|
||||
cinfo.image_height = h;
|
||||
cinfo.input_components = 3;
|
||||
cinfo.in_color_space = JCS_RGB;
|
||||
|
||||
jpeg_set_defaults(&cinfo);
|
||||
jpeg_set_quality(&cinfo, jpegQuality[level], 1);
|
||||
|
||||
/*
|
||||
* Allocate memory for the destination
|
||||
* buffer.
|
||||
*/
|
||||
|
||||
jpegCompBufSize = JPEG_DEST_SIZE(w, h);
|
||||
|
||||
#ifdef TEST
|
||||
fprintf(stderr, "******JpegCompressData: Allocating [%d] bytes for the destination data.\n",
|
||||
jpegCompBufSize);
|
||||
#endif
|
||||
|
||||
jpegCompBuf = malloc(jpegCompBufSize);
|
||||
|
||||
if (jpegCompBuf == NULL)
|
||||
{
|
||||
#ifdef PANIC
|
||||
fprintf(stderr, "******JpegCompressData: PANIC! Error allocating [%d] bytes for the Jpeg data.\n",
|
||||
jpegCompBufSize);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JpegSetDstManager(&cinfo);
|
||||
|
||||
jpeg_start_compress(&cinfo, 1);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "******JpegCompressedData: Initialization finished.\n");
|
||||
#endif
|
||||
|
||||
for (dy = 0; dy < h; dy++)
|
||||
{
|
||||
PrepareRowForJpeg(srcBuf, dy, w);
|
||||
|
||||
jpeg_write_scanlines(&cinfo, rowPointer, 1);
|
||||
|
||||
if (jpegError != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "******JpegCompressedData: Compression finished. Lines handled [%d,%d]. Error is [%d].\n",
|
||||
dy, h, jpegError);
|
||||
#endif
|
||||
|
||||
if (jpegError == 0)
|
||||
{
|
||||
jpeg_finish_compress(&cinfo);
|
||||
}
|
||||
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
|
||||
free((char *) srcBuf);
|
||||
|
||||
if (jpegError != 0)
|
||||
{
|
||||
#ifdef PANIC
|
||||
fprintf(stderr, "******JpegCompressedData: PANIC! Compression failed. Error is [%d].\n",
|
||||
jpegError);
|
||||
#endif
|
||||
|
||||
SAFE_free(jpegCompBuf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the size of the resulting data.
|
||||
*/
|
||||
|
||||
if (jpegDstDataLen > 0)
|
||||
{
|
||||
/*
|
||||
* Save the image on disk to help with
|
||||
* the debug.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
int i = 0;
|
||||
|
||||
fprintf(stderr, "******JpegCompressedData: Compressed size [%d].\n",
|
||||
jpegDstDataLen);
|
||||
|
||||
jpegId++;
|
||||
|
||||
sprintf(jpegName, "jpeg%d", jpegId);
|
||||
|
||||
jpegFile = fopen(jpegName, "w");
|
||||
|
||||
for (i = 0; i < jpegDstDataLen; i++)
|
||||
{
|
||||
fprintf(jpegFile, "%c", *(jpegCompBuf + i));
|
||||
}
|
||||
|
||||
fclose(jpegFile);
|
||||
|
||||
#endif
|
||||
|
||||
*compressed_size = jpegDstDataLen;
|
||||
|
||||
return jpegCompBuf;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef PANIC
|
||||
fprintf(stderr, "******JpegCompressedData: PANIC! Invalid size of the compressed data [%d].\n",
|
||||
jpegDstDataLen);
|
||||
#endif
|
||||
|
||||
SAFE_free(jpegCompBuf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void PrepareRowForJpeg(CARD8 *dst, int y, int count)
|
||||
{
|
||||
if (bitsPerPixel == 32)
|
||||
{
|
||||
if (redMax == 0xff &&
|
||||
greenMax == 0xff &&
|
||||
blueMax == 0xff)
|
||||
{
|
||||
PrepareRowForJpeg24(dst, y, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrepareRowForJpeg32(dst, y, count);
|
||||
}
|
||||
}
|
||||
else if (bitsPerPixel == 24)
|
||||
{
|
||||
memcpy(dst, jpegBeforeBuf + y * bytesPerLine, count * 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* 16 bpp assumed.
|
||||
*/
|
||||
|
||||
PrepareRowForJpeg16(dst, y, count);
|
||||
}
|
||||
}
|
||||
|
||||
void PrepareRowForJpeg24(CARD8 *dst, int y, int count)
|
||||
{
|
||||
CARD8 *fbptr;
|
||||
CARD32 pix;
|
||||
|
||||
fbptr = (CARD8 *) (jpegBeforeBuf + 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_JPEG_GET_ROW_FUNCTION(bpp) \
|
||||
\
|
||||
void PrepareRowForJpeg##bpp(CARD8 *dst, int y, int count) \
|
||||
{ \
|
||||
CARD8 *fbptr; \
|
||||
CARD##bpp pix; \
|
||||
int inRed, inGreen, inBlue; \
|
||||
int i; \
|
||||
\
|
||||
fbptr = (CARD8 *) (jpegBeforeBuf + 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_JPEG_GET_ROW_FUNCTION(16)
|
||||
DEFINE_JPEG_GET_ROW_FUNCTION(32)
|
||||
|
||||
/*
|
||||
* Destination manager implementation for JPEG library.
|
||||
*/
|
||||
|
||||
void JpegInitDestination(j_compress_ptr cinfo)
|
||||
{
|
||||
jpegError = 0;
|
||||
|
||||
jpegDstManager.next_output_byte = (JOCTET *) jpegCompBuf;
|
||||
jpegDstManager.free_in_buffer = (size_t) jpegCompBufSize;
|
||||
}
|
||||
|
||||
int JpegEmptyOutputBuffer(j_compress_ptr cinfo)
|
||||
{
|
||||
jpegError = 1;
|
||||
|
||||
jpegDstManager.next_output_byte = (JOCTET *) jpegCompBuf;
|
||||
jpegDstManager.free_in_buffer = (size_t) jpegCompBufSize;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void JpegTermDestination(j_compress_ptr cinfo)
|
||||
{
|
||||
jpegDstDataLen = jpegCompBufSize - jpegDstManager.free_in_buffer;
|
||||
}
|
||||
|
||||
void JpegSetDstManager(j_compress_ptr cinfo)
|
||||
{
|
||||
jpegDstManager.init_destination = JpegInitDestination;
|
||||
jpegDstManager.empty_output_buffer = JpegEmptyOutputBuffer;
|
||||
jpegDstManager.term_destination = JpegTermDestination;
|
||||
|
||||
cinfo -> dest = &jpegDstManager;
|
||||
}
|
||||
|
||||
46
nx-X11/programs/Xserver/hw/nxagent/compext/Jpeg.h
Normal file
46
nx-X11/programs/Xserver/hw/nxagent/compext/Jpeg.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Jpeg_H
|
||||
#define Jpeg_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char *JpegCompressData(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage* /* image */,
|
||||
int /* level */,
|
||||
int* /* compressed_size */
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* Jpeg_H */
|
||||
|
||||
802
nx-X11/programs/Xserver/hw/nxagent/compext/Mask.c
Normal file
802
nx-X11/programs/Xserver/hw/nxagent/compext/Mask.c
Normal file
@@ -0,0 +1,802 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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;
|
||||
}
|
||||
|
||||
48
nx-X11/programs/Xserver/hw/nxagent/compext/Mask.h
Normal file
48
nx-X11/programs/Xserver/hw/nxagent/compext/Mask.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Mask_H
|
||||
#define Mask_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "Xlib.h"
|
||||
|
||||
extern int MaskImage(const ColorMask *mask, XImage *src_image, XImage *dst_image);
|
||||
|
||||
extern int MaskInPlaceImage(const ColorMask *mask, XImage *image);
|
||||
|
||||
extern int PackImage(unsigned int method, unsigned int src_data_size, XImage *src_image,
|
||||
unsigned int dst_data_size, XImage *dst_image);
|
||||
|
||||
int FindLSB(int word);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* Mask_H */
|
||||
725
nx-X11/programs/Xserver/hw/nxagent/compext/Png.c
Normal file
725
nx-X11/programs/Xserver/hw/nxagent/compext/Png.c
Normal file
@@ -0,0 +1,725 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nx-X11/Xutil.h>
|
||||
|
||||
#include "Compext.h"
|
||||
|
||||
#include "Mask.h"
|
||||
#include "Png.h"
|
||||
|
||||
#include "../Utils.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;
|
||||
|
||||
*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);
|
||||
SAFE_free(pngCompBuf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image_index = (CARD8 *) calloc(1, (image -> height) * (image -> width) * sizeof(CARD8));
|
||||
if (image_index == NULL)
|
||||
{
|
||||
#ifdef PANIC
|
||||
fprintf(stderr, "******PngCompressData: PANIC! Could not alloc image_index.\n");
|
||||
#endif
|
||||
|
||||
SAFE_free(pngCompBuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Be sure the padded bytes are cleaned.
|
||||
* It would be better to set to zero the bytes
|
||||
* that are not aligned to the word boundary
|
||||
* at the end of the procedure.
|
||||
*/
|
||||
|
||||
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);
|
||||
|
||||
SAFE_free(pngCompBuf);
|
||||
SAFE_free(image_index);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int count;
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
count = w;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 3 * w;
|
||||
}
|
||||
|
||||
srcBuf = (CARD8 *) calloc(count, sizeof(CARD8));
|
||||
|
||||
if (srcBuf == NULL)
|
||||
{
|
||||
#ifdef PANIC
|
||||
fprintf(stderr, "******PngCompressData: PANIC! Cannot allocate [%d] bytes.\n",
|
||||
(int) (count * sizeof(CARD8)));
|
||||
#endif
|
||||
|
||||
SAFE_free(pngCompBuf);
|
||||
SAFE_free(image_index);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Be sure the padded bytes are cleaned.
|
||||
* It would be better to set to zero the bytes
|
||||
* that are not aligned to the word boundary
|
||||
* at the end of the procedure.
|
||||
*/
|
||||
|
||||
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
|
||||
|
||||
SAFE_free(srcBuf);
|
||||
SAFE_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);
|
||||
|
||||
SAFE_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
|
||||
|
||||
SAFE_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)
|
||||
76
nx-X11/programs/Xserver/hw/nxagent/compext/Png.h
Normal file
76
nx-X11/programs/Xserver/hw/nxagent/compext/Png.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Png_H
|
||||
#define Png_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xlib.h>
|
||||
#include <nx-X11/Xmd.h>
|
||||
|
||||
#include <png.h>
|
||||
|
||||
extern int PngCompareColorTable(
|
||||
#if NeedFunctionPrototypes
|
||||
NXColorTable* /* color_table_1 */,
|
||||
NXColorTable* /* color_table_2 */
|
||||
#endif
|
||||
);
|
||||
|
||||
extern char *PngCompressData(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage* /* image */,
|
||||
int* /* compressed_size */
|
||||
#endif
|
||||
);
|
||||
|
||||
int NXCreatePalette16(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage* /* src_image */,
|
||||
NXColorTable* /* color_table */,
|
||||
CARD8* /* image_index */,
|
||||
int /* nb_max */
|
||||
#endif
|
||||
);
|
||||
|
||||
int NXCreatePalette32(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage* /* src_image */,
|
||||
NXColorTable* /* color_table */,
|
||||
CARD8* /* image_index */,
|
||||
int /* nb_max */
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* Png_H */
|
||||
|
||||
51
nx-X11/programs/Xserver/hw/nxagent/compext/Rgb.c
Normal file
51
nx-X11/programs/Xserver/hw/nxagent/compext/Rgb.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 <zlib.h>
|
||||
|
||||
#include "Compext.h"
|
||||
|
||||
#include "Rgb.h"
|
||||
#include "Z.h"
|
||||
|
||||
#define PANIC
|
||||
#define WARNING
|
||||
#undef TEST
|
||||
#undef DEBUG
|
||||
|
||||
#define RGB_COMPRESSION_LEVEL 4
|
||||
#define RGB_COMPRESSION_THRESHOLD 32
|
||||
#define RGB_COMPRESSION_STRATEGY Z_DEFAULT_STRATEGY
|
||||
|
||||
static int rgbCompressionLevel = RGB_COMPRESSION_LEVEL;
|
||||
static int rgbCompressionThreshold = RGB_COMPRESSION_THRESHOLD;
|
||||
static int rgbCompressionStrategy = RGB_COMPRESSION_STRATEGY;
|
||||
|
||||
char *RgbCompressData(XImage *image, unsigned int *size)
|
||||
{
|
||||
return ZCompressData(image -> data, image -> bytes_per_line * image -> height,
|
||||
rgbCompressionThreshold, rgbCompressionLevel,
|
||||
rgbCompressionStrategy, size);
|
||||
}
|
||||
44
nx-X11/programs/Xserver/hw/nxagent/compext/Rgb.h
Normal file
44
nx-X11/programs/Xserver/hw/nxagent/compext/Rgb.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Rgb_H
|
||||
#define Rgb_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char *RgbCompressData(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage* /* image */,
|
||||
unsigned int* /* compressed_size */
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* Rgb_H */
|
||||
51
nx-X11/programs/Xserver/hw/nxagent/compext/Rle.c
Normal file
51
nx-X11/programs/Xserver/hw/nxagent/compext/Rle.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 <zlib.h>
|
||||
|
||||
#include "Compext.h"
|
||||
|
||||
#include "Rle.h"
|
||||
#include "Z.h"
|
||||
|
||||
#define PANIC
|
||||
#define WARNING
|
||||
#undef TEST
|
||||
#undef DEBUG
|
||||
|
||||
#define RLE_COMPRESSION_LEVEL 1
|
||||
#define RLE_COMPRESSION_THRESHOLD 32
|
||||
#define RLE_COMPRESSION_STRATEGY Z_RLE
|
||||
|
||||
static int rleCompressionLevel = RLE_COMPRESSION_LEVEL;
|
||||
static int rleCompressionThreshold = RLE_COMPRESSION_THRESHOLD;
|
||||
static int rleCompressionStrategy = RLE_COMPRESSION_STRATEGY;
|
||||
|
||||
char *RleCompressData(XImage *image, unsigned int *size)
|
||||
{
|
||||
return ZCompressData(image -> data, image -> bytes_per_line * image -> height,
|
||||
rleCompressionThreshold, rleCompressionLevel,
|
||||
rleCompressionStrategy, size);
|
||||
}
|
||||
44
nx-X11/programs/Xserver/hw/nxagent/compext/Rle.h
Normal file
44
nx-X11/programs/Xserver/hw/nxagent/compext/Rle.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Rle_H
|
||||
#define Rle_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char *RleCompressData(
|
||||
#if NeedFunctionPrototypes
|
||||
XImage* /* image */,
|
||||
unsigned int* /* compressed_size */
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* Rle_H */
|
||||
311
nx-X11/programs/Xserver/hw/nxagent/compext/Z.c
Normal file
311
nx-X11/programs/Xserver/hw/nxagent/compext/Z.c
Normal file
@@ -0,0 +1,311 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#include "Compext.h"
|
||||
|
||||
#include "Z.h"
|
||||
|
||||
#include "../Utils.h"
|
||||
|
||||
#define PANIC
|
||||
#define WARNING
|
||||
#undef TEST
|
||||
#undef DEBUG
|
||||
|
||||
#define Z_COMPRESSION_LEVEL 4
|
||||
#define Z_COMPRESSION_THRESHOLD 32
|
||||
#define Z_COMPRESSION_STRATEGY Z_DEFAULT_STRATEGY
|
||||
|
||||
static int zCompressionLevel = Z_COMPRESSION_LEVEL;
|
||||
static int zCompressionStrategy = Z_COMPRESSION_STRATEGY;
|
||||
|
||||
static z_stream *zStream;
|
||||
|
||||
static int zInitialized;
|
||||
|
||||
static int ZConfigure(int level, int strategy);
|
||||
|
||||
static int ZDeflate(char *dest, unsigned int *destLen,
|
||||
const char *source, unsigned int sourceLen);
|
||||
|
||||
char *ZCompressData(const char *plainData, unsigned int plainSize, int threshold,
|
||||
int level, int strategy, unsigned int *compressedSize)
|
||||
{
|
||||
char *compressedData;
|
||||
|
||||
/*
|
||||
* Determine the size of the source image
|
||||
* data and make sure there is enough
|
||||
* space in the destination buffer.
|
||||
*/
|
||||
|
||||
*compressedSize = plainSize + (plainSize / 1000) + 12 + 1;
|
||||
|
||||
compressedData = malloc(*compressedSize);
|
||||
|
||||
if (compressedData == NULL)
|
||||
{
|
||||
#ifdef PANIC
|
||||
fprintf(stderr, "******ZCompressData: PANIC! Failed to allocate [%d] bytes for the destination.\n",
|
||||
*compressedSize);
|
||||
#endif
|
||||
|
||||
*compressedSize = 0;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (level == Z_NO_COMPRESSION || plainSize < threshold)
|
||||
{
|
||||
#ifdef TEST
|
||||
fprintf(stderr, "******ZCompressData: Not compressing [%d] bytes with level [%d] and "
|
||||
"threshold [%d].\n", plainSize, level, threshold);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Tell in the first byte of the buffer
|
||||
* if the remaining data is compressed
|
||||
* or not. This same byte can be used
|
||||
* in future to store some other flag.
|
||||
*/
|
||||
|
||||
*compressedData = 0;
|
||||
|
||||
memcpy(compressedData + 1, plainData, plainSize);
|
||||
|
||||
*compressedSize = plainSize + 1;
|
||||
|
||||
return compressedData;
|
||||
}
|
||||
else
|
||||
{
|
||||
int result;
|
||||
|
||||
/*
|
||||
* Reconfigure the stream if needed.
|
||||
*/
|
||||
|
||||
if (zCompressionLevel != level ||
|
||||
zCompressionStrategy != strategy)
|
||||
{
|
||||
ZConfigure(level, strategy);
|
||||
|
||||
zCompressionLevel = level;
|
||||
zCompressionStrategy = strategy;
|
||||
}
|
||||
|
||||
result = ZDeflate(compressedData + 1, compressedSize, plainData, plainSize);
|
||||
|
||||
if (result != Z_OK)
|
||||
{
|
||||
#ifdef PANIC
|
||||
fprintf(stderr, "******ZCompressData: PANIC! Failed to compress [%d] bytes with error [%s].\n",
|
||||
plainSize, zError(result));
|
||||
#endif
|
||||
|
||||
SAFE_free(compressedData);
|
||||
|
||||
*compressedSize = 0;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
fprintf(stderr, "******ZCompressData: Source data of [%d] bytes compressed to [%d].\n",
|
||||
plainSize, *compressedSize);
|
||||
#endif
|
||||
|
||||
*compressedData = 1;
|
||||
|
||||
*compressedSize = *compressedSize + 1;
|
||||
|
||||
return compressedData;
|
||||
}
|
||||
}
|
||||
|
||||
int ZConfigure(int level, int strategy)
|
||||
{
|
||||
/*
|
||||
* ZLIB wants the avail_out to be
|
||||
* non zero, even if the stream was
|
||||
* already flushed.
|
||||
*/
|
||||
|
||||
unsigned char dest[1];
|
||||
|
||||
zStream -> next_out = dest;
|
||||
zStream -> avail_out = 1;
|
||||
|
||||
if (deflateParams(zStream, level, strategy) != Z_OK)
|
||||
{
|
||||
#ifdef PANIC
|
||||
fprintf(stderr, "******ZConfigure: PANIC! Failed to set level to [%d] and strategy to [%d].\n",
|
||||
level, strategy);
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
#ifdef TEST
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "******ZConfigure: Reconfigured the stream with level [%d] and strategy [%d].\n",
|
||||
level, strategy);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ZDeflate(char *dest, unsigned int *destLen, const char *source, unsigned int sourceLen)
|
||||
{
|
||||
int saveOut;
|
||||
int result;
|
||||
|
||||
/*
|
||||
* Deal with the possible overflow.
|
||||
*/
|
||||
|
||||
if (zStream -> total_out & 0x80000000)
|
||||
{
|
||||
#ifdef TEST
|
||||
fprintf(stderr, "******ZDeflate: Reset Z stream counters with total in [%ld] total out [%ld].\n",
|
||||
zStream -> total_in, zStream -> total_out);
|
||||
#endif
|
||||
|
||||
zStream -> total_in = 0;
|
||||
zStream -> total_out = 0;
|
||||
}
|
||||
|
||||
saveOut = zStream -> total_out;
|
||||
|
||||
zStream -> next_in = (Bytef *) source;
|
||||
zStream -> avail_in = (uInt) sourceLen;
|
||||
|
||||
#ifdef MAXSEG_64K
|
||||
|
||||
/*
|
||||
* Check if the source is greater
|
||||
* than 64K on a 16-bit machine.
|
||||
*/
|
||||
|
||||
if ((uLong) zStream -> avail_in != sourceLen) return Z_BUF_ERROR;
|
||||
|
||||
#endif
|
||||
|
||||
zStream -> next_out = (unsigned char *) dest;
|
||||
zStream -> avail_out = (uInt) *destLen;
|
||||
|
||||
if ((uLong) zStream -> avail_out != *destLen) return Z_BUF_ERROR;
|
||||
|
||||
result = deflate(zStream, Z_FINISH);
|
||||
|
||||
if (result != Z_STREAM_END)
|
||||
{
|
||||
deflateReset(zStream);
|
||||
|
||||
return (result == Z_OK ? Z_BUF_ERROR : result);
|
||||
}
|
||||
|
||||
*destLen = zStream -> total_out - saveOut;
|
||||
|
||||
result = deflateReset(zStream);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int ZInitEncoder(void)
|
||||
{
|
||||
if (zInitialized == 0)
|
||||
{
|
||||
int result;
|
||||
|
||||
zStream = malloc(sizeof(z_stream));
|
||||
|
||||
if (zStream == NULL)
|
||||
{
|
||||
#ifdef PANIC
|
||||
fprintf(stderr, "******ZInitEncoder: PANIC! Failed to allocate memory for the stream.\n");
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
zStream -> zalloc = (alloc_func) 0;
|
||||
zStream -> zfree = (free_func) 0;
|
||||
zStream -> opaque = (voidpf) 0;
|
||||
|
||||
#ifdef TEST
|
||||
fprintf(stderr, "******ZInitEncoder: Initializing compressor with level [%d] and strategy [%d].\n",
|
||||
zCompressionLevel, zCompressionStrategy);
|
||||
#endif
|
||||
|
||||
result = deflateInit2(zStream, zCompressionLevel, Z_DEFLATED,
|
||||
15, 9, zCompressionStrategy);
|
||||
|
||||
if (result != Z_OK)
|
||||
{
|
||||
#ifdef PANIC
|
||||
fprintf(stderr, "******ZInitEncoder: Failed to initialize the compressor with error [%s].\n",
|
||||
zError(result));
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
zInitialized = 1;
|
||||
}
|
||||
|
||||
return zInitialized;
|
||||
}
|
||||
|
||||
int ZResetEncoder(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (zInitialized == 1)
|
||||
{
|
||||
result = deflateEnd(zStream);
|
||||
|
||||
if (result != Z_OK)
|
||||
{
|
||||
#ifdef WARNING
|
||||
fprintf(stderr, "******ZResetEncoder: WARNING! Failed to deinitialize the compressor with error [%s].\n",
|
||||
zError(result));
|
||||
#endif
|
||||
}
|
||||
|
||||
SAFE_free(zStream);
|
||||
}
|
||||
|
||||
zInitialized = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
60
nx-X11/programs/Xserver/hw/nxagent/compext/Z.h
Normal file
60
nx-X11/programs/Xserver/hw/nxagent/compext/Z.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Z_H
|
||||
#define Z_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int ZInitEncoder(
|
||||
#if NeedFunctionPrototypes
|
||||
void
|
||||
#endif
|
||||
);
|
||||
|
||||
int ZResetEncoder(
|
||||
#if NeedFunctionPrototypes
|
||||
void
|
||||
#endif
|
||||
);
|
||||
|
||||
extern char *ZCompressData(
|
||||
#if NeedFunctionPrototypes
|
||||
const char* /* data */,
|
||||
unsigned int /* size */,
|
||||
int /* threshold */,
|
||||
int /* level */,
|
||||
int /* strategy */,
|
||||
unsigned int* /* compressed_size */
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* Z_H */
|
||||
Reference in New Issue
Block a user