mirror of
https://github.com/gryf/wmaker.git
synced 2026-01-06 22:04:12 +01:00
Change to the linux kernel coding style
for arq in `git ls-files *.c`; do
echo $arq;
indent -linux -l115 $arq;
done
The different line break at 115 columns is because
I use a widescreen monitor :-)
This commit is contained in:
@@ -58,41 +58,41 @@ static int icbrt_with_guess();
|
||||
*/
|
||||
|
||||
Status XmuGetColormapAllocation(vinfo, property, red_max, green_max, blue_max)
|
||||
XVisualInfo *vinfo;
|
||||
Atom property;
|
||||
unsigned long *red_max, *green_max, *blue_max;
|
||||
XVisualInfo *vinfo;
|
||||
Atom property;
|
||||
unsigned long *red_max, *green_max, *blue_max;
|
||||
{
|
||||
Status status = 1;
|
||||
Status status = 1;
|
||||
|
||||
if (vinfo->colormap_size <= 2)
|
||||
return 0;
|
||||
if (vinfo->colormap_size <= 2)
|
||||
return 0;
|
||||
|
||||
switch (property) {
|
||||
case XA_RGB_DEFAULT_MAP:
|
||||
status = default_allocation(vinfo, red_max, green_max, blue_max);
|
||||
break;
|
||||
case XA_RGB_BEST_MAP:
|
||||
best_allocation(vinfo, red_max, green_max, blue_max);
|
||||
break;
|
||||
case XA_RGB_GRAY_MAP:
|
||||
gray_allocation(vinfo->colormap_size, red_max, green_max, blue_max);
|
||||
break;
|
||||
case XA_RGB_RED_MAP:
|
||||
*red_max = vinfo->colormap_size - 1;
|
||||
*green_max = *blue_max = 0;
|
||||
break;
|
||||
case XA_RGB_GREEN_MAP:
|
||||
*green_max = vinfo->colormap_size - 1;
|
||||
*red_max = *blue_max = 0;
|
||||
break;
|
||||
case XA_RGB_BLUE_MAP:
|
||||
*blue_max = vinfo->colormap_size - 1;
|
||||
*red_max = *green_max = 0;
|
||||
break;
|
||||
default:
|
||||
status = 0;
|
||||
}
|
||||
return status;
|
||||
switch (property) {
|
||||
case XA_RGB_DEFAULT_MAP:
|
||||
status = default_allocation(vinfo, red_max, green_max, blue_max);
|
||||
break;
|
||||
case XA_RGB_BEST_MAP:
|
||||
best_allocation(vinfo, red_max, green_max, blue_max);
|
||||
break;
|
||||
case XA_RGB_GRAY_MAP:
|
||||
gray_allocation(vinfo->colormap_size, red_max, green_max, blue_max);
|
||||
break;
|
||||
case XA_RGB_RED_MAP:
|
||||
*red_max = vinfo->colormap_size - 1;
|
||||
*green_max = *blue_max = 0;
|
||||
break;
|
||||
case XA_RGB_GREEN_MAP:
|
||||
*green_max = vinfo->colormap_size - 1;
|
||||
*red_max = *blue_max = 0;
|
||||
break;
|
||||
case XA_RGB_BLUE_MAP:
|
||||
*blue_max = vinfo->colormap_size - 1;
|
||||
*red_max = *green_max = 0;
|
||||
break;
|
||||
default:
|
||||
status = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -102,13 +102,13 @@ Status XmuGetColormapAllocation(vinfo, property, red_max, green_max, blue_max)
|
||||
*/
|
||||
|
||||
static void gray_allocation(n, red_max, green_max, blue_max)
|
||||
int n; /* the number of cells of the gray scale */
|
||||
unsigned long *red_max, *green_max, *blue_max;
|
||||
int n; /* the number of cells of the gray scale */
|
||||
unsigned long *red_max, *green_max, *blue_max;
|
||||
{
|
||||
*red_max = (n * 30) / 100;
|
||||
*green_max = (n * 59) / 100;
|
||||
*blue_max = (n * 11) / 100;
|
||||
*green_max += ((n - 1) - (*red_max + *green_max + *blue_max));
|
||||
*red_max = (n * 30) / 100;
|
||||
*green_max = (n * 59) / 100;
|
||||
*blue_max = (n * 11) / 100;
|
||||
*green_max += ((n - 1) - (*red_max + *green_max + *blue_max));
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -126,59 +126,59 @@ static void gray_allocation(n, red_max, green_max, blue_max)
|
||||
*/
|
||||
|
||||
static int default_allocation(vinfo, red, green, blue)
|
||||
XVisualInfo *vinfo;
|
||||
unsigned long *red, *green, *blue;
|
||||
XVisualInfo *vinfo;
|
||||
unsigned long *red, *green, *blue;
|
||||
{
|
||||
int ngrays; /* number of gray cells */
|
||||
int ngrays; /* number of gray cells */
|
||||
|
||||
switch (vinfo->class) {
|
||||
case PseudoColor:
|
||||
switch (vinfo->class) {
|
||||
case PseudoColor:
|
||||
|
||||
if (vinfo->colormap_size > 65000)
|
||||
/* intended for displays with 16 planes */
|
||||
*red = *green = *blue = (unsigned long) 27;
|
||||
else if (vinfo->colormap_size > 4000)
|
||||
/* intended for displays with 12 planes */
|
||||
*red = *green = *blue = (unsigned long) 12;
|
||||
else if (vinfo->colormap_size < 250)
|
||||
return 0;
|
||||
else
|
||||
/* intended for displays with 8 planes */
|
||||
*red = *green = *blue = (unsigned long)
|
||||
(icbrt(vinfo->colormap_size - 125) - 1);
|
||||
break;
|
||||
if (vinfo->colormap_size > 65000)
|
||||
/* intended for displays with 16 planes */
|
||||
*red = *green = *blue = (unsigned long)27;
|
||||
else if (vinfo->colormap_size > 4000)
|
||||
/* intended for displays with 12 planes */
|
||||
*red = *green = *blue = (unsigned long)12;
|
||||
else if (vinfo->colormap_size < 250)
|
||||
return 0;
|
||||
else
|
||||
/* intended for displays with 8 planes */
|
||||
*red = *green = *blue = (unsigned long)
|
||||
(icbrt(vinfo->colormap_size - 125) - 1);
|
||||
break;
|
||||
|
||||
case DirectColor:
|
||||
case DirectColor:
|
||||
|
||||
if (vinfo->colormap_size < 10)
|
||||
return 0;
|
||||
*red = *green = *blue = vinfo->colormap_size / 2 - 1;
|
||||
break;
|
||||
if (vinfo->colormap_size < 10)
|
||||
return 0;
|
||||
*red = *green = *blue = vinfo->colormap_size / 2 - 1;
|
||||
break;
|
||||
|
||||
case TrueColor:
|
||||
case TrueColor:
|
||||
|
||||
*red = vinfo->red_mask / lowbit(vinfo->red_mask);
|
||||
*green = vinfo->green_mask / lowbit(vinfo->green_mask);
|
||||
*blue = vinfo->blue_mask / lowbit(vinfo->blue_mask);
|
||||
break;
|
||||
*red = vinfo->red_mask / lowbit(vinfo->red_mask);
|
||||
*green = vinfo->green_mask / lowbit(vinfo->green_mask);
|
||||
*blue = vinfo->blue_mask / lowbit(vinfo->blue_mask);
|
||||
break;
|
||||
|
||||
case GrayScale:
|
||||
case GrayScale:
|
||||
|
||||
if (vinfo->colormap_size > 65000)
|
||||
ngrays = 4096;
|
||||
else if (vinfo->colormap_size > 4000)
|
||||
ngrays = 512;
|
||||
else if (vinfo->colormap_size < 250)
|
||||
return 0;
|
||||
else
|
||||
ngrays = 12;
|
||||
gray_allocation(ngrays, red, green, blue);
|
||||
break;
|
||||
if (vinfo->colormap_size > 65000)
|
||||
ngrays = 4096;
|
||||
else if (vinfo->colormap_size > 4000)
|
||||
ngrays = 512;
|
||||
else if (vinfo->colormap_size < 250)
|
||||
return 0;
|
||||
else
|
||||
ngrays = 12;
|
||||
gray_allocation(ngrays, red, green, blue);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -200,58 +200,58 @@ static int default_allocation(vinfo, red, green, blue)
|
||||
*/
|
||||
|
||||
static void best_allocation(vinfo, red, green, blue)
|
||||
XVisualInfo *vinfo;
|
||||
unsigned long *red, *green, *blue;
|
||||
XVisualInfo *vinfo;
|
||||
unsigned long *red, *green, *blue;
|
||||
{
|
||||
|
||||
if (vinfo->class == DirectColor || vinfo->class == TrueColor) {
|
||||
*red = vinfo->red_mask;
|
||||
while ((*red & 01) == 0)
|
||||
*red >>= 1;
|
||||
*green = vinfo->green_mask;
|
||||
while ((*green & 01) == 0)
|
||||
*green >>=1;
|
||||
*blue = vinfo->blue_mask;
|
||||
while ((*blue & 01) == 0)
|
||||
*blue >>= 1;
|
||||
} else {
|
||||
register int bits, n;
|
||||
if (vinfo->class == DirectColor || vinfo->class == TrueColor) {
|
||||
*red = vinfo->red_mask;
|
||||
while ((*red & 01) == 0)
|
||||
*red >>= 1;
|
||||
*green = vinfo->green_mask;
|
||||
while ((*green & 01) == 0)
|
||||
*green >>= 1;
|
||||
*blue = vinfo->blue_mask;
|
||||
while ((*blue & 01) == 0)
|
||||
*blue >>= 1;
|
||||
} else {
|
||||
register int bits, n;
|
||||
|
||||
/* Determine n such that n is the least integral power of 2 which is
|
||||
* greater than or equal to the number of entries in the colormap.
|
||||
*/
|
||||
n = 1;
|
||||
bits = 0;
|
||||
while (vinfo->colormap_size > n) {
|
||||
n = n << 1;
|
||||
bits++;
|
||||
}
|
||||
/* Determine n such that n is the least integral power of 2 which is
|
||||
* greater than or equal to the number of entries in the colormap.
|
||||
*/
|
||||
n = 1;
|
||||
bits = 0;
|
||||
while (vinfo->colormap_size > n) {
|
||||
n = n << 1;
|
||||
bits++;
|
||||
}
|
||||
|
||||
/* If the number of entries in the colormap is a power of 2, determine
|
||||
* the allocation by "dealing" the bits, first to green, then red, then
|
||||
* blue. If not, find the maximum integral red, green, and blue values
|
||||
* which, when multiplied together, do not exceed the number of
|
||||
/* If the number of entries in the colormap is a power of 2, determine
|
||||
* the allocation by "dealing" the bits, first to green, then red, then
|
||||
* blue. If not, find the maximum integral red, green, and blue values
|
||||
* which, when multiplied together, do not exceed the number of
|
||||
|
||||
* colormap entries.
|
||||
*/
|
||||
if (n == vinfo->colormap_size) {
|
||||
register int r, g, b;
|
||||
b = bits / 3;
|
||||
g = b + ((bits % 3) ? 1 : 0);
|
||||
r = b + (((bits % 3) == 2) ? 1 : 0);
|
||||
*red = 1 << r;
|
||||
*green = 1 << g;
|
||||
*blue = 1 << b;
|
||||
} else {
|
||||
*red = icbrt_with_bits(vinfo->colormap_size, bits);
|
||||
*blue = *red;
|
||||
*green = (vinfo->colormap_size / ((*red) * (*blue)));
|
||||
}
|
||||
(*red)--;
|
||||
(*green)--;
|
||||
(*blue)--;
|
||||
}
|
||||
return;
|
||||
* colormap entries.
|
||||
*/
|
||||
if (n == vinfo->colormap_size) {
|
||||
register int r, g, b;
|
||||
b = bits / 3;
|
||||
g = b + ((bits % 3) ? 1 : 0);
|
||||
r = b + (((bits % 3) == 2) ? 1 : 0);
|
||||
*red = 1 << r;
|
||||
*green = 1 << g;
|
||||
*blue = 1 << b;
|
||||
} else {
|
||||
*red = icbrt_with_bits(vinfo->colormap_size, bits);
|
||||
*blue = *red;
|
||||
*green = (vinfo->colormap_size / ((*red) * (*blue)));
|
||||
}
|
||||
(*red)--;
|
||||
(*green)--;
|
||||
(*blue)--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -261,24 +261,23 @@ static void best_allocation(vinfo, red, green, blue)
|
||||
*/
|
||||
|
||||
static int icbrt(a) /* integer cube root */
|
||||
int a;
|
||||
int a;
|
||||
{
|
||||
register int bits = 0;
|
||||
register unsigned n = a;
|
||||
register int bits = 0;
|
||||
register unsigned n = a;
|
||||
|
||||
while (n) {
|
||||
bits++;
|
||||
n >>= 1;
|
||||
}
|
||||
return icbrt_with_bits(a, bits);
|
||||
while (n) {
|
||||
bits++;
|
||||
n >>= 1;
|
||||
}
|
||||
return icbrt_with_bits(a, bits);
|
||||
}
|
||||
|
||||
|
||||
static int icbrt_with_bits(a, bits)
|
||||
int a;
|
||||
int bits; /* log 2 of a */
|
||||
int a;
|
||||
int bits; /* log 2 of a */
|
||||
{
|
||||
return icbrt_with_guess(a, a>>2*bits/3);
|
||||
return icbrt_with_guess(a, a >> 2 * bits / 3);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -296,32 +295,31 @@ int icbrt_loopcount;
|
||||
*/
|
||||
|
||||
static int icbrt_with_guess(a, guess)
|
||||
int a, guess;
|
||||
int a, guess;
|
||||
{
|
||||
register int delta;
|
||||
register int delta;
|
||||
|
||||
#ifdef DEBUG
|
||||
icbrt_loopcount = 0;
|
||||
icbrt_loopcount = 0;
|
||||
#endif
|
||||
if (a <= 0)
|
||||
return 0;
|
||||
if (guess < 1)
|
||||
guess = 1;
|
||||
if (a <= 0)
|
||||
return 0;
|
||||
if (guess < 1)
|
||||
guess = 1;
|
||||
|
||||
do {
|
||||
do {
|
||||
#ifdef DEBUG
|
||||
icbrt_loopcount++;
|
||||
icbrt_loopcount++;
|
||||
#endif
|
||||
delta = (guess - a/(guess*guess))/3;
|
||||
delta = (guess - a / (guess * guess)) / 3;
|
||||
#ifdef DEBUG
|
||||
printf("pass %d: guess=%d, delta=%d\n", icbrt_loopcount, guess, delta);
|
||||
printf("pass %d: guess=%d, delta=%d\n", icbrt_loopcount, guess, delta);
|
||||
#endif
|
||||
guess -= delta;
|
||||
} while (delta != 0);
|
||||
guess -= delta;
|
||||
} while (delta != 0);
|
||||
|
||||
if (guess*guess*guess > a)
|
||||
guess--;
|
||||
if (guess * guess * guess > a)
|
||||
guess--;
|
||||
|
||||
return guess;
|
||||
return guess;
|
||||
}
|
||||
|
||||
|
||||
709
wrlib/CrCmap.c
709
wrlib/CrCmap.c
@@ -40,15 +40,14 @@ in this Software without prior written authorization from the X Consortium.
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
|
||||
static int ROmap(); /* allocate entire map Read Only */
|
||||
static Status ROorRWcell(); /* allocate a cell, prefer Read Only */
|
||||
static Status RWcell(); /* allocate a cell Read Write */
|
||||
static int compare(); /* for quicksort */
|
||||
static Status contiguous(); /* find contiguous sequence of cells */
|
||||
static void free_cells(); /* frees resources before quitting */
|
||||
static Status readonly_map(); /* create a map in a RO visual type */
|
||||
static Status readwrite_map(); /* create a map in a RW visual type */
|
||||
static int ROmap(); /* allocate entire map Read Only */
|
||||
static Status ROorRWcell(); /* allocate a cell, prefer Read Only */
|
||||
static Status RWcell(); /* allocate a cell Read Write */
|
||||
static int compare(); /* for quicksort */
|
||||
static Status contiguous(); /* find contiguous sequence of cells */
|
||||
static void free_cells(); /* frees resources before quitting */
|
||||
static Status readonly_map(); /* create a map in a RO visual type */
|
||||
static Status readwrite_map(); /* create a map in a RW visual type */
|
||||
|
||||
#define lowbit(x) ((x) & (~(x) + 1))
|
||||
#define TRUEMATCH(mult,max,mask) \
|
||||
@@ -76,450 +75,410 @@ static Status readwrite_map(); /* create a map in a RW visual type */
|
||||
*/
|
||||
|
||||
Status XmuCreateColormap(dpy, colormap)
|
||||
Display *dpy; /* specifies the connection under
|
||||
* which the map is created */
|
||||
XStandardColormap *colormap; /* specifies the map to be created,
|
||||
* and returns, particularly if the
|
||||
* map is created as a subset of the
|
||||
* default colormap of the screen,
|
||||
* the base_pixel of the map.
|
||||
*/
|
||||
Display *dpy; /* specifies the connection under
|
||||
* which the map is created */
|
||||
XStandardColormap *colormap; /* specifies the map to be created,
|
||||
* and returns, particularly if the
|
||||
* map is created as a subset of the
|
||||
* default colormap of the screen,
|
||||
* the base_pixel of the map.
|
||||
*/
|
||||
{
|
||||
XVisualInfo vinfo_template; /* template visual information */
|
||||
XVisualInfo *vinfo; /* matching visual information */
|
||||
XVisualInfo *vpointer; /* for freeing the entire list */
|
||||
long vinfo_mask; /* specifies the visual mask value */
|
||||
int n; /* number of matching visuals */
|
||||
int status;
|
||||
XVisualInfo vinfo_template; /* template visual information */
|
||||
XVisualInfo *vinfo; /* matching visual information */
|
||||
XVisualInfo *vpointer; /* for freeing the entire list */
|
||||
long vinfo_mask; /* specifies the visual mask value */
|
||||
int n; /* number of matching visuals */
|
||||
int status;
|
||||
|
||||
vinfo_template.visualid = colormap->visualid;
|
||||
vinfo_mask = VisualIDMask;
|
||||
if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
|
||||
return 0;
|
||||
vinfo_template.visualid = colormap->visualid;
|
||||
vinfo_mask = VisualIDMask;
|
||||
if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
|
||||
return 0;
|
||||
|
||||
/* A visual id may be valid on multiple screens. Also, there may
|
||||
* be multiple visuals with identical visual ids at different depths.
|
||||
* If the colormap is the Default Colormap, use the Default Visual.
|
||||
* Otherwise, arbitrarily, use the deepest visual.
|
||||
*/
|
||||
vpointer = vinfo;
|
||||
if (n > 1)
|
||||
{
|
||||
register int i;
|
||||
register int screen_number;
|
||||
Bool def_cmap;
|
||||
/* A visual id may be valid on multiple screens. Also, there may
|
||||
* be multiple visuals with identical visual ids at different depths.
|
||||
* If the colormap is the Default Colormap, use the Default Visual.
|
||||
* Otherwise, arbitrarily, use the deepest visual.
|
||||
*/
|
||||
vpointer = vinfo;
|
||||
if (n > 1) {
|
||||
register int i;
|
||||
register int screen_number;
|
||||
Bool def_cmap;
|
||||
|
||||
def_cmap = False;
|
||||
for (screen_number = ScreenCount(dpy); --screen_number >= 0; )
|
||||
if (colormap->colormap == DefaultColormap(dpy, screen_number)) {
|
||||
def_cmap = True;
|
||||
break;
|
||||
}
|
||||
def_cmap = False;
|
||||
for (screen_number = ScreenCount(dpy); --screen_number >= 0;)
|
||||
if (colormap->colormap == DefaultColormap(dpy, screen_number)) {
|
||||
def_cmap = True;
|
||||
break;
|
||||
}
|
||||
|
||||
if (def_cmap) {
|
||||
for (i=0; i < n; i++, vinfo++) {
|
||||
if (vinfo->visual == DefaultVisual(dpy, screen_number))
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
unsigned int maxdepth = 0;
|
||||
XVisualInfo *v = vinfo;
|
||||
if (def_cmap) {
|
||||
for (i = 0; i < n; i++, vinfo++) {
|
||||
if (vinfo->visual == DefaultVisual(dpy, screen_number))
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
unsigned int maxdepth = 0;
|
||||
XVisualInfo *v = vinfo;
|
||||
|
||||
for (i=0; i < n; i++, vinfo++)
|
||||
if (vinfo->depth > maxdepth) {
|
||||
maxdepth = vinfo->depth;
|
||||
v = vinfo;
|
||||
}
|
||||
vinfo = v;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < n; i++, vinfo++)
|
||||
if (vinfo->depth > maxdepth) {
|
||||
maxdepth = vinfo->depth;
|
||||
v = vinfo;
|
||||
}
|
||||
vinfo = v;
|
||||
}
|
||||
}
|
||||
|
||||
if (vinfo->class == PseudoColor || vinfo->class == DirectColor ||
|
||||
vinfo->class == GrayScale)
|
||||
status = readwrite_map(dpy, vinfo, colormap);
|
||||
else if (vinfo->class == TrueColor)
|
||||
status = TRUEMATCH(red_mult, red_max, red_mask) &&
|
||||
TRUEMATCH(green_mult, green_max, green_mask) &&
|
||||
TRUEMATCH(blue_mult, blue_max, blue_mask);
|
||||
else
|
||||
status = readonly_map(dpy, vinfo, colormap);
|
||||
if (vinfo->class == PseudoColor || vinfo->class == DirectColor || vinfo->class == GrayScale)
|
||||
status = readwrite_map(dpy, vinfo, colormap);
|
||||
else if (vinfo->class == TrueColor)
|
||||
status = TRUEMATCH(red_mult, red_max, red_mask) &&
|
||||
TRUEMATCH(green_mult, green_max, green_mask) && TRUEMATCH(blue_mult, blue_max, blue_mask);
|
||||
else
|
||||
status = readonly_map(dpy, vinfo, colormap);
|
||||
|
||||
XFree((char *) vpointer);
|
||||
return status;
|
||||
XFree((char *)vpointer);
|
||||
return status;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static Status readwrite_map(dpy, vinfo, colormap)
|
||||
Display *dpy;
|
||||
XVisualInfo *vinfo;
|
||||
XStandardColormap *colormap;
|
||||
Display *dpy;
|
||||
XVisualInfo *vinfo;
|
||||
XStandardColormap *colormap;
|
||||
{
|
||||
register unsigned long i, n; /* index counters */
|
||||
int ncolors; /* number of colors to be defined */
|
||||
int npixels; /* number of pixels allocated R/W */
|
||||
int first_index; /* first index of pixels to use */
|
||||
int remainder; /* first index of remainder */
|
||||
XColor color; /* the definition of a color */
|
||||
unsigned long *pixels; /* array of colormap pixels */
|
||||
unsigned long delta;
|
||||
register unsigned long i, n; /* index counters */
|
||||
int ncolors; /* number of colors to be defined */
|
||||
int npixels; /* number of pixels allocated R/W */
|
||||
int first_index; /* first index of pixels to use */
|
||||
int remainder; /* first index of remainder */
|
||||
XColor color; /* the definition of a color */
|
||||
unsigned long *pixels; /* array of colormap pixels */
|
||||
unsigned long delta;
|
||||
|
||||
/* Determine ncolors, the number of colors to be defined.
|
||||
* Insure that 1 < ncolors <= the colormap size.
|
||||
*/
|
||||
if (vinfo->class == DirectColor) {
|
||||
ncolors = colormap->red_max;
|
||||
if (colormap->green_max > ncolors)
|
||||
ncolors = colormap->green_max;
|
||||
if (colormap->blue_max > ncolors)
|
||||
ncolors = colormap->blue_max;
|
||||
ncolors++;
|
||||
delta = lowbit(vinfo->red_mask) + lowbit(vinfo->green_mask) + lowbit(vinfo->blue_mask);
|
||||
} else {
|
||||
ncolors = colormap->red_max * colormap->red_mult +
|
||||
colormap->green_max * colormap->green_mult + colormap->blue_max * colormap->blue_mult + 1;
|
||||
delta = 1;
|
||||
}
|
||||
if (ncolors <= 1 || ncolors > vinfo->colormap_size)
|
||||
return 0;
|
||||
|
||||
/* Determine ncolors, the number of colors to be defined.
|
||||
* Insure that 1 < ncolors <= the colormap size.
|
||||
*/
|
||||
if (vinfo->class == DirectColor) {
|
||||
ncolors = colormap->red_max;
|
||||
if (colormap->green_max > ncolors)
|
||||
ncolors = colormap->green_max;
|
||||
if (colormap->blue_max > ncolors)
|
||||
ncolors = colormap->blue_max;
|
||||
ncolors++;
|
||||
delta = lowbit(vinfo->red_mask) +
|
||||
lowbit(vinfo->green_mask) +
|
||||
lowbit(vinfo->blue_mask);
|
||||
} else {
|
||||
ncolors = colormap->red_max * colormap->red_mult +
|
||||
colormap->green_max * colormap->green_mult +
|
||||
colormap->blue_max * colormap->blue_mult + 1;
|
||||
delta = 1;
|
||||
}
|
||||
if (ncolors <= 1 || ncolors > vinfo->colormap_size) return 0;
|
||||
/* Allocate Read/Write as much of the colormap as we can possibly get.
|
||||
* Then insure that the pixels we were allocated are given in
|
||||
* monotonically increasing order, using a quicksort. Next, insure
|
||||
* that our allocation includes a subset of contiguous pixels at least
|
||||
* as long as the number of colors to be defined. Now we know that
|
||||
* these conditions are met:
|
||||
* 1) There are no free cells in the colormap.
|
||||
* 2) We have a contiguous sequence of pixels, monotonically
|
||||
* increasing, of length >= the number of colors requested.
|
||||
*
|
||||
* One cell at a time, we will free, compute the next color value,
|
||||
* then allocate read only. This takes a long time.
|
||||
* This is done to insure that cells are allocated read only in the
|
||||
* contiguous order which we prefer. If the server has a choice of
|
||||
* cells to grant to an allocation request, the server may give us any
|
||||
* cell, so that is why we do these slow gymnastics.
|
||||
*/
|
||||
|
||||
/* Allocate Read/Write as much of the colormap as we can possibly get.
|
||||
* Then insure that the pixels we were allocated are given in
|
||||
* monotonically increasing order, using a quicksort. Next, insure
|
||||
* that our allocation includes a subset of contiguous pixels at least
|
||||
* as long as the number of colors to be defined. Now we know that
|
||||
* these conditions are met:
|
||||
* 1) There are no free cells in the colormap.
|
||||
* 2) We have a contiguous sequence of pixels, monotonically
|
||||
* increasing, of length >= the number of colors requested.
|
||||
*
|
||||
* One cell at a time, we will free, compute the next color value,
|
||||
* then allocate read only. This takes a long time.
|
||||
* This is done to insure that cells are allocated read only in the
|
||||
* contiguous order which we prefer. If the server has a choice of
|
||||
* cells to grant to an allocation request, the server may give us any
|
||||
* cell, so that is why we do these slow gymnastics.
|
||||
*/
|
||||
if ((pixels = (unsigned long *)calloc((unsigned)vinfo->colormap_size, sizeof(unsigned long))) == NULL)
|
||||
return 0;
|
||||
|
||||
if ((pixels = (unsigned long *) calloc((unsigned) vinfo->colormap_size,
|
||||
sizeof(unsigned long))) == NULL)
|
||||
return 0;
|
||||
if ((npixels = ROmap(dpy, colormap->colormap, pixels, vinfo->colormap_size, ncolors)) == 0) {
|
||||
free((char *)pixels);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((npixels = ROmap(dpy, colormap->colormap, pixels,
|
||||
vinfo->colormap_size, ncolors)) == 0) {
|
||||
free((char *) pixels);
|
||||
return 0;
|
||||
}
|
||||
qsort((char *)pixels, npixels, sizeof(unsigned long), compare);
|
||||
|
||||
qsort((char *) pixels, npixels, sizeof(unsigned long), compare);
|
||||
if (!contiguous(pixels, npixels, ncolors, delta, &first_index, &remainder)) {
|
||||
/* can't find enough contiguous cells, give up */
|
||||
XFreeColors(dpy, colormap->colormap, pixels, npixels, (unsigned long)0);
|
||||
free((char *)pixels);
|
||||
return 0;
|
||||
}
|
||||
colormap->base_pixel = pixels[first_index];
|
||||
|
||||
if (!contiguous(pixels, npixels, ncolors, delta, &first_index, &remainder))
|
||||
{
|
||||
/* can't find enough contiguous cells, give up */
|
||||
XFreeColors(dpy, colormap->colormap, pixels, npixels,
|
||||
(unsigned long) 0);
|
||||
free((char *) pixels);
|
||||
return 0;
|
||||
}
|
||||
colormap->base_pixel = pixels[first_index];
|
||||
/* construct a gray map */
|
||||
if (colormap->red_mult == 1 && colormap->green_mult == 1 && colormap->blue_mult == 1)
|
||||
for (n = colormap->base_pixel, i = 0; i < ncolors; i++, n += delta) {
|
||||
color.pixel = n;
|
||||
color.blue = color.green = color.red =
|
||||
(unsigned short)((i * 65535) / (colormap->red_max +
|
||||
colormap->green_max + colormap->blue_max));
|
||||
|
||||
/* construct a gray map */
|
||||
if (colormap->red_mult == 1 && colormap->green_mult == 1 &&
|
||||
colormap->blue_mult == 1)
|
||||
for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
|
||||
{
|
||||
color.pixel = n;
|
||||
color.blue = color.green = color.red =
|
||||
(unsigned short) ((i * 65535) / (colormap->red_max +
|
||||
colormap->green_max +
|
||||
colormap->blue_max));
|
||||
if (!ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, first_index + i))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
|
||||
first_index + i))
|
||||
return 0;
|
||||
}
|
||||
/* construct a red ramp map */
|
||||
else if (colormap->green_max == 0 && colormap->blue_max == 0)
|
||||
for (n = colormap->base_pixel, i = 0; i < ncolors; i++, n += delta) {
|
||||
color.pixel = n;
|
||||
color.red = (unsigned short)((i * 65535) / colormap->red_max);
|
||||
color.green = color.blue = 0;
|
||||
|
||||
/* construct a red ramp map */
|
||||
else if (colormap->green_max == 0 && colormap->blue_max == 0)
|
||||
for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
|
||||
{
|
||||
color.pixel = n;
|
||||
color.red = (unsigned short) ((i * 65535) / colormap->red_max);
|
||||
color.green = color.blue = 0;
|
||||
if (!ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, first_index + i))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
|
||||
first_index + i))
|
||||
return 0;
|
||||
}
|
||||
/* construct a green ramp map */
|
||||
else if (colormap->red_max == 0 && colormap->blue_max == 0)
|
||||
for (n = colormap->base_pixel, i = 0; i < ncolors; i++, n += delta) {
|
||||
color.pixel = n;
|
||||
color.green = (unsigned short)((i * 65535) / colormap->green_max);
|
||||
color.red = color.blue = 0;
|
||||
|
||||
/* construct a green ramp map */
|
||||
else if (colormap->red_max == 0 && colormap->blue_max == 0)
|
||||
for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
|
||||
{
|
||||
color.pixel = n;
|
||||
color.green = (unsigned short) ((i * 65535) / colormap->green_max);
|
||||
color.red = color.blue = 0;
|
||||
if (!ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, first_index + i))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
|
||||
first_index + i))
|
||||
return 0;
|
||||
}
|
||||
/* construct a blue ramp map */
|
||||
else if (colormap->red_max == 0 && colormap->green_max == 0)
|
||||
for (n = colormap->base_pixel, i = 0; i < ncolors; i++, n += delta) {
|
||||
color.pixel = n;
|
||||
color.blue = (unsigned short)((i * 65535) / colormap->blue_max);
|
||||
color.red = color.green = 0;
|
||||
|
||||
/* construct a blue ramp map */
|
||||
else if (colormap->red_max == 0 && colormap->green_max == 0)
|
||||
for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
|
||||
{
|
||||
color.pixel = n;
|
||||
color.blue = (unsigned short) ((i * 65535) / colormap->blue_max);
|
||||
color.red = color.green = 0;
|
||||
if (!ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, first_index + i))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
|
||||
first_index + i))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* construct a standard red green blue cube map */
|
||||
else
|
||||
{
|
||||
/* construct a standard red green blue cube map */
|
||||
else {
|
||||
#define calc(max,mult) (((n / colormap->mult) % \
|
||||
(colormap->max + 1)) * 65535) / colormap->max
|
||||
|
||||
for (n=0, i=0; i < ncolors; i++, n += delta)
|
||||
{
|
||||
color.pixel = n + colormap->base_pixel;
|
||||
color.red = calc(red_max, red_mult);
|
||||
color.green = calc(green_max, green_mult);
|
||||
color.blue = calc(blue_max, blue_mult);
|
||||
if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
|
||||
first_index + i))
|
||||
return 0;
|
||||
}
|
||||
for (n = 0, i = 0; i < ncolors; i++, n += delta) {
|
||||
color.pixel = n + colormap->base_pixel;
|
||||
color.red = calc(red_max, red_mult);
|
||||
color.green = calc(green_max, green_mult);
|
||||
color.blue = calc(blue_max, blue_mult);
|
||||
if (!ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color, first_index + i))
|
||||
return 0;
|
||||
}
|
||||
#undef calc
|
||||
}
|
||||
/* We have a read-only map defined. Now free unused cells,
|
||||
* first those occuring before the contiguous sequence begins,
|
||||
* then any following the contiguous sequence.
|
||||
*/
|
||||
}
|
||||
/* We have a read-only map defined. Now free unused cells,
|
||||
* first those occuring before the contiguous sequence begins,
|
||||
* then any following the contiguous sequence.
|
||||
*/
|
||||
|
||||
if (first_index)
|
||||
XFreeColors(dpy, colormap->colormap, pixels, first_index,
|
||||
(unsigned long) 0);
|
||||
if (remainder)
|
||||
XFreeColors(dpy, colormap->colormap,
|
||||
&(pixels[first_index + ncolors]), remainder,
|
||||
(unsigned long) 0);
|
||||
if (first_index)
|
||||
XFreeColors(dpy, colormap->colormap, pixels, first_index, (unsigned long)0);
|
||||
if (remainder)
|
||||
XFreeColors(dpy, colormap->colormap,
|
||||
&(pixels[first_index + ncolors]), remainder, (unsigned long)0);
|
||||
|
||||
free((char *) pixels);
|
||||
return 1;
|
||||
free((char *)pixels);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
static int ROmap(dpy, cmap, pixels, m, n)
|
||||
Display *dpy; /* the X server connection */
|
||||
Colormap cmap; /* specifies colormap ID */
|
||||
unsigned long pixels[]; /* returns pixel allocations */
|
||||
int m; /* specifies colormap size */
|
||||
int n; /* specifies number of colors */
|
||||
Display *dpy; /* the X server connection */
|
||||
Colormap cmap; /* specifies colormap ID */
|
||||
unsigned long pixels[]; /* returns pixel allocations */
|
||||
int m; /* specifies colormap size */
|
||||
int n; /* specifies number of colors */
|
||||
{
|
||||
register int p;
|
||||
register int p;
|
||||
|
||||
/* first try to allocate the entire colormap */
|
||||
if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL,
|
||||
(unsigned) 0, pixels, (unsigned) m))
|
||||
return m;
|
||||
/* first try to allocate the entire colormap */
|
||||
if (XAllocColorCells(dpy, cmap, 1, (unsigned long *)NULL, (unsigned)0, pixels, (unsigned)m))
|
||||
return m;
|
||||
|
||||
/* Allocate all available cells in the colormap, using a binary
|
||||
* algorithm to discover how many cells we can allocate in the colormap.
|
||||
*/
|
||||
m--;
|
||||
while (n <= m) {
|
||||
p = n + ((m - n + 1) / 2);
|
||||
if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL,
|
||||
(unsigned) 0, pixels, (unsigned) p)) {
|
||||
if (p == m)
|
||||
return p;
|
||||
else {
|
||||
XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0);
|
||||
n = p;
|
||||
}
|
||||
}
|
||||
else
|
||||
m = p - 1;
|
||||
}
|
||||
return 0;
|
||||
/* Allocate all available cells in the colormap, using a binary
|
||||
* algorithm to discover how many cells we can allocate in the colormap.
|
||||
*/
|
||||
m--;
|
||||
while (n <= m) {
|
||||
p = n + ((m - n + 1) / 2);
|
||||
if (XAllocColorCells(dpy, cmap, 1, (unsigned long *)NULL, (unsigned)0, pixels, (unsigned)p)) {
|
||||
if (p == m)
|
||||
return p;
|
||||
else {
|
||||
XFreeColors(dpy, cmap, pixels, p, (unsigned long)0);
|
||||
n = p;
|
||||
}
|
||||
} else
|
||||
m = p - 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
static Status contiguous(pixels, npixels, ncolors, delta, first, rem)
|
||||
unsigned long pixels[]; /* specifies allocated pixels */
|
||||
int npixels; /* specifies count of alloc'd pixels */
|
||||
int ncolors; /* specifies needed sequence length */
|
||||
unsigned long delta; /* between pixels */
|
||||
int *first; /* returns first index of sequence */
|
||||
int *rem; /* returns first index after sequence,
|
||||
* or 0, if none follow */
|
||||
unsigned long pixels[]; /* specifies allocated pixels */
|
||||
int npixels; /* specifies count of alloc'd pixels */
|
||||
int ncolors; /* specifies needed sequence length */
|
||||
unsigned long delta; /* between pixels */
|
||||
int *first; /* returns first index of sequence */
|
||||
int *rem; /* returns first index after sequence,
|
||||
* or 0, if none follow */
|
||||
{
|
||||
register int i = 1; /* walking index into the pixel array */
|
||||
register int count = 1; /* length of sequence discovered so far */
|
||||
register int i = 1; /* walking index into the pixel array */
|
||||
register int count = 1; /* length of sequence discovered so far */
|
||||
|
||||
*first = 0;
|
||||
if (npixels == ncolors) {
|
||||
*rem = 0;
|
||||
return 1;
|
||||
}
|
||||
*rem = npixels - 1;
|
||||
while (count < ncolors && ncolors - count <= *rem)
|
||||
{
|
||||
if (pixels[i-1] + delta == pixels[i])
|
||||
count++;
|
||||
else {
|
||||
count = 1;
|
||||
*first = i;
|
||||
}
|
||||
i++;
|
||||
(*rem)--;
|
||||
}
|
||||
if (count != ncolors)
|
||||
return 0;
|
||||
return 1;
|
||||
*first = 0;
|
||||
if (npixels == ncolors) {
|
||||
*rem = 0;
|
||||
return 1;
|
||||
}
|
||||
*rem = npixels - 1;
|
||||
while (count < ncolors && ncolors - count <= *rem) {
|
||||
if (pixels[i - 1] + delta == pixels[i])
|
||||
count++;
|
||||
else {
|
||||
count = 1;
|
||||
*first = i;
|
||||
}
|
||||
i++;
|
||||
(*rem)--;
|
||||
}
|
||||
if (count != ncolors)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
static Status ROorRWcell(dpy, cmap, pixels, npixels, color, p)
|
||||
Display *dpy;
|
||||
Colormap cmap;
|
||||
unsigned long pixels[];
|
||||
int npixels;
|
||||
XColor *color;
|
||||
unsigned long p;
|
||||
Display *dpy;
|
||||
Colormap cmap;
|
||||
unsigned long pixels[];
|
||||
int npixels;
|
||||
XColor *color;
|
||||
unsigned long p;
|
||||
{
|
||||
unsigned long pixel;
|
||||
XColor request;
|
||||
unsigned long pixel;
|
||||
XColor request;
|
||||
|
||||
/* Free the read/write allocation of one cell in the colormap.
|
||||
* Request a read only allocation of one cell in the colormap.
|
||||
* If the read only allocation cannot be granted, give up, because
|
||||
* there must be no free cells in the colormap.
|
||||
* If the read only allocation is granted, but gives us a cell which
|
||||
* is not the one that we just freed, it is probably the case that
|
||||
* we are trying allocate White or Black or some other color which
|
||||
* already has a read-only allocation in the map. So we try to
|
||||
* allocate the previously freed cell with a read/write allocation,
|
||||
* because we want contiguous cells for image processing algorithms.
|
||||
*/
|
||||
/* Free the read/write allocation of one cell in the colormap.
|
||||
* Request a read only allocation of one cell in the colormap.
|
||||
* If the read only allocation cannot be granted, give up, because
|
||||
* there must be no free cells in the colormap.
|
||||
* If the read only allocation is granted, but gives us a cell which
|
||||
* is not the one that we just freed, it is probably the case that
|
||||
* we are trying allocate White or Black or some other color which
|
||||
* already has a read-only allocation in the map. So we try to
|
||||
* allocate the previously freed cell with a read/write allocation,
|
||||
* because we want contiguous cells for image processing algorithms.
|
||||
*/
|
||||
|
||||
pixel = color->pixel;
|
||||
request.red = color->red;
|
||||
request.green = color->green;
|
||||
request.blue = color->blue;
|
||||
pixel = color->pixel;
|
||||
request.red = color->red;
|
||||
request.green = color->green;
|
||||
request.blue = color->blue;
|
||||
|
||||
XFreeColors(dpy, cmap, &pixel, 1, (unsigned long) 0);
|
||||
if (! XAllocColor(dpy, cmap, color)
|
||||
|| (color->pixel != pixel &&
|
||||
(!RWcell(dpy, cmap, color, &request, &pixel))))
|
||||
{
|
||||
free_cells(dpy, cmap, pixels, npixels, (int)p);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
XFreeColors(dpy, cmap, &pixel, 1, (unsigned long)0);
|
||||
if (!XAllocColor(dpy, cmap, color)
|
||||
|| (color->pixel != pixel && (!RWcell(dpy, cmap, color, &request, &pixel)))) {
|
||||
free_cells(dpy, cmap, pixels, npixels, (int)p);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
static void free_cells(dpy, cmap, pixels, npixels, p)
|
||||
Display *dpy;
|
||||
Colormap cmap;
|
||||
unsigned long pixels[]; /* to be freed */
|
||||
int npixels; /* original number allocated */
|
||||
int p;
|
||||
static void free_cells(dpy, cmap, pixels, npixels, p)
|
||||
Display *dpy;
|
||||
Colormap cmap;
|
||||
unsigned long pixels[]; /* to be freed */
|
||||
int npixels; /* original number allocated */
|
||||
int p;
|
||||
{
|
||||
/* One of the npixels allocated has already been freed.
|
||||
* p is the index of the freed pixel.
|
||||
* First free the pixels preceeding p, and there are p of them;
|
||||
* then free the pixels following p, there are npixels - p - 1 of them.
|
||||
*/
|
||||
XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0);
|
||||
XFreeColors(dpy, cmap, &(pixels[p+1]), npixels - p - 1, (unsigned long) 0);
|
||||
free((char *) pixels);
|
||||
/* One of the npixels allocated has already been freed.
|
||||
* p is the index of the freed pixel.
|
||||
* First free the pixels preceeding p, and there are p of them;
|
||||
* then free the pixels following p, there are npixels - p - 1 of them.
|
||||
*/
|
||||
XFreeColors(dpy, cmap, pixels, p, (unsigned long)0);
|
||||
XFreeColors(dpy, cmap, &(pixels[p + 1]), npixels - p - 1, (unsigned long)0);
|
||||
free((char *)pixels);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
static Status RWcell(dpy, cmap, color, request, pixel)
|
||||
Display *dpy;
|
||||
Colormap cmap;
|
||||
XColor *color;
|
||||
XColor *request;
|
||||
unsigned long *pixel;
|
||||
Display *dpy;
|
||||
Colormap cmap;
|
||||
XColor *color;
|
||||
XColor *request;
|
||||
unsigned long *pixel;
|
||||
{
|
||||
unsigned long n = *pixel;
|
||||
unsigned long n = *pixel;
|
||||
|
||||
XFreeColors(dpy, cmap, &(color->pixel), 1, (unsigned long)0);
|
||||
if (! XAllocColorCells(dpy, cmap, (Bool) 0, (unsigned long *) NULL,
|
||||
(unsigned) 0, pixel, (unsigned) 1))
|
||||
return 0;
|
||||
if (*pixel != n)
|
||||
{
|
||||
XFreeColors(dpy, cmap, pixel, 1, (unsigned long) 0);
|
||||
return 0;
|
||||
}
|
||||
color->pixel = *pixel;
|
||||
color->flags = DoRed | DoGreen | DoBlue;
|
||||
color->red = request->red;
|
||||
color->green = request->green;
|
||||
color->blue = request->blue;
|
||||
XStoreColors(dpy, cmap, color, 1);
|
||||
return 1;
|
||||
XFreeColors(dpy, cmap, &(color->pixel), 1, (unsigned long)0);
|
||||
if (!XAllocColorCells(dpy, cmap, (Bool) 0, (unsigned long *)NULL, (unsigned)0, pixel, (unsigned)1))
|
||||
return 0;
|
||||
if (*pixel != n) {
|
||||
XFreeColors(dpy, cmap, pixel, 1, (unsigned long)0);
|
||||
return 0;
|
||||
}
|
||||
color->pixel = *pixel;
|
||||
color->flags = DoRed | DoGreen | DoBlue;
|
||||
color->red = request->red;
|
||||
color->green = request->green;
|
||||
color->blue = request->blue;
|
||||
XStoreColors(dpy, cmap, color, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
static int compare(e1, e2)
|
||||
unsigned long *e1, *e2;
|
||||
unsigned long *e1, *e2;
|
||||
{
|
||||
if (*e1 < *e2) return -1;
|
||||
if (*e1 > *e2) return 1;
|
||||
return 0;
|
||||
if (*e1 < *e2)
|
||||
return -1;
|
||||
if (*e1 > *e2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
static Status readonly_map(dpy, vinfo, colormap)
|
||||
Display *dpy;
|
||||
XVisualInfo *vinfo;
|
||||
XStandardColormap *colormap;
|
||||
Display *dpy;
|
||||
XVisualInfo *vinfo;
|
||||
XStandardColormap *colormap;
|
||||
{
|
||||
int i, last_pixel;
|
||||
XColor color;
|
||||
int i, last_pixel;
|
||||
XColor color;
|
||||
|
||||
last_pixel = (colormap->red_max + 1) * (colormap->green_max + 1) *
|
||||
(colormap->blue_max + 1) + colormap->base_pixel - 1;
|
||||
last_pixel = (colormap->red_max + 1) * (colormap->green_max + 1) *
|
||||
(colormap->blue_max + 1) + colormap->base_pixel - 1;
|
||||
|
||||
for(i=colormap->base_pixel; i <= last_pixel; i++) {
|
||||
for (i = colormap->base_pixel; i <= last_pixel; i++) {
|
||||
|
||||
color.pixel = (unsigned long) i;
|
||||
color.red = (unsigned short)
|
||||
(((i/colormap->red_mult) * 65535) / colormap->red_max);
|
||||
color.pixel = (unsigned long)i;
|
||||
color.red = (unsigned short)
|
||||
(((i / colormap->red_mult) * 65535) / colormap->red_max);
|
||||
|
||||
if (vinfo->class == StaticColor) {
|
||||
color.green = (unsigned short)
|
||||
((((i/colormap->green_mult) % (colormap->green_max + 1)) *
|
||||
65535) / colormap->green_max);
|
||||
color.blue = (unsigned short)
|
||||
(((i%colormap->green_mult) * 65535) / colormap->blue_max);
|
||||
}
|
||||
else /* vinfo->class == GrayScale, old style allocation XXX */
|
||||
color.green = color.blue = color.red;
|
||||
if (vinfo->class == StaticColor) {
|
||||
color.green = (unsigned short)
|
||||
((((i / colormap->green_mult) % (colormap->green_max + 1)) *
|
||||
65535) / colormap->green_max);
|
||||
color.blue = (unsigned short)
|
||||
(((i % colormap->green_mult) * 65535) / colormap->blue_max);
|
||||
} else /* vinfo->class == GrayScale, old style allocation XXX */
|
||||
color.green = color.blue = color.red;
|
||||
|
||||
XAllocColor(dpy, colormap->colormap, &color);
|
||||
if (color.pixel != (unsigned long) i)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
XAllocColor(dpy, colormap->colormap, &color);
|
||||
if (color.pixel != (unsigned long)i)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,26 +41,23 @@ in this Software without prior written authorization from the X Consortium.
|
||||
*/
|
||||
|
||||
void XmuDeleteStandardColormap(dpy, screen, property)
|
||||
Display *dpy; /* specifies the X server to connect to */
|
||||
int screen; /* specifies the screen of the display */
|
||||
Atom property; /* specifies the standard colormap property */
|
||||
Display *dpy; /* specifies the X server to connect to */
|
||||
int screen; /* specifies the screen of the display */
|
||||
Atom property; /* specifies the standard colormap property */
|
||||
{
|
||||
XStandardColormap *stdcmaps, *s;
|
||||
int count = 0;
|
||||
XStandardColormap *stdcmaps, *s;
|
||||
int count = 0;
|
||||
|
||||
if (XGetRGBColormaps(dpy, RootWindow(dpy, screen), &stdcmaps, &count,
|
||||
property)) {
|
||||
for (s=stdcmaps; count > 0; count--, s++) {
|
||||
if ((s->killid == ReleaseByFreeingColormap) &&
|
||||
(s->colormap != None) &&
|
||||
(s->colormap != DefaultColormap(dpy, screen)))
|
||||
XFreeColormap(dpy, s->colormap);
|
||||
else if (s->killid != None)
|
||||
XKillClient(dpy, s->killid);
|
||||
}
|
||||
XDeleteProperty(dpy, RootWindow(dpy, screen), property);
|
||||
XFree((char *) stdcmaps);
|
||||
XSync(dpy, False);
|
||||
}
|
||||
if (XGetRGBColormaps(dpy, RootWindow(dpy, screen), &stdcmaps, &count, property)) {
|
||||
for (s = stdcmaps; count > 0; count--, s++) {
|
||||
if ((s->killid == ReleaseByFreeingColormap) &&
|
||||
(s->colormap != None) && (s->colormap != DefaultColormap(dpy, screen)))
|
||||
XFreeColormap(dpy, s->colormap);
|
||||
else if (s->killid != None)
|
||||
XKillClient(dpy, s->killid);
|
||||
}
|
||||
XDeleteProperty(dpy, RootWindow(dpy, screen), property);
|
||||
XFree((char *)stdcmaps);
|
||||
XSync(dpy, False);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ in this Software without prior written authorization from the X Consortium.
|
||||
#include <X11/Xutil.h>
|
||||
#include "StdCmap.h"
|
||||
|
||||
|
||||
static Status lookup();
|
||||
|
||||
/*
|
||||
@@ -66,110 +65,102 @@ static Status lookup();
|
||||
* RGB_BEST_MAP on a display whose colormap size is 16.
|
||||
*/
|
||||
|
||||
Status XmuLookupStandardColormap(dpy, screen, visualid, depth, property,
|
||||
replace, retain)
|
||||
Display *dpy; /* specifies X server connection */
|
||||
int screen; /* specifies screen of display */
|
||||
VisualID visualid; /* specifies the visual type */
|
||||
unsigned int depth; /* specifies the visual type */
|
||||
Atom property; /* a standard colormap property */
|
||||
Bool replace; /* specifies whether to replace */
|
||||
Bool retain; /* specifies whether to retain */
|
||||
Status XmuLookupStandardColormap(dpy, screen, visualid, depth, property, replace, retain)
|
||||
Display *dpy; /* specifies X server connection */
|
||||
int screen; /* specifies screen of display */
|
||||
VisualID visualid; /* specifies the visual type */
|
||||
unsigned int depth; /* specifies the visual type */
|
||||
Atom property; /* a standard colormap property */
|
||||
Bool replace; /* specifies whether to replace */
|
||||
Bool retain; /* specifies whether to retain */
|
||||
{
|
||||
Display *odpy; /* original display connection */
|
||||
XStandardColormap *colormap;
|
||||
XVisualInfo vinfo_template, *vinfo; /* visual */
|
||||
long vinfo_mask;
|
||||
unsigned long r_max, g_max, b_max; /* allocation */
|
||||
int count;
|
||||
Colormap cmap; /* colormap ID */
|
||||
Status status = 0;
|
||||
Display *odpy; /* original display connection */
|
||||
XStandardColormap *colormap;
|
||||
XVisualInfo vinfo_template, *vinfo; /* visual */
|
||||
long vinfo_mask;
|
||||
unsigned long r_max, g_max, b_max; /* allocation */
|
||||
int count;
|
||||
Colormap cmap; /* colormap ID */
|
||||
Status status = 0;
|
||||
|
||||
/* Match the requested visual */
|
||||
|
||||
/* Match the requested visual */
|
||||
vinfo_template.visualid = visualid;
|
||||
vinfo_template.screen = screen;
|
||||
vinfo_template.depth = depth;
|
||||
vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
|
||||
if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &count)) == NULL)
|
||||
return 0;
|
||||
|
||||
vinfo_template.visualid = visualid;
|
||||
vinfo_template.screen = screen;
|
||||
vinfo_template.depth = depth;
|
||||
vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
|
||||
if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &count)) ==
|
||||
NULL)
|
||||
return 0;
|
||||
/* Monochrome visuals have no standard maps */
|
||||
|
||||
/* Monochrome visuals have no standard maps */
|
||||
if (vinfo->colormap_size <= 2) {
|
||||
XFree((char *)vinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vinfo->colormap_size <= 2) {
|
||||
XFree((char *) vinfo);
|
||||
return 0;
|
||||
}
|
||||
/* If the requested property already exists on this screen, and,
|
||||
* if the replace flag has not been set to true, return success.
|
||||
* lookup() will remove a pre-existing map if replace is true.
|
||||
*/
|
||||
|
||||
/* If the requested property already exists on this screen, and,
|
||||
* if the replace flag has not been set to true, return success.
|
||||
* lookup() will remove a pre-existing map if replace is true.
|
||||
*/
|
||||
if (lookup(dpy, screen, visualid, property, (XStandardColormap *) NULL, replace) && !replace) {
|
||||
XFree((char *)vinfo);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lookup(dpy, screen, visualid, property, (XStandardColormap *) NULL,
|
||||
replace) && !replace) {
|
||||
XFree((char *) vinfo);
|
||||
return 1;
|
||||
}
|
||||
/* Determine the best allocation for this property under the requested
|
||||
* visualid and depth, and determine whether or not to use the default
|
||||
* colormap of the screen.
|
||||
*/
|
||||
|
||||
/* Determine the best allocation for this property under the requested
|
||||
* visualid and depth, and determine whether or not to use the default
|
||||
* colormap of the screen.
|
||||
*/
|
||||
if (!XmuGetColormapAllocation(vinfo, property, &r_max, &g_max, &b_max)) {
|
||||
XFree((char *)vinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!XmuGetColormapAllocation(vinfo, property, &r_max, &g_max, &b_max)) {
|
||||
XFree((char *) vinfo);
|
||||
return 0;
|
||||
}
|
||||
cmap = (property == XA_RGB_DEFAULT_MAP && visualid == XVisualIDFromVisual(DefaultVisual(dpy, screen)))
|
||||
? DefaultColormap(dpy, screen) : None;
|
||||
|
||||
cmap = (property == XA_RGB_DEFAULT_MAP &&
|
||||
visualid == XVisualIDFromVisual(DefaultVisual(dpy, screen)))
|
||||
? DefaultColormap(dpy, screen) : None;
|
||||
/* If retaining resources, open a new connection to the same server */
|
||||
|
||||
/* If retaining resources, open a new connection to the same server */
|
||||
if (retain) {
|
||||
odpy = dpy;
|
||||
if ((dpy = XOpenDisplay(XDisplayString(odpy))) == NULL) {
|
||||
XFree((char *)vinfo);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (retain) {
|
||||
odpy = dpy;
|
||||
if ((dpy = XOpenDisplay(XDisplayString(odpy))) == NULL) {
|
||||
XFree((char *) vinfo);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* Create the standard colormap */
|
||||
|
||||
/* Create the standard colormap */
|
||||
colormap = XmuStandardColormap(dpy, screen, visualid, depth, property, cmap, r_max, g_max, b_max);
|
||||
|
||||
colormap = XmuStandardColormap(dpy, screen, visualid, depth, property,
|
||||
cmap, r_max, g_max, b_max);
|
||||
/* Set the standard colormap property */
|
||||
|
||||
/* Set the standard colormap property */
|
||||
if (colormap) {
|
||||
XGrabServer(dpy);
|
||||
|
||||
if (colormap) {
|
||||
XGrabServer(dpy);
|
||||
if (lookup(dpy, screen, visualid, property, colormap, replace) && !replace) {
|
||||
/* Someone has defined the property since we last looked.
|
||||
* Since we will not replace it, release our own resources.
|
||||
* If this is the default map, our allocations will be freed
|
||||
* when this connection closes.
|
||||
*/
|
||||
if (colormap->killid == ReleaseByFreeingColormap)
|
||||
XFreeColormap(dpy, colormap->colormap);
|
||||
} else if (retain) {
|
||||
XSetCloseDownMode(dpy, RetainPermanent);
|
||||
}
|
||||
XUngrabServer(dpy);
|
||||
XFree((char *)colormap);
|
||||
status = 1;
|
||||
}
|
||||
|
||||
if (lookup(dpy, screen, visualid, property, colormap, replace) &&
|
||||
!replace) {
|
||||
/* Someone has defined the property since we last looked.
|
||||
* Since we will not replace it, release our own resources.
|
||||
* If this is the default map, our allocations will be freed
|
||||
* when this connection closes.
|
||||
*/
|
||||
if (colormap->killid == ReleaseByFreeingColormap)
|
||||
XFreeColormap(dpy, colormap->colormap);
|
||||
}
|
||||
else if (retain) {
|
||||
XSetCloseDownMode(dpy, RetainPermanent);
|
||||
}
|
||||
XUngrabServer(dpy);
|
||||
XFree((char *) colormap);
|
||||
status = 1;
|
||||
}
|
||||
|
||||
if (retain)
|
||||
XCloseDisplay(dpy);
|
||||
XFree((char *) vinfo);
|
||||
return status;
|
||||
if (retain)
|
||||
XCloseDisplay(dpy);
|
||||
XFree((char *)vinfo);
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
@@ -189,125 +180,119 @@ Status XmuLookupStandardColormap(dpy, screen, visualid, depth, property,
|
||||
*/
|
||||
|
||||
static Status lookup(dpy, screen, visualid, property, new, replace)
|
||||
Display *dpy; /* specifies display connection */
|
||||
int screen; /* specifies screen number */
|
||||
VisualID visualid; /* specifies visualid for std map */
|
||||
Atom property; /* specifies colormap property name */
|
||||
XStandardColormap *new; /* specifies a standard colormap */
|
||||
Bool replace; /* specifies whether to replace */
|
||||
Display *dpy; /* specifies display connection */
|
||||
int screen; /* specifies screen number */
|
||||
VisualID visualid; /* specifies visualid for std map */
|
||||
Atom property; /* specifies colormap property name */
|
||||
XStandardColormap *new; /* specifies a standard colormap */
|
||||
Bool replace; /* specifies whether to replace */
|
||||
{
|
||||
register int i;
|
||||
int count;
|
||||
XStandardColormap *stdcmaps, *s;
|
||||
Window win = RootWindow(dpy, screen);
|
||||
register int i;
|
||||
int count;
|
||||
XStandardColormap *stdcmaps, *s;
|
||||
Window win = RootWindow(dpy, screen);
|
||||
|
||||
/* The property does not already exist */
|
||||
/* The property does not already exist */
|
||||
|
||||
if (! XGetRGBColormaps(dpy, win, &stdcmaps, &count, property)) {
|
||||
if (new)
|
||||
XSetRGBColormaps(dpy, win, new, 1, property);
|
||||
return 0;
|
||||
}
|
||||
if (!XGetRGBColormaps(dpy, win, &stdcmaps, &count, property)) {
|
||||
if (new)
|
||||
XSetRGBColormaps(dpy, win, new, 1, property);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The property exists and is not describing the RGB_DEFAULT_MAP */
|
||||
/* The property exists and is not describing the RGB_DEFAULT_MAP */
|
||||
|
||||
if (property != XA_RGB_DEFAULT_MAP) {
|
||||
if (replace) {
|
||||
XmuDeleteStandardColormap(dpy, screen, property);
|
||||
if (new)
|
||||
XSetRGBColormaps(dpy, win, new, 1, property);
|
||||
}
|
||||
XFree((char *)stdcmaps);
|
||||
return 1;
|
||||
}
|
||||
if (property != XA_RGB_DEFAULT_MAP) {
|
||||
if (replace) {
|
||||
XmuDeleteStandardColormap(dpy, screen, property);
|
||||
if (new)
|
||||
XSetRGBColormaps(dpy, win, new, 1, property);
|
||||
}
|
||||
XFree((char *)stdcmaps);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The property exists and is RGB_DEFAULT_MAP */
|
||||
/* The property exists and is RGB_DEFAULT_MAP */
|
||||
|
||||
for (i=0, s=stdcmaps; (i < count) && (s->visualid != visualid); i++, s++)
|
||||
;
|
||||
for (i = 0, s = stdcmaps; (i < count) && (s->visualid != visualid); i++, s++) ;
|
||||
|
||||
/* No RGB_DEFAULT_MAP property matches the given visualid */
|
||||
/* No RGB_DEFAULT_MAP property matches the given visualid */
|
||||
|
||||
if (i == count) {
|
||||
if (new) {
|
||||
XStandardColormap *m, *maps;
|
||||
if (i == count) {
|
||||
if (new) {
|
||||
XStandardColormap *m, *maps;
|
||||
|
||||
s = (XStandardColormap *) malloc((unsigned) ((count+1) * sizeof
|
||||
(XStandardColormap)));
|
||||
s = (XStandardColormap *) malloc((unsigned)((count + 1) * sizeof(XStandardColormap)));
|
||||
|
||||
for (i = 0, m = s, maps = stdcmaps; i < count; i++, m++, maps++) {
|
||||
m->colormap = maps->colormap;
|
||||
m->red_max = maps->red_max;
|
||||
m->red_mult = maps->red_mult;
|
||||
m->green_max = maps->green_max;
|
||||
m->green_mult = maps->green_mult;
|
||||
m->blue_max = maps->blue_max;
|
||||
m->blue_mult = maps->blue_mult;
|
||||
m->base_pixel = maps->base_pixel;
|
||||
m->visualid = maps->visualid;
|
||||
m->killid = maps->killid;
|
||||
}
|
||||
m->colormap = new->colormap;
|
||||
m->red_max = new->red_max;
|
||||
m->red_mult = new->red_mult;
|
||||
m->green_max = new->green_max;
|
||||
m->green_mult = new->green_mult;
|
||||
m->blue_max = new->blue_max;
|
||||
m->blue_mult = new->blue_mult;
|
||||
m->base_pixel = new->base_pixel;
|
||||
m->visualid = new->visualid;
|
||||
m->killid = new->killid;
|
||||
for (i = 0, m = s, maps = stdcmaps; i < count; i++, m++, maps++) {
|
||||
m->colormap = maps->colormap;
|
||||
m->red_max = maps->red_max;
|
||||
m->red_mult = maps->red_mult;
|
||||
m->green_max = maps->green_max;
|
||||
m->green_mult = maps->green_mult;
|
||||
m->blue_max = maps->blue_max;
|
||||
m->blue_mult = maps->blue_mult;
|
||||
m->base_pixel = maps->base_pixel;
|
||||
m->visualid = maps->visualid;
|
||||
m->killid = maps->killid;
|
||||
}
|
||||
m->colormap = new->colormap;
|
||||
m->red_max = new->red_max;
|
||||
m->red_mult = new->red_mult;
|
||||
m->green_max = new->green_max;
|
||||
m->green_mult = new->green_mult;
|
||||
m->blue_max = new->blue_max;
|
||||
m->blue_mult = new->blue_mult;
|
||||
m->base_pixel = new->base_pixel;
|
||||
m->visualid = new->visualid;
|
||||
m->killid = new->killid;
|
||||
|
||||
XSetRGBColormaps(dpy, win, s, ++count, property);
|
||||
free((char *) s);
|
||||
}
|
||||
XFree((char *) stdcmaps);
|
||||
return 0;
|
||||
}
|
||||
XSetRGBColormaps(dpy, win, s, ++count, property);
|
||||
free((char *)s);
|
||||
}
|
||||
XFree((char *)stdcmaps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Found an RGB_DEFAULT_MAP property with a matching visualid */
|
||||
/* Found an RGB_DEFAULT_MAP property with a matching visualid */
|
||||
|
||||
if (replace) {
|
||||
/* Free old resources first - we may need them, particularly in
|
||||
* the default colormap of the screen. However, because of this,
|
||||
* it is possible that we will destroy the old resource and fail
|
||||
* to create a new one if XmuStandardColormap() fails.
|
||||
*/
|
||||
if (replace) {
|
||||
/* Free old resources first - we may need them, particularly in
|
||||
* the default colormap of the screen. However, because of this,
|
||||
* it is possible that we will destroy the old resource and fail
|
||||
* to create a new one if XmuStandardColormap() fails.
|
||||
*/
|
||||
|
||||
if (count == 1) {
|
||||
XmuDeleteStandardColormap(dpy, screen, property);
|
||||
if (new)
|
||||
XSetRGBColormaps(dpy, win, new, 1, property);
|
||||
}
|
||||
else {
|
||||
XStandardColormap *map;
|
||||
if (count == 1) {
|
||||
XmuDeleteStandardColormap(dpy, screen, property);
|
||||
if (new)
|
||||
XSetRGBColormaps(dpy, win, new, 1, property);
|
||||
} else {
|
||||
XStandardColormap *map;
|
||||
|
||||
/* s still points to the matching standard colormap */
|
||||
/* s still points to the matching standard colormap */
|
||||
|
||||
if (s->killid == ReleaseByFreeingColormap) {
|
||||
if ((s->colormap != None) &&
|
||||
(s->colormap != DefaultColormap(dpy, screen)))
|
||||
XFreeColormap(dpy, s->colormap);
|
||||
}
|
||||
else if (s->killid != None)
|
||||
XKillClient(dpy, s->killid);
|
||||
if (s->killid == ReleaseByFreeingColormap) {
|
||||
if ((s->colormap != None) && (s->colormap != DefaultColormap(dpy, screen)))
|
||||
XFreeColormap(dpy, s->colormap);
|
||||
} else if (s->killid != None)
|
||||
XKillClient(dpy, s->killid);
|
||||
|
||||
map = (new) ? new : stdcmaps + --count;
|
||||
map = (new) ? new : stdcmaps + --count;
|
||||
|
||||
s->colormap = map->colormap;
|
||||
s->red_max = map->red_max;
|
||||
s->red_mult = map->red_mult;
|
||||
s->green_max = map->green_max;
|
||||
s->green_mult = map->green_mult;
|
||||
s->blue_max = map->blue_max;
|
||||
s->blue_mult = map->blue_mult;
|
||||
s->visualid = map->visualid;
|
||||
s->killid = map->killid;
|
||||
s->colormap = map->colormap;
|
||||
s->red_max = map->red_max;
|
||||
s->red_mult = map->red_mult;
|
||||
s->green_max = map->green_max;
|
||||
s->green_mult = map->green_mult;
|
||||
s->blue_max = map->blue_max;
|
||||
s->blue_mult = map->blue_mult;
|
||||
s->visualid = map->visualid;
|
||||
s->killid = map->killid;
|
||||
|
||||
XSetRGBColormaps(dpy, win, stdcmaps, count, property);
|
||||
}
|
||||
}
|
||||
XFree((char *) stdcmaps);
|
||||
return 1;
|
||||
XSetRGBColormaps(dpy, win, stdcmaps, count, property);
|
||||
}
|
||||
}
|
||||
XFree((char *)stdcmaps);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
276
wrlib/StdCmap.c
276
wrlib/StdCmap.c
@@ -39,7 +39,7 @@ in this Software without prior written authorization from the X Consortium.
|
||||
|
||||
#define lowbit(x) ((x) & (~(x) + 1))
|
||||
|
||||
static Status valid_args(); /* argument restrictions */
|
||||
static Status valid_args(); /* argument restrictions */
|
||||
|
||||
/*
|
||||
* To create any one standard colormap, use XmuStandardColormap().
|
||||
@@ -56,165 +56,161 @@ static Status valid_args(); /* argument restrictions */
|
||||
* caller's responsibility.
|
||||
*/
|
||||
|
||||
XStandardColormap *XmuStandardColormap(dpy, screen, visualid, depth, property,
|
||||
cmap, red_max, green_max, blue_max)
|
||||
Display *dpy; /* specifies X server connection */
|
||||
int screen; /* specifies display screen */
|
||||
VisualID visualid; /* identifies the visual type */
|
||||
unsigned int depth; /* identifies the visual type */
|
||||
Atom property; /* a standard colormap property */
|
||||
Colormap cmap; /* specifies colormap ID or None */
|
||||
unsigned long red_max, green_max, blue_max; /* allocations */
|
||||
XStandardColormap *XmuStandardColormap(dpy, screen, visualid, depth, property, cmap, red_max, green_max, blue_max)
|
||||
Display *dpy; /* specifies X server connection */
|
||||
int screen; /* specifies display screen */
|
||||
VisualID visualid; /* identifies the visual type */
|
||||
unsigned int depth; /* identifies the visual type */
|
||||
Atom property; /* a standard colormap property */
|
||||
Colormap cmap; /* specifies colormap ID or None */
|
||||
unsigned long red_max, green_max, blue_max; /* allocations */
|
||||
{
|
||||
XStandardColormap *stdcmap;
|
||||
Status status;
|
||||
XVisualInfo vinfo_template, *vinfo;
|
||||
long vinfo_mask;
|
||||
int n;
|
||||
XStandardColormap *stdcmap;
|
||||
Status status;
|
||||
XVisualInfo vinfo_template, *vinfo;
|
||||
long vinfo_mask;
|
||||
int n;
|
||||
|
||||
/* Match the required visual information to an actual visual */
|
||||
vinfo_template.visualid = visualid;
|
||||
vinfo_template.screen = screen;
|
||||
vinfo_template.depth = depth;
|
||||
vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
|
||||
if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
|
||||
return 0;
|
||||
/* Match the required visual information to an actual visual */
|
||||
vinfo_template.visualid = visualid;
|
||||
vinfo_template.screen = screen;
|
||||
vinfo_template.depth = depth;
|
||||
vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
|
||||
if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
|
||||
return 0;
|
||||
|
||||
/* Check the validity of the combination of visual characteristics,
|
||||
* allocation, and colormap property. Create an XStandardColormap
|
||||
* structure.
|
||||
*/
|
||||
/* Check the validity of the combination of visual characteristics,
|
||||
* allocation, and colormap property. Create an XStandardColormap
|
||||
* structure.
|
||||
*/
|
||||
|
||||
if (! valid_args(vinfo, red_max, green_max, blue_max, property)
|
||||
|| ((stdcmap = XAllocStandardColormap()) == NULL)) {
|
||||
XFree((char *) vinfo);
|
||||
return 0;
|
||||
}
|
||||
if (!valid_args(vinfo, red_max, green_max, blue_max, property)
|
||||
|| ((stdcmap = XAllocStandardColormap()) == NULL)) {
|
||||
XFree((char *)vinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Fill in the XStandardColormap structure */
|
||||
/* Fill in the XStandardColormap structure */
|
||||
|
||||
if (cmap == DefaultColormap(dpy, screen)) {
|
||||
/* Allocating out of the default map, cannot use XFreeColormap() */
|
||||
Window win = XCreateWindow(dpy, RootWindow(dpy, screen), 1, 1, 1, 1,
|
||||
0, 0, InputOnly, vinfo->visual,
|
||||
(unsigned long) 0,
|
||||
(XSetWindowAttributes *)NULL);
|
||||
stdcmap->killid = (XID) XCreatePixmap(dpy, win, 1, 1, depth);
|
||||
XDestroyWindow(dpy, win);
|
||||
stdcmap->colormap = cmap;
|
||||
} else {
|
||||
stdcmap->killid = ReleaseByFreeingColormap;
|
||||
stdcmap->colormap = XCreateColormap(dpy, RootWindow(dpy, screen),
|
||||
vinfo->visual, AllocNone);
|
||||
}
|
||||
stdcmap->red_max = red_max;
|
||||
stdcmap->green_max = green_max;
|
||||
stdcmap->blue_max = blue_max;
|
||||
if (property == XA_RGB_GRAY_MAP)
|
||||
stdcmap->red_mult = stdcmap->green_mult = stdcmap->blue_mult = 1;
|
||||
else if (vinfo->class == TrueColor || vinfo->class == DirectColor) {
|
||||
stdcmap->red_mult = lowbit(vinfo->red_mask);
|
||||
stdcmap->green_mult = lowbit(vinfo->green_mask);
|
||||
stdcmap->blue_mult = lowbit(vinfo->blue_mask);
|
||||
} else {
|
||||
stdcmap->red_mult = (red_max > 0)
|
||||
? (green_max + 1) * (blue_max + 1) : 0;
|
||||
stdcmap->green_mult = (green_max > 0) ? blue_max + 1 : 0;
|
||||
stdcmap->blue_mult = (blue_max > 0) ? 1 : 0;
|
||||
}
|
||||
stdcmap->base_pixel = 0; /* base pixel may change */
|
||||
stdcmap->visualid = vinfo->visualid;
|
||||
if (cmap == DefaultColormap(dpy, screen)) {
|
||||
/* Allocating out of the default map, cannot use XFreeColormap() */
|
||||
Window win = XCreateWindow(dpy, RootWindow(dpy, screen), 1, 1, 1, 1,
|
||||
0, 0, InputOnly, vinfo->visual,
|
||||
(unsigned long)0,
|
||||
(XSetWindowAttributes *) NULL);
|
||||
stdcmap->killid = (XID) XCreatePixmap(dpy, win, 1, 1, depth);
|
||||
XDestroyWindow(dpy, win);
|
||||
stdcmap->colormap = cmap;
|
||||
} else {
|
||||
stdcmap->killid = ReleaseByFreeingColormap;
|
||||
stdcmap->colormap = XCreateColormap(dpy, RootWindow(dpy, screen), vinfo->visual, AllocNone);
|
||||
}
|
||||
stdcmap->red_max = red_max;
|
||||
stdcmap->green_max = green_max;
|
||||
stdcmap->blue_max = blue_max;
|
||||
if (property == XA_RGB_GRAY_MAP)
|
||||
stdcmap->red_mult = stdcmap->green_mult = stdcmap->blue_mult = 1;
|
||||
else if (vinfo->class == TrueColor || vinfo->class == DirectColor) {
|
||||
stdcmap->red_mult = lowbit(vinfo->red_mask);
|
||||
stdcmap->green_mult = lowbit(vinfo->green_mask);
|
||||
stdcmap->blue_mult = lowbit(vinfo->blue_mask);
|
||||
} else {
|
||||
stdcmap->red_mult = (red_max > 0)
|
||||
? (green_max + 1) * (blue_max + 1) : 0;
|
||||
stdcmap->green_mult = (green_max > 0) ? blue_max + 1 : 0;
|
||||
stdcmap->blue_mult = (blue_max > 0) ? 1 : 0;
|
||||
}
|
||||
stdcmap->base_pixel = 0; /* base pixel may change */
|
||||
stdcmap->visualid = vinfo->visualid;
|
||||
|
||||
/* Make the colormap */
|
||||
/* Make the colormap */
|
||||
|
||||
status = XmuCreateColormap(dpy, stdcmap);
|
||||
status = XmuCreateColormap(dpy, stdcmap);
|
||||
|
||||
/* Clean up */
|
||||
/* Clean up */
|
||||
|
||||
XFree((char *) vinfo);
|
||||
if (!status) {
|
||||
XFree((char *)vinfo);
|
||||
if (!status) {
|
||||
|
||||
/* Free the colormap or the pixmap, if we created one */
|
||||
if (stdcmap->killid == ReleaseByFreeingColormap)
|
||||
XFreeColormap(dpy, stdcmap->colormap);
|
||||
else if (stdcmap->killid != None)
|
||||
XFreePixmap(dpy, stdcmap->killid);
|
||||
/* Free the colormap or the pixmap, if we created one */
|
||||
if (stdcmap->killid == ReleaseByFreeingColormap)
|
||||
XFreeColormap(dpy, stdcmap->colormap);
|
||||
else if (stdcmap->killid != None)
|
||||
XFreePixmap(dpy, stdcmap->killid);
|
||||
|
||||
XFree((char *) stdcmap);
|
||||
return (XStandardColormap *) NULL;
|
||||
}
|
||||
return stdcmap;
|
||||
XFree((char *)stdcmap);
|
||||
return (XStandardColormap *) NULL;
|
||||
}
|
||||
return stdcmap;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
static Status valid_args(vinfo, red_max, green_max, blue_max, property)
|
||||
XVisualInfo *vinfo; /* specifies visual */
|
||||
unsigned long red_max, green_max, blue_max; /* specifies alloc */
|
||||
Atom property; /* specifies property name */
|
||||
XVisualInfo *vinfo; /* specifies visual */
|
||||
unsigned long red_max, green_max, blue_max; /* specifies alloc */
|
||||
Atom property; /* specifies property name */
|
||||
{
|
||||
unsigned long ncolors; /* number of colors requested */
|
||||
unsigned long ncolors; /* number of colors requested */
|
||||
|
||||
/* Determine that the number of colors requested is <= map size */
|
||||
/* Determine that the number of colors requested is <= map size */
|
||||
|
||||
if ((vinfo->class == DirectColor) || (vinfo->class == TrueColor)) {
|
||||
unsigned long mask;
|
||||
if ((vinfo->class == DirectColor) || (vinfo->class == TrueColor)) {
|
||||
unsigned long mask;
|
||||
|
||||
mask = vinfo->red_mask;
|
||||
while (!(mask & 1))
|
||||
mask >>= 1;
|
||||
if (red_max > mask)
|
||||
return 0;
|
||||
mask = vinfo->green_mask;
|
||||
while (!(mask & 1))
|
||||
mask >>= 1;
|
||||
if (green_max > mask)
|
||||
return 0;
|
||||
mask = vinfo->blue_mask;
|
||||
while (!(mask & 1))
|
||||
mask >>= 1;
|
||||
if (blue_max > mask)
|
||||
return 0;
|
||||
} else if (property == XA_RGB_GRAY_MAP) {
|
||||
ncolors = red_max + green_max + blue_max + 1;
|
||||
if (ncolors > vinfo->colormap_size)
|
||||
return 0;
|
||||
} else {
|
||||
ncolors = (red_max + 1) * (green_max + 1) * (blue_max + 1);
|
||||
if (ncolors > vinfo->colormap_size)
|
||||
return 0;
|
||||
}
|
||||
mask = vinfo->red_mask;
|
||||
while (!(mask & 1))
|
||||
mask >>= 1;
|
||||
if (red_max > mask)
|
||||
return 0;
|
||||
mask = vinfo->green_mask;
|
||||
while (!(mask & 1))
|
||||
mask >>= 1;
|
||||
if (green_max > mask)
|
||||
return 0;
|
||||
mask = vinfo->blue_mask;
|
||||
while (!(mask & 1))
|
||||
mask >>= 1;
|
||||
if (blue_max > mask)
|
||||
return 0;
|
||||
} else if (property == XA_RGB_GRAY_MAP) {
|
||||
ncolors = red_max + green_max + blue_max + 1;
|
||||
if (ncolors > vinfo->colormap_size)
|
||||
return 0;
|
||||
} else {
|
||||
ncolors = (red_max + 1) * (green_max + 1) * (blue_max + 1);
|
||||
if (ncolors > vinfo->colormap_size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Determine that the allocation and visual make sense for the property */
|
||||
/* Determine that the allocation and visual make sense for the property */
|
||||
|
||||
switch (property)
|
||||
{
|
||||
case XA_RGB_DEFAULT_MAP:
|
||||
if (red_max == 0 || green_max == 0 || blue_max == 0)
|
||||
return 0;
|
||||
break;
|
||||
case XA_RGB_RED_MAP:
|
||||
if (red_max == 0)
|
||||
return 0;
|
||||
break;
|
||||
case XA_RGB_GREEN_MAP:
|
||||
if (green_max == 0)
|
||||
return 0;
|
||||
break;
|
||||
case XA_RGB_BLUE_MAP:
|
||||
if (blue_max == 0)
|
||||
return 0;
|
||||
break;
|
||||
case XA_RGB_BEST_MAP:
|
||||
if (red_max == 0 || green_max == 0 || blue_max == 0)
|
||||
return 0;
|
||||
break;
|
||||
case XA_RGB_GRAY_MAP:
|
||||
if (red_max == 0 || blue_max == 0 || green_max == 0)
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
switch (property) {
|
||||
case XA_RGB_DEFAULT_MAP:
|
||||
if (red_max == 0 || green_max == 0 || blue_max == 0)
|
||||
return 0;
|
||||
break;
|
||||
case XA_RGB_RED_MAP:
|
||||
if (red_max == 0)
|
||||
return 0;
|
||||
break;
|
||||
case XA_RGB_GREEN_MAP:
|
||||
if (green_max == 0)
|
||||
return 0;
|
||||
break;
|
||||
case XA_RGB_BLUE_MAP:
|
||||
if (blue_max == 0)
|
||||
return 0;
|
||||
break;
|
||||
case XA_RGB_BEST_MAP:
|
||||
if (red_max == 0 || green_max == 0 || blue_max == 0)
|
||||
return 0;
|
||||
break;
|
||||
case XA_RGB_GRAY_MAP:
|
||||
if (red_max == 0 || blue_max == 0 || green_max == 0)
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
505
wrlib/alloca.c
505
wrlib/alloca.c
@@ -50,23 +50,18 @@
|
||||
in order to make unexec workable
|
||||
*/
|
||||
#ifndef STACK_DIRECTION
|
||||
you
|
||||
lose
|
||||
-- must know STACK_DIRECTION at compile-time
|
||||
#endif /* STACK_DIRECTION undefined */
|
||||
#endif /* static */
|
||||
#endif /* emacs */
|
||||
|
||||
you lose-- must know STACK_DIRECTION at compile - time
|
||||
#endif /* STACK_DIRECTION undefined */
|
||||
#endif /* static */
|
||||
#endif /* emacs */
|
||||
/* If your stack is a linked list of frames, you have to
|
||||
provide an "address metric" ADDRESS_FUNCTION macro. */
|
||||
|
||||
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
long i00afunc ();
|
||||
long i00afunc();
|
||||
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
|
||||
#else
|
||||
#define ADDRESS_FUNCTION(arg) &(arg)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
typedef void *pointer;
|
||||
#else
|
||||
@@ -90,7 +85,7 @@ typedef char *pointer;
|
||||
#ifndef emacs
|
||||
#define malloc xmalloc
|
||||
#endif
|
||||
extern pointer malloc ();
|
||||
extern pointer malloc();
|
||||
|
||||
/* Define STACK_DIRECTION if you know the direction of stack
|
||||
growth for your system; otherwise it will be automatically
|
||||
@@ -108,34 +103,30 @@ extern pointer malloc ();
|
||||
|
||||
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
|
||||
|
||||
#else /* STACK_DIRECTION == 0; need run-time code. */
|
||||
#else /* STACK_DIRECTION == 0; need run-time code. */
|
||||
|
||||
static int stack_dir; /* 1 or -1 once known. */
|
||||
#define STACK_DIR stack_dir
|
||||
|
||||
static void
|
||||
find_stack_direction ()
|
||||
static void find_stack_direction()
|
||||
{
|
||||
static char *addr = NULL; /* Address of first `dummy', once known. */
|
||||
auto char dummy; /* To get stack address. */
|
||||
static char *addr = NULL; /* Address of first `dummy', once known. */
|
||||
auto char dummy; /* To get stack address. */
|
||||
|
||||
if (addr == NULL)
|
||||
{ /* Initial entry. */
|
||||
addr = ADDRESS_FUNCTION (dummy);
|
||||
if (addr == NULL) { /* Initial entry. */
|
||||
addr = ADDRESS_FUNCTION(dummy);
|
||||
|
||||
find_stack_direction (); /* Recurse once. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Second entry. */
|
||||
if (ADDRESS_FUNCTION (dummy) > addr)
|
||||
stack_dir = 1; /* Stack grew upward. */
|
||||
else
|
||||
stack_dir = -1; /* Stack grew downward. */
|
||||
}
|
||||
find_stack_direction(); /* Recurse once. */
|
||||
} else {
|
||||
/* Second entry. */
|
||||
if (ADDRESS_FUNCTION(dummy) > addr)
|
||||
stack_dir = 1; /* Stack grew upward. */
|
||||
else
|
||||
stack_dir = -1; /* Stack grew downward. */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* STACK_DIRECTION == 0 */
|
||||
#endif /* STACK_DIRECTION == 0 */
|
||||
|
||||
/* An "alloca header" is used to:
|
||||
(a) chain together all alloca'ed blocks;
|
||||
@@ -148,14 +139,12 @@ find_stack_direction ()
|
||||
#define ALIGN_SIZE sizeof(double)
|
||||
#endif
|
||||
|
||||
typedef union hdr
|
||||
{
|
||||
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||
struct
|
||||
{
|
||||
union hdr *next; /* For chaining headers. */
|
||||
char *deep; /* For stack depth measure. */
|
||||
} h;
|
||||
typedef union hdr {
|
||||
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||
struct {
|
||||
union hdr *next; /* For chaining headers. */
|
||||
char *deep; /* For stack depth measure. */
|
||||
} h;
|
||||
} header;
|
||||
|
||||
static header *last_alloca_header = NULL; /* -> last alloca header. */
|
||||
@@ -167,69 +156,66 @@ static header *last_alloca_header = NULL; /* -> last alloca header. */
|
||||
caller, but that method cannot be made to work for some
|
||||
implementations of C, for example under Gould's UTX/32. */
|
||||
|
||||
pointer
|
||||
alloca (size)
|
||||
unsigned size;
|
||||
pointer alloca(size)
|
||||
unsigned size;
|
||||
{
|
||||
auto char probe; /* Probes stack depth: */
|
||||
register char *depth = ADDRESS_FUNCTION (probe);
|
||||
auto char probe; /* Probes stack depth: */
|
||||
register char *depth = ADDRESS_FUNCTION(probe);
|
||||
|
||||
#if STACK_DIRECTION == 0
|
||||
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||
find_stack_direction ();
|
||||
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||
find_stack_direction();
|
||||
#endif
|
||||
|
||||
/* Reclaim garbage, defined as all alloca'd storage that
|
||||
was allocated from deeper in the stack than currently. */
|
||||
/* Reclaim garbage, defined as all alloca'd storage that
|
||||
was allocated from deeper in the stack than currently. */
|
||||
|
||||
{
|
||||
register header *hp; /* Traverses linked list. */
|
||||
{
|
||||
register header *hp; /* Traverses linked list. */
|
||||
|
||||
#ifdef emacs
|
||||
BLOCK_INPUT;
|
||||
BLOCK_INPUT;
|
||||
#endif
|
||||
|
||||
for (hp = last_alloca_header; hp != NULL;)
|
||||
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
||||
{
|
||||
register header *np = hp->h.next;
|
||||
for (hp = last_alloca_header; hp != NULL;)
|
||||
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||
|| (STACK_DIR < 0 && hp->h.deep < depth)) {
|
||||
register header *np = hp->h.next;
|
||||
|
||||
free ((pointer) hp); /* Collect garbage. */
|
||||
free((pointer) hp); /* Collect garbage. */
|
||||
|
||||
hp = np; /* -> next header. */
|
||||
}
|
||||
else
|
||||
break; /* Rest are not deeper. */
|
||||
hp = np; /* -> next header. */
|
||||
} else
|
||||
break; /* Rest are not deeper. */
|
||||
|
||||
last_alloca_header = hp; /* -> last valid storage. */
|
||||
last_alloca_header = hp; /* -> last valid storage. */
|
||||
|
||||
#ifdef emacs
|
||||
UNBLOCK_INPUT;
|
||||
UNBLOCK_INPUT;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return NULL; /* No allocation required. */
|
||||
if (size == 0)
|
||||
return NULL; /* No allocation required. */
|
||||
|
||||
/* Allocate combined header + user data storage. */
|
||||
/* Allocate combined header + user data storage. */
|
||||
|
||||
{
|
||||
register pointer new = malloc (sizeof (header) + size);
|
||||
/* Address of header. */
|
||||
{
|
||||
register pointer new = malloc(sizeof(header) + size);
|
||||
/* Address of header. */
|
||||
|
||||
if (new == 0)
|
||||
abort();
|
||||
if (new == 0)
|
||||
abort();
|
||||
|
||||
((header *) new)->h.next = last_alloca_header;
|
||||
((header *) new)->h.deep = depth;
|
||||
((header *) new)->h.next = last_alloca_header;
|
||||
((header *) new)->h.deep = depth;
|
||||
|
||||
last_alloca_header = (header *) new;
|
||||
last_alloca_header = (header *) new;
|
||||
|
||||
/* User storage begins just after header. */
|
||||
/* User storage begins just after header. */
|
||||
|
||||
return (pointer) ((char *) new + sizeof (header));
|
||||
}
|
||||
return (pointer) ((char *)new + sizeof(header));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
@@ -242,12 +228,11 @@ alloca (size)
|
||||
#define CRAY_STACK
|
||||
#ifndef CRAY2
|
||||
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
|
||||
struct stack_control_header
|
||||
{
|
||||
long shgrow:32; /* Number of times stack has grown. */
|
||||
long shaseg:32; /* Size of increments to stack. */
|
||||
long shhwm:32; /* High water mark of stack. */
|
||||
long shsize:32; /* Current size of stack (all segments). */
|
||||
struct stack_control_header {
|
||||
long shgrow:32; /* Number of times stack has grown. */
|
||||
long shaseg:32; /* Size of increments to stack. */
|
||||
long shhwm:32; /* High water mark of stack. */
|
||||
long shsize:32; /* Current size of stack (all segments). */
|
||||
};
|
||||
|
||||
/* The stack segment linkage control information occurs at
|
||||
@@ -257,248 +242,236 @@ struct stack_control_header
|
||||
0200 (octal) words. This provides for register storage
|
||||
for the routine which overflows the stack. */
|
||||
|
||||
struct stack_segment_linkage
|
||||
{
|
||||
long ss[0200]; /* 0200 overflow words. */
|
||||
long sssize:32; /* Number of words in this segment. */
|
||||
long ssbase:32; /* Offset to stack base. */
|
||||
long:32;
|
||||
long sspseg:32; /* Offset to linkage control of previous
|
||||
segment of stack. */
|
||||
long:32;
|
||||
long sstcpt:32; /* Pointer to task common address block. */
|
||||
long sscsnm; /* Private control structure number for
|
||||
microtasking. */
|
||||
long ssusr1; /* Reserved for user. */
|
||||
long ssusr2; /* Reserved for user. */
|
||||
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||
long sscray[7]; /* Reserved for Cray Research. */
|
||||
long ssa0;
|
||||
long ssa1;
|
||||
long ssa2;
|
||||
long ssa3;
|
||||
long ssa4;
|
||||
long ssa5;
|
||||
long ssa6;
|
||||
long ssa7;
|
||||
long sss0;
|
||||
long sss1;
|
||||
long sss2;
|
||||
long sss3;
|
||||
long sss4;
|
||||
long sss5;
|
||||
long sss6;
|
||||
long sss7;
|
||||
struct stack_segment_linkage {
|
||||
long ss[0200]; /* 0200 overflow words. */
|
||||
long sssize:32; /* Number of words in this segment. */
|
||||
long ssbase:32; /* Offset to stack base. */
|
||||
long:32;
|
||||
long sspseg:32; /* Offset to linkage control of previous
|
||||
segment of stack. */
|
||||
long:32;
|
||||
long sstcpt:32; /* Pointer to task common address block. */
|
||||
long sscsnm; /* Private control structure number for
|
||||
microtasking. */
|
||||
long ssusr1; /* Reserved for user. */
|
||||
long ssusr2; /* Reserved for user. */
|
||||
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||
long sscray[7]; /* Reserved for Cray Research. */
|
||||
long ssa0;
|
||||
long ssa1;
|
||||
long ssa2;
|
||||
long ssa3;
|
||||
long ssa4;
|
||||
long ssa5;
|
||||
long ssa6;
|
||||
long ssa7;
|
||||
long sss0;
|
||||
long sss1;
|
||||
long sss2;
|
||||
long sss3;
|
||||
long sss4;
|
||||
long sss5;
|
||||
long sss6;
|
||||
long sss7;
|
||||
};
|
||||
|
||||
#else /* CRAY2 */
|
||||
#else /* CRAY2 */
|
||||
/* The following structure defines the vector of words
|
||||
returned by the STKSTAT library routine. */
|
||||
struct stk_stat
|
||||
{
|
||||
long now; /* Current total stack size. */
|
||||
long maxc; /* Amount of contiguous space which would
|
||||
be required to satisfy the maximum
|
||||
stack demand to date. */
|
||||
long high_water; /* Stack high-water mark. */
|
||||
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||
long hits; /* Number of internal buffer hits. */
|
||||
long extends; /* Number of block extensions. */
|
||||
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||
long segments; /* Current number of stack segments. */
|
||||
long maxs; /* Maximum number of stack segments so far. */
|
||||
long pad_size; /* Stack pad size. */
|
||||
long current_address; /* Current stack segment address. */
|
||||
long current_size; /* Current stack segment size. This
|
||||
number is actually corrupted by STKSTAT to
|
||||
include the fifteen word trailer area. */
|
||||
long initial_address; /* Address of initial segment. */
|
||||
long initial_size; /* Size of initial segment. */
|
||||
struct stk_stat {
|
||||
long now; /* Current total stack size. */
|
||||
long maxc; /* Amount of contiguous space which would
|
||||
be required to satisfy the maximum
|
||||
stack demand to date. */
|
||||
long high_water; /* Stack high-water mark. */
|
||||
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||
long hits; /* Number of internal buffer hits. */
|
||||
long extends; /* Number of block extensions. */
|
||||
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||
long segments; /* Current number of stack segments. */
|
||||
long maxs; /* Maximum number of stack segments so far. */
|
||||
long pad_size; /* Stack pad size. */
|
||||
long current_address; /* Current stack segment address. */
|
||||
long current_size; /* Current stack segment size. This
|
||||
number is actually corrupted by STKSTAT to
|
||||
include the fifteen word trailer area. */
|
||||
long initial_address; /* Address of initial segment. */
|
||||
long initial_size; /* Size of initial segment. */
|
||||
};
|
||||
|
||||
/* The following structure describes the data structure which trails
|
||||
any stack segment. I think that the description in 'asdef' is
|
||||
out of date. I only describe the parts that I am sure about. */
|
||||
|
||||
struct stk_trailer
|
||||
{
|
||||
long this_address; /* Address of this block. */
|
||||
long this_size; /* Size of this block (does not include
|
||||
this trailer). */
|
||||
long unknown2;
|
||||
long unknown3;
|
||||
long link; /* Address of trailer block of previous
|
||||
segment. */
|
||||
long unknown5;
|
||||
long unknown6;
|
||||
long unknown7;
|
||||
long unknown8;
|
||||
long unknown9;
|
||||
long unknown10;
|
||||
long unknown11;
|
||||
long unknown12;
|
||||
long unknown13;
|
||||
long unknown14;
|
||||
struct stk_trailer {
|
||||
long this_address; /* Address of this block. */
|
||||
long this_size; /* Size of this block (does not include
|
||||
this trailer). */
|
||||
long unknown2;
|
||||
long unknown3;
|
||||
long link; /* Address of trailer block of previous
|
||||
segment. */
|
||||
long unknown5;
|
||||
long unknown6;
|
||||
long unknown7;
|
||||
long unknown8;
|
||||
long unknown9;
|
||||
long unknown10;
|
||||
long unknown11;
|
||||
long unknown12;
|
||||
long unknown13;
|
||||
long unknown14;
|
||||
};
|
||||
|
||||
#endif /* CRAY2 */
|
||||
#endif /* not CRAY_STACK */
|
||||
#endif /* CRAY2 */
|
||||
#endif /* not CRAY_STACK */
|
||||
|
||||
#ifdef CRAY2
|
||||
/* Determine a "stack measure" for an arbitrary ADDRESS.
|
||||
I doubt that "lint" will like this much. */
|
||||
|
||||
static long
|
||||
i00afunc (long *address)
|
||||
static long i00afunc(long *address)
|
||||
{
|
||||
struct stk_stat status;
|
||||
struct stk_trailer *trailer;
|
||||
long *block, size;
|
||||
long result = 0;
|
||||
struct stk_stat status;
|
||||
struct stk_trailer *trailer;
|
||||
long *block, size;
|
||||
long result = 0;
|
||||
|
||||
/* We want to iterate through all of the segments. The first
|
||||
step is to get the stack status structure. We could do this
|
||||
more quickly and more directly, perhaps, by referencing the
|
||||
$LM00 common block, but I know that this works. */
|
||||
/* We want to iterate through all of the segments. The first
|
||||
step is to get the stack status structure. We could do this
|
||||
more quickly and more directly, perhaps, by referencing the
|
||||
$LM00 common block, but I know that this works. */
|
||||
|
||||
STKSTAT (&status);
|
||||
STKSTAT(&status);
|
||||
|
||||
/* Set up the iteration. */
|
||||
/* Set up the iteration. */
|
||||
|
||||
trailer = (struct stk_trailer *) (status.current_address
|
||||
+ status.current_size
|
||||
- 15);
|
||||
trailer = (struct stk_trailer *)(status.current_address + status.current_size - 15);
|
||||
|
||||
/* There must be at least one stack segment. Therefore it is
|
||||
a fatal error if "trailer" is null. */
|
||||
/* There must be at least one stack segment. Therefore it is
|
||||
a fatal error if "trailer" is null. */
|
||||
|
||||
if (trailer == 0)
|
||||
abort ();
|
||||
if (trailer == 0)
|
||||
abort();
|
||||
|
||||
/* Discard segments that do not contain our argument address. */
|
||||
/* Discard segments that do not contain our argument address. */
|
||||
|
||||
while (trailer != 0)
|
||||
{
|
||||
block = (long *) trailer->this_address;
|
||||
size = trailer->this_size;
|
||||
if (block == 0 || size == 0)
|
||||
abort ();
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
if ((block <= address) && (address < (block + size)))
|
||||
break;
|
||||
}
|
||||
while (trailer != 0) {
|
||||
block = (long *)trailer->this_address;
|
||||
size = trailer->this_size;
|
||||
if (block == 0 || size == 0)
|
||||
abort();
|
||||
trailer = (struct stk_trailer *)trailer->link;
|
||||
if ((block <= address) && (address < (block + size)))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the result to the offset in this segment and add the sizes
|
||||
of all predecessor segments. */
|
||||
/* Set the result to the offset in this segment and add the sizes
|
||||
of all predecessor segments. */
|
||||
|
||||
result = address - block;
|
||||
result = address - block;
|
||||
|
||||
if (trailer == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (trailer == 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (trailer->this_size <= 0)
|
||||
abort ();
|
||||
result += trailer->this_size;
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
}
|
||||
while (trailer != 0);
|
||||
do {
|
||||
if (trailer->this_size <= 0)
|
||||
abort();
|
||||
result += trailer->this_size;
|
||||
trailer = (struct stk_trailer *)trailer->link;
|
||||
}
|
||||
while (trailer != 0);
|
||||
|
||||
/* We are done. Note that if you present a bogus address (one
|
||||
not in any segment), you will get a different number back, formed
|
||||
from subtracting the address of the first block. This is probably
|
||||
not what you want. */
|
||||
/* We are done. Note that if you present a bogus address (one
|
||||
not in any segment), you will get a different number back, formed
|
||||
from subtracting the address of the first block. This is probably
|
||||
not what you want. */
|
||||
|
||||
return (result);
|
||||
return (result);
|
||||
}
|
||||
|
||||
#else /* not CRAY2 */
|
||||
#else /* not CRAY2 */
|
||||
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
|
||||
Determine the number of the cell within the stack,
|
||||
given the address of the cell. The purpose of this
|
||||
routine is to linearize, in some sense, stack addresses
|
||||
for alloca. */
|
||||
|
||||
static long
|
||||
i00afunc (long address)
|
||||
static long i00afunc(long address)
|
||||
{
|
||||
long stkl = 0;
|
||||
long stkl = 0;
|
||||
|
||||
long size, pseg, this_segment, stack;
|
||||
long result = 0;
|
||||
long size, pseg, this_segment, stack;
|
||||
long result = 0;
|
||||
|
||||
struct stack_segment_linkage *ssptr;
|
||||
struct stack_segment_linkage *ssptr;
|
||||
|
||||
/* Register B67 contains the address of the end of the
|
||||
current stack segment. If you (as a subprogram) store
|
||||
your registers on the stack and find that you are past
|
||||
the contents of B67, you have overflowed the segment.
|
||||
/* Register B67 contains the address of the end of the
|
||||
current stack segment. If you (as a subprogram) store
|
||||
your registers on the stack and find that you are past
|
||||
the contents of B67, you have overflowed the segment.
|
||||
|
||||
B67 also points to the stack segment linkage control
|
||||
area, which is what we are really interested in. */
|
||||
B67 also points to the stack segment linkage control
|
||||
area, which is what we are really interested in. */
|
||||
|
||||
stkl = CRAY_STACKSEG_END ();
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
stkl = CRAY_STACKSEG_END();
|
||||
ssptr = (struct stack_segment_linkage *)stkl;
|
||||
|
||||
/* If one subtracts 'size' from the end of the segment,
|
||||
one has the address of the first word of the segment.
|
||||
/* If one subtracts 'size' from the end of the segment,
|
||||
one has the address of the first word of the segment.
|
||||
|
||||
If this is not the first segment, 'pseg' will be
|
||||
nonzero. */
|
||||
If this is not the first segment, 'pseg' will be
|
||||
nonzero. */
|
||||
|
||||
pseg = ssptr->sspseg;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
size = ssptr->sssize;
|
||||
|
||||
this_segment = stkl - size;
|
||||
this_segment = stkl - size;
|
||||
|
||||
/* It is possible that calling this routine itself caused
|
||||
a stack overflow. Discard stack segments which do not
|
||||
contain the target address. */
|
||||
/* It is possible that calling this routine itself caused
|
||||
a stack overflow. Discard stack segments which do not
|
||||
contain the target address. */
|
||||
|
||||
while (!(this_segment <= address && address <= stkl))
|
||||
{
|
||||
while (!(this_segment <= address && address <= stkl)) {
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
|
||||
fprintf(stderr, "%011o %011o %011o\n", this_segment, address, stkl);
|
||||
#endif
|
||||
if (pseg == 0)
|
||||
break;
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
this_segment = stkl - size;
|
||||
}
|
||||
if (pseg == 0)
|
||||
break;
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *)stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
this_segment = stkl - size;
|
||||
}
|
||||
|
||||
result = address - this_segment;
|
||||
result = address - this_segment;
|
||||
|
||||
/* If you subtract pseg from the current end of the stack,
|
||||
you get the address of the previous stack segment's end.
|
||||
This seems a little convoluted to me, but I'll bet you save
|
||||
a cycle somewhere. */
|
||||
/* If you subtract pseg from the current end of the stack,
|
||||
you get the address of the previous stack segment's end.
|
||||
This seems a little convoluted to me, but I'll bet you save
|
||||
a cycle somewhere. */
|
||||
|
||||
while (pseg != 0)
|
||||
{
|
||||
while (pseg != 0) {
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o\n", pseg, size);
|
||||
fprintf(stderr, "%011o %011o\n", pseg, size);
|
||||
#endif
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
result += size;
|
||||
}
|
||||
return (result);
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *)stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
result += size;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
#endif /* not CRAY2 */
|
||||
#endif /* CRAY */
|
||||
#endif /* not CRAY2 */
|
||||
#endif /* CRAY */
|
||||
|
||||
#endif /* no alloca */
|
||||
#endif /* not GCC version 2 */
|
||||
#endif /* no alloca */
|
||||
#endif /* not GCC version 2 */
|
||||
|
||||
160
wrlib/color.c
160
wrlib/color.c
@@ -21,7 +21,6 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -31,105 +30,98 @@
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
|
||||
#define MIN(a,b) ((a)<(b) ? (a) : (b))
|
||||
#define MAX(a,b) ((a)>(b) ? (a) : (b))
|
||||
|
||||
#define MIN3(a,b,c) MIN(MIN(a,b), c)
|
||||
#define MAX3(a,b,c) MAX(MAX(a,b), c)
|
||||
|
||||
|
||||
void
|
||||
RHSVtoRGB(RHSVColor *hsv, RColor *rgb)
|
||||
void RHSVtoRGB(RHSVColor * hsv, RColor * rgb)
|
||||
{
|
||||
int h = hsv->hue % 360;
|
||||
int s = hsv->saturation;
|
||||
int v = hsv->value;
|
||||
int i, f;
|
||||
int p, q, t;
|
||||
int h = hsv->hue % 360;
|
||||
int s = hsv->saturation;
|
||||
int v = hsv->value;
|
||||
int i, f;
|
||||
int p, q, t;
|
||||
|
||||
if (s == 0) {
|
||||
rgb->red = rgb->green = rgb->blue = v;
|
||||
return;
|
||||
}
|
||||
i = h / 60;
|
||||
f = h % 60;
|
||||
p = v * (255 - s) / 255;
|
||||
q = v * (255 - s * f / 60) / 255;
|
||||
t = v * (255 - s * (60 - f) / 60) / 255;
|
||||
if (s == 0) {
|
||||
rgb->red = rgb->green = rgb->blue = v;
|
||||
return;
|
||||
}
|
||||
i = h / 60;
|
||||
f = h % 60;
|
||||
p = v * (255 - s) / 255;
|
||||
q = v * (255 - s * f / 60) / 255;
|
||||
t = v * (255 - s * (60 - f) / 60) / 255;
|
||||
|
||||
switch (i) {
|
||||
case 0:
|
||||
rgb->red = v;
|
||||
rgb->green = t;
|
||||
rgb->blue = p;
|
||||
break;
|
||||
case 1:
|
||||
rgb->red = q;
|
||||
rgb->green = v;
|
||||
rgb->blue = p;
|
||||
break;
|
||||
case 2:
|
||||
rgb->red = p;
|
||||
rgb->green = v;
|
||||
rgb->blue = t;
|
||||
break;
|
||||
case 3:
|
||||
rgb->red = p;
|
||||
rgb->green = q;
|
||||
rgb->blue = v;
|
||||
break;
|
||||
case 4:
|
||||
rgb->red = t;
|
||||
rgb->green = p;
|
||||
rgb->blue = v;
|
||||
break;
|
||||
case 5:
|
||||
rgb->red = v;
|
||||
rgb->green = p;
|
||||
rgb->blue = q;
|
||||
break;
|
||||
}
|
||||
switch (i) {
|
||||
case 0:
|
||||
rgb->red = v;
|
||||
rgb->green = t;
|
||||
rgb->blue = p;
|
||||
break;
|
||||
case 1:
|
||||
rgb->red = q;
|
||||
rgb->green = v;
|
||||
rgb->blue = p;
|
||||
break;
|
||||
case 2:
|
||||
rgb->red = p;
|
||||
rgb->green = v;
|
||||
rgb->blue = t;
|
||||
break;
|
||||
case 3:
|
||||
rgb->red = p;
|
||||
rgb->green = q;
|
||||
rgb->blue = v;
|
||||
break;
|
||||
case 4:
|
||||
rgb->red = t;
|
||||
rgb->green = p;
|
||||
rgb->blue = v;
|
||||
break;
|
||||
case 5:
|
||||
rgb->red = v;
|
||||
rgb->green = p;
|
||||
rgb->blue = q;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RRGBtoHSV(RColor *rgb, RHSVColor *hsv)
|
||||
void RRGBtoHSV(RColor * rgb, RHSVColor * hsv)
|
||||
{
|
||||
int h, s, v;
|
||||
int max = MAX3(rgb->red, rgb->green, rgb->blue);
|
||||
int min = MIN3(rgb->red, rgb->green, rgb->blue);
|
||||
int h, s, v;
|
||||
int max = MAX3(rgb->red, rgb->green, rgb->blue);
|
||||
int min = MIN3(rgb->red, rgb->green, rgb->blue);
|
||||
|
||||
v = max;
|
||||
v = max;
|
||||
|
||||
if (max == 0)
|
||||
s = 0;
|
||||
else
|
||||
s = (max - min) * 255 / max;
|
||||
if (max == 0)
|
||||
s = 0;
|
||||
else
|
||||
s = (max - min) * 255 / max;
|
||||
|
||||
if (s == 0)
|
||||
h = 0;
|
||||
else {
|
||||
int rc, gc, bc;
|
||||
if (s == 0)
|
||||
h = 0;
|
||||
else {
|
||||
int rc, gc, bc;
|
||||
|
||||
rc = (max - rgb->red) * 255 / (max - min);
|
||||
gc = (max - rgb->green) * 255 / (max - min);
|
||||
bc = (max - rgb->blue) * 255 / (max - min);
|
||||
rc = (max - rgb->red) * 255 / (max - min);
|
||||
gc = (max - rgb->green) * 255 / (max - min);
|
||||
bc = (max - rgb->blue) * 255 / (max - min);
|
||||
|
||||
if (rgb->red == max) {
|
||||
h = ((bc - gc) * 60 / 255);
|
||||
} else if (rgb->green == max) {
|
||||
h = 2*60 + ((rc - bc) * 60 / 255);
|
||||
} else {
|
||||
h = 4*60 + ((gc - rc) * 60 / 255);
|
||||
}
|
||||
if (h < 0)
|
||||
h += 360;
|
||||
}
|
||||
if (rgb->red == max) {
|
||||
h = ((bc - gc) * 60 / 255);
|
||||
} else if (rgb->green == max) {
|
||||
h = 2 * 60 + ((rc - bc) * 60 / 255);
|
||||
} else {
|
||||
h = 4 * 60 + ((gc - rc) * 60 / 255);
|
||||
}
|
||||
if (h < 0)
|
||||
h += 360;
|
||||
}
|
||||
|
||||
hsv->hue = h;
|
||||
hsv->saturation = s;
|
||||
hsv->value = v;
|
||||
hsv->hue = h;
|
||||
hsv->saturation = s;
|
||||
hsv->value = v;
|
||||
}
|
||||
|
||||
|
||||
1130
wrlib/context.c
1130
wrlib/context.c
File diff suppressed because it is too large
Load Diff
1699
wrlib/convert.c
1699
wrlib/convert.c
File diff suppressed because it is too large
Load Diff
441
wrlib/convolve.c
441
wrlib/convolve.c
@@ -20,14 +20,12 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* RBlurImage--
|
||||
@@ -36,276 +34,287 @@
|
||||
* 1 1 1 /10
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
RBlurImage(RImage *image)
|
||||
int RBlurImage(RImage * image)
|
||||
{
|
||||
register int x, y;
|
||||
register int tmp;
|
||||
unsigned char *ptr, *nptr;
|
||||
unsigned char *pptr=NULL, *tmpp;
|
||||
int ch = image->format == RRGBAFormat ? 4 : 3;
|
||||
|
||||
pptr = malloc(image->width * ch);
|
||||
if (!pptr) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return False;
|
||||
}
|
||||
register int x, y;
|
||||
register int tmp;
|
||||
unsigned char *ptr, *nptr;
|
||||
unsigned char *pptr = NULL, *tmpp;
|
||||
int ch = image->format == RRGBAFormat ? 4 : 3;
|
||||
|
||||
pptr = malloc(image->width * ch);
|
||||
if (!pptr) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return False;
|
||||
}
|
||||
#define MASK(prev, cur, next, ch)\
|
||||
(*(prev-ch) + *prev + *(prev+ch)\
|
||||
+*(cur-ch) + 2 * *cur + *(cur+ch)\
|
||||
+*(next-ch) + *next + *(next+ch)) / 10
|
||||
|
||||
memcpy(pptr, image->data, image->width * ch);
|
||||
memcpy(pptr, image->data, image->width * ch);
|
||||
|
||||
ptr = image->data;
|
||||
nptr = ptr + image->width*ch;
|
||||
tmpp = pptr;
|
||||
ptr = image->data;
|
||||
nptr = ptr + image->width * ch;
|
||||
tmpp = pptr;
|
||||
|
||||
if (ch == 3) {
|
||||
ptr+=3;
|
||||
nptr+=3;
|
||||
pptr+=3;
|
||||
if (ch == 3) {
|
||||
ptr += 3;
|
||||
nptr += 3;
|
||||
pptr += 3;
|
||||
|
||||
for (y = 1; y < image->height-1; y++) {
|
||||
for (y = 1; y < image->height - 1; y++) {
|
||||
|
||||
for (x = 1; x < image->width-1; x++) {
|
||||
tmp = *ptr;
|
||||
*ptr = MASK(pptr, ptr, nptr, 3);
|
||||
*pptr = tmp;
|
||||
ptr++; nptr++; pptr++;
|
||||
for (x = 1; x < image->width - 1; x++) {
|
||||
tmp = *ptr;
|
||||
*ptr = MASK(pptr, ptr, nptr, 3);
|
||||
*pptr = tmp;
|
||||
ptr++;
|
||||
nptr++;
|
||||
pptr++;
|
||||
|
||||
tmp = *ptr;
|
||||
*ptr = MASK(pptr, ptr, nptr, 3);
|
||||
*pptr = tmp;
|
||||
ptr++; nptr++; pptr++;
|
||||
tmp = *ptr;
|
||||
*ptr = MASK(pptr, ptr, nptr, 3);
|
||||
*pptr = tmp;
|
||||
ptr++;
|
||||
nptr++;
|
||||
pptr++;
|
||||
|
||||
tmp = *ptr;
|
||||
*ptr = MASK(pptr, ptr, nptr, 3);
|
||||
*pptr = tmp;
|
||||
ptr++; nptr++; pptr++;
|
||||
}
|
||||
pptr = tmpp;
|
||||
ptr+=6;
|
||||
nptr+=6;
|
||||
pptr+=6;
|
||||
}
|
||||
} else {
|
||||
ptr+=4;
|
||||
nptr+=4;
|
||||
pptr+=4;
|
||||
tmp = *ptr;
|
||||
*ptr = MASK(pptr, ptr, nptr, 3);
|
||||
*pptr = tmp;
|
||||
ptr++;
|
||||
nptr++;
|
||||
pptr++;
|
||||
}
|
||||
pptr = tmpp;
|
||||
ptr += 6;
|
||||
nptr += 6;
|
||||
pptr += 6;
|
||||
}
|
||||
} else {
|
||||
ptr += 4;
|
||||
nptr += 4;
|
||||
pptr += 4;
|
||||
|
||||
for (y = 1; y < image->height-1; y++) {
|
||||
for (x = 1; x < image->width-1; x++) {
|
||||
tmp = *ptr;
|
||||
*ptr = MASK(pptr, ptr, nptr, 4);
|
||||
*pptr = tmp;
|
||||
ptr++; nptr++; pptr++;
|
||||
for (y = 1; y < image->height - 1; y++) {
|
||||
for (x = 1; x < image->width - 1; x++) {
|
||||
tmp = *ptr;
|
||||
*ptr = MASK(pptr, ptr, nptr, 4);
|
||||
*pptr = tmp;
|
||||
ptr++;
|
||||
nptr++;
|
||||
pptr++;
|
||||
|
||||
tmp = *ptr;
|
||||
*ptr = MASK(pptr, ptr, nptr, 4);
|
||||
*pptr = tmp;
|
||||
ptr++; nptr++; pptr++;
|
||||
tmp = *ptr;
|
||||
*ptr = MASK(pptr, ptr, nptr, 4);
|
||||
*pptr = tmp;
|
||||
ptr++;
|
||||
nptr++;
|
||||
pptr++;
|
||||
|
||||
tmp = *ptr;
|
||||
*ptr = MASK(pptr, ptr, nptr, 4);
|
||||
*pptr = tmp;
|
||||
ptr++; nptr++; pptr++;
|
||||
tmp = *ptr;
|
||||
*ptr = MASK(pptr, ptr, nptr, 4);
|
||||
*pptr = tmp;
|
||||
ptr++;
|
||||
nptr++;
|
||||
pptr++;
|
||||
|
||||
tmp = *ptr;
|
||||
*ptr = MASK(pptr, ptr, nptr, 4);
|
||||
*pptr = tmp;
|
||||
ptr++; nptr++; pptr++;
|
||||
}
|
||||
pptr = tmpp;
|
||||
ptr+=8;
|
||||
nptr+=8;
|
||||
pptr+=8;
|
||||
}
|
||||
}
|
||||
tmp = *ptr;
|
||||
*ptr = MASK(pptr, ptr, nptr, 4);
|
||||
*pptr = tmp;
|
||||
ptr++;
|
||||
nptr++;
|
||||
pptr++;
|
||||
}
|
||||
pptr = tmpp;
|
||||
ptr += 8;
|
||||
nptr += 8;
|
||||
pptr += 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return True;
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
int
|
||||
REdgeDetectImage(RImage *image)
|
||||
int REdgeDetectImage(RImage * image)
|
||||
{
|
||||
register int x, y, d1, d2, d3, d4, rsum;
|
||||
int w;
|
||||
unsigned char *r, *g, *b, *a;
|
||||
unsigned char *dr, *dg, *db, *da;
|
||||
unsigned char *pr=NULL, *pg=NULL, *pb=NULL, *pa=NULL;
|
||||
RImage *image2;
|
||||
register int x, y, d1, d2, d3, d4, rsum;
|
||||
int w;
|
||||
unsigned char *r, *g, *b, *a;
|
||||
unsigned char *dr, *dg, *db, *da;
|
||||
unsigned char *pr = NULL, *pg = NULL, *pb = NULL, *pa = NULL;
|
||||
RImage *image2;
|
||||
|
||||
image2 = RCloneImage(image);
|
||||
|
||||
image2 = RCloneImage(image);
|
||||
pr = alloca(image->width * sizeof(char));
|
||||
if (!pr)
|
||||
goto outofmem;
|
||||
|
||||
pr = alloca(image->width*sizeof(char));
|
||||
if (!pr)
|
||||
goto outofmem;
|
||||
pg = alloca(image->width * sizeof(char));
|
||||
if (!pg)
|
||||
goto outofmem;
|
||||
|
||||
pg = alloca(image->width*sizeof(char));
|
||||
if (!pg)
|
||||
goto outofmem;
|
||||
pb = alloca(image->width * sizeof(char));
|
||||
if (!pb)
|
||||
goto outofmem;
|
||||
|
||||
pb = alloca(image->width*sizeof(char));
|
||||
if (!pb)
|
||||
goto outofmem;
|
||||
pa = alloca(image->width * sizeof(char));
|
||||
if (!pa)
|
||||
goto outofmem;
|
||||
|
||||
pa = alloca(image->width*sizeof(char));
|
||||
if (!pa)
|
||||
goto outofmem;
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
a = image->data[3];
|
||||
|
||||
dr = image2->data[0];
|
||||
dg = image2->data[1];
|
||||
db = image2->data[2];
|
||||
da = image2->data[3];
|
||||
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
a = image->data[3];
|
||||
for (x = 0; x < image->width; x++) {
|
||||
*(dr++) = *(r++);
|
||||
*(dg++) = *(g++);
|
||||
*(db++) = *(b++);
|
||||
}
|
||||
|
||||
dr = image2->data[0];
|
||||
dg = image2->data[1];
|
||||
db = image2->data[2];
|
||||
da = image2->data[3];
|
||||
w = image->width;
|
||||
|
||||
for (y = 1; y < image->height - 1; y++) {
|
||||
dr[w - 1] = r[w - 1];
|
||||
dg[w - 1] = g[w - 1];
|
||||
db[w - 1] = b[w - 1];
|
||||
|
||||
for (x=0; x<image->width; x++) {
|
||||
*(dr++) = *(r++);
|
||||
*(dg++) = *(g++);
|
||||
*(db++) = *(b++);
|
||||
}
|
||||
*(dr++) = *(r++);
|
||||
*(dg++) = *(g++);
|
||||
*(db++) = *(b++);
|
||||
|
||||
w = image->width;
|
||||
for (x = 1; x < image->width - 1; x++) {
|
||||
d1 = r[w + 1] - r[-w - 1];
|
||||
d2 = r[1] - r[-1];
|
||||
d3 = r[-w + 1] - r[w - 1];
|
||||
d4 = r[-w] - r[w];
|
||||
|
||||
for (y=1; y<image->height-1; y++) {
|
||||
dr[w-1] = r[w-1];
|
||||
dg[w-1] = g[w-1];
|
||||
db[w-1] = b[w-1];
|
||||
rsum = d1 + d2 + d3;
|
||||
if (rsum < 0)
|
||||
rsum = -rsum;
|
||||
d1 = d1 - d2 - d4; /* vertical gradient */
|
||||
if (d1 < 0)
|
||||
d1 = -d1;
|
||||
if (d1 > rsum)
|
||||
rsum = d1;
|
||||
rsum /= 3;
|
||||
|
||||
*(dr++) = *(r++);
|
||||
*(dg++) = *(g++);
|
||||
*(db++) = *(b++);
|
||||
*(dr++) = rsum;
|
||||
|
||||
for (x=1; x<image->width-1; x++) {
|
||||
d1 = r[w+1] - r[-w-1];
|
||||
d2 = r[1] - r[-1];
|
||||
d3 = r[-w+1] - r[w-1];
|
||||
d4 = r[-w] - r[w];
|
||||
d1 = g[w + 1] - g[-w - 1];
|
||||
d2 = g[1] - g[-1];
|
||||
d3 = g[-w + 1] - g[w - 1];
|
||||
d4 = g[-w] - g[w];
|
||||
|
||||
rsum = d1 + d2 + d3;
|
||||
if (rsum < 0) rsum = -rsum;
|
||||
d1 = d1 - d2 - d4; /* vertical gradient */
|
||||
if (d1 < 0) d1 = -d1;
|
||||
if (d1 > rsum) rsum = d1;
|
||||
rsum /= 3;
|
||||
rsum = d1 + d2 + d3;
|
||||
if (rsum < 0)
|
||||
rsum = -rsum;
|
||||
d1 = d1 - d2 - d4; /* vertical gradient */
|
||||
if (d1 < 0)
|
||||
d1 = -d1;
|
||||
if (d1 > rsum)
|
||||
rsum = d1;
|
||||
rsum /= 3;
|
||||
|
||||
*(dr++) = rsum;
|
||||
*(dg++) = rsum;
|
||||
|
||||
d1 = g[w+1] - g[-w-1];
|
||||
d2 = g[1] - g[-1];
|
||||
d3 = g[-w+1] - g[w-1];
|
||||
d4 = g[-w] - g[w];
|
||||
d1 = b[w + 1] - b[-w - 1];
|
||||
d2 = b[1] - b[-1];
|
||||
d3 = b[-w + 1] - b[w - 1];
|
||||
d4 = b[-w] - b[w];
|
||||
|
||||
rsum = d1 + d2 + d3;
|
||||
if (rsum < 0) rsum = -rsum;
|
||||
d1 = d1 - d2 - d4; /* vertical gradient */
|
||||
if (d1 < 0) d1 = -d1;
|
||||
if (d1 > rsum) rsum = d1;
|
||||
rsum /= 3;
|
||||
rsum = d1 + d2 + d3;
|
||||
if (rsum < 0)
|
||||
rsum = -rsum;
|
||||
d1 = d1 - d2 - d4; /* vertical gradient */
|
||||
if (d1 < 0)
|
||||
d1 = -d1;
|
||||
if (d1 > rsum)
|
||||
rsum = d1;
|
||||
rsum /= 3;
|
||||
|
||||
*(dg++) = rsum;
|
||||
*(db++) = rsum;
|
||||
|
||||
d1 = b[w+1] - b[-w-1];
|
||||
d2 = b[1] - b[-1];
|
||||
d3 = b[-w+1] - b[w-1];
|
||||
d4 = b[-w] - b[w];
|
||||
r++;
|
||||
g++;
|
||||
b++;
|
||||
}
|
||||
r++;
|
||||
g++;
|
||||
b++;
|
||||
|
||||
rsum = d1 + d2 + d3;
|
||||
if (rsum < 0) rsum = -rsum;
|
||||
d1 = d1 - d2 - d4; /* vertical gradient */
|
||||
if (d1 < 0) d1 = -d1;
|
||||
if (d1 > rsum) rsum = d1;
|
||||
rsum /= 3;
|
||||
|
||||
*(db++) = rsum;
|
||||
|
||||
r++;
|
||||
g++;
|
||||
b++;
|
||||
}
|
||||
r++;
|
||||
g++;
|
||||
b++;
|
||||
|
||||
dr++;
|
||||
dg++;
|
||||
db++;
|
||||
}
|
||||
{
|
||||
r = image->data[0];
|
||||
image2->data[0] = r;
|
||||
g = image->data[1];
|
||||
image2->data[1] = g;
|
||||
b = image->data[2];
|
||||
image2->data[2] = b;
|
||||
RReleaseImage(image2);
|
||||
}
|
||||
dr++;
|
||||
dg++;
|
||||
db++;
|
||||
}
|
||||
{
|
||||
r = image->data[0];
|
||||
image2->data[0] = r;
|
||||
g = image->data[1];
|
||||
image2->data[1] = g;
|
||||
b = image->data[2];
|
||||
image2->data[2] = b;
|
||||
RReleaseImage(image2);
|
||||
}
|
||||
|
||||
#undef MASK
|
||||
|
||||
return True;
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
RSmoothImage(RImage *image)
|
||||
int RSmoothImage(RImage * image)
|
||||
{
|
||||
register int x, y;
|
||||
register int v, w;
|
||||
unsigned char *ptr;
|
||||
int ch = image->format == RRGBAFormat;
|
||||
register int x, y;
|
||||
register int v, w;
|
||||
unsigned char *ptr;
|
||||
int ch = image->format == RRGBAFormat;
|
||||
|
||||
ptr = image->data;
|
||||
ptr = image->data;
|
||||
|
||||
w = image->width * ch;
|
||||
for (y = 0; y < image->height - 1; y++) {
|
||||
for (x = 0; x < image->width - 1; x++) {
|
||||
v = *ptr + 2 * *(ptr + ch) + 2 * *(ptr + w) + *(ptr + w + ch);
|
||||
*ptr = v / 6;
|
||||
v = *(ptr + 1) + 2 * *(ptr + 1 + ch) + 2 * *(ptr + 1 + w) + *(ptr + 1 + w + ch);
|
||||
*(ptr + 1) = v / 6;
|
||||
v = *(ptr + 2) + 2 * *(ptr + 2 + ch) + 2 * *(ptr + 2 + w) + *(ptr + 2 + w + ch);
|
||||
*(ptr + 2) = v / 6;
|
||||
|
||||
w = image->width*ch;
|
||||
for (y=0; y<image->height - 1; y++) {
|
||||
for (x=0; x<image->width - 1; x++) {
|
||||
v = *ptr + 2 * *(ptr + ch) + 2 * *(ptr + w) + *(ptr + w + ch);
|
||||
*ptr = v/6;
|
||||
v = *(ptr+1) + 2 * *(ptr+1 + ch) + 2 * *(ptr+1 + w) + *(ptr+1 + w + ch);
|
||||
*(ptr+1) = v/6;
|
||||
v = *(ptr+2) + 2 * *(ptr+2 + ch) + 2 * *(ptr+2 + w) + *(ptr+2 + w + ch);
|
||||
*(ptr+2) = v/6;
|
||||
ptr += ch;
|
||||
}
|
||||
/* last column */
|
||||
v = 3 * *ptr + 3 * *(ptr + w);
|
||||
*ptr = v / 6;
|
||||
v = 3 * *(ptr + 1) + 3 * *(ptr + 1 + w);
|
||||
*(ptr + 1) = v / 6;
|
||||
v = 3 * *(ptr + 2) + 3 * *(ptr + 2 + w);
|
||||
*(ptr + 2) = v / 6;
|
||||
|
||||
ptr+= ch;
|
||||
}
|
||||
/* last column */
|
||||
v = 3 * *ptr + 3 * *(ptr + w);
|
||||
*ptr = v/6;
|
||||
v = 3 * *(ptr+1) + 3 * *(ptr+1 + w);
|
||||
*(ptr+1) = v/6;
|
||||
v = 3 * *(ptr+2) + 3 * *(ptr+2 + w);
|
||||
*(ptr+2) = v/6;
|
||||
ptr += ch;
|
||||
}
|
||||
|
||||
ptr+= ch;
|
||||
}
|
||||
/* last line */
|
||||
for (x = 0; x < image->width - 1; x++) {
|
||||
v = 3 * *ptr + 3 * *(ptr + ch);
|
||||
*ptr = v / 6;
|
||||
v = 3 * *(ptr + 1) + 3 * *(ptr + 1 + ch);
|
||||
*(ptr + 1) = v / 6;
|
||||
v = 3 * *(ptr + 2) + 3 * *(ptr + 2 + ch);
|
||||
*(ptr + 2) = v / 6;
|
||||
|
||||
/* last line */
|
||||
for (x=0; x<image->width - 1; x++) {
|
||||
v = 3 * *ptr + 3 * *(ptr + ch);
|
||||
*ptr = v/6;
|
||||
v = 3 * *(ptr+1) + 3 * *(ptr+1 + ch);
|
||||
*(ptr+1) = v/6;
|
||||
v = 3 * *(ptr+2) + 3 * *(ptr+2 + ch);
|
||||
*(ptr+2) = v/6;
|
||||
ptr += ch;
|
||||
}
|
||||
|
||||
ptr+= ch;
|
||||
}
|
||||
|
||||
return True;
|
||||
return True;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
905
wrlib/draw.c
905
wrlib/draw.c
File diff suppressed because it is too large
Load Diff
324
wrlib/gif.c
324
wrlib/gif.c
@@ -21,7 +21,6 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#ifdef USE_GIF
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -32,201 +31,196 @@
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
static int InterlacedOffset[] = { 0, 4, 2, 1 };
|
||||
static int InterlacedJumps[] = { 8, 8, 4, 2 };
|
||||
|
||||
|
||||
/*
|
||||
* Partially based on code in gif2rgb from giflib, by Gershon Elber.
|
||||
*/
|
||||
RImage*
|
||||
RLoadGIF(RContext *context, char *file, int index)
|
||||
RImage *RLoadGIF(RContext * context, char *file, int index)
|
||||
{
|
||||
RImage *image = NULL;
|
||||
unsigned char *cptr;
|
||||
GifFileType *gif = NULL;
|
||||
GifPixelType *buffer = NULL;
|
||||
int i, j, k;
|
||||
int width, height;
|
||||
GifRecordType recType;
|
||||
ColorMapObject *colormap;
|
||||
unsigned char rmap[256];
|
||||
unsigned char gmap[256];
|
||||
unsigned char bmap[256];
|
||||
RImage *image = NULL;
|
||||
unsigned char *cptr;
|
||||
GifFileType *gif = NULL;
|
||||
GifPixelType *buffer = NULL;
|
||||
int i, j, k;
|
||||
int width, height;
|
||||
GifRecordType recType;
|
||||
ColorMapObject *colormap;
|
||||
unsigned char rmap[256];
|
||||
unsigned char gmap[256];
|
||||
unsigned char bmap[256];
|
||||
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
|
||||
/* default error message */
|
||||
RErrorCode = RERR_BADINDEX;
|
||||
/* default error message */
|
||||
RErrorCode = RERR_BADINDEX;
|
||||
|
||||
gif = DGifOpenFileName(file);
|
||||
gif = DGifOpenFileName(file);
|
||||
|
||||
if (!gif) {
|
||||
switch (GifLastError()) {
|
||||
case D_GIF_ERR_OPEN_FAILED:
|
||||
RErrorCode = RERR_OPEN;
|
||||
break;
|
||||
case D_GIF_ERR_READ_FAILED:
|
||||
RErrorCode = RERR_READ;
|
||||
break;
|
||||
default:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (!gif) {
|
||||
switch (GifLastError()) {
|
||||
case D_GIF_ERR_OPEN_FAILED:
|
||||
RErrorCode = RERR_OPEN;
|
||||
break;
|
||||
case D_GIF_ERR_READ_FAILED:
|
||||
RErrorCode = RERR_READ;
|
||||
break;
|
||||
default:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (gif->SWidth<1 || gif->SHeight<1) {
|
||||
DGifCloseFile(gif);
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
return NULL;
|
||||
}
|
||||
if (gif->SWidth < 1 || gif->SHeight < 1) {
|
||||
DGifCloseFile(gif);
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
colormap = gif->SColorMap;
|
||||
colormap = gif->SColorMap;
|
||||
|
||||
i = 0;
|
||||
i = 0;
|
||||
|
||||
do {
|
||||
int extCode;
|
||||
GifByteType *extension;
|
||||
do {
|
||||
int extCode;
|
||||
GifByteType *extension;
|
||||
|
||||
if (DGifGetRecordType(gif, &recType) == GIF_ERROR) {
|
||||
goto giferr;
|
||||
}
|
||||
switch (recType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
if (i++ != index)
|
||||
break;
|
||||
if (DGifGetRecordType(gif, &recType) == GIF_ERROR) {
|
||||
goto giferr;
|
||||
}
|
||||
switch (recType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
if (i++ != index)
|
||||
break;
|
||||
|
||||
if (DGifGetImageDesc(gif)==GIF_ERROR) {
|
||||
goto giferr;
|
||||
}
|
||||
if (DGifGetImageDesc(gif) == GIF_ERROR) {
|
||||
goto giferr;
|
||||
}
|
||||
|
||||
width = gif->Image.Width;
|
||||
height = gif->Image.Height;
|
||||
width = gif->Image.Width;
|
||||
height = gif->Image.Height;
|
||||
|
||||
if (gif->Image.ColorMap)
|
||||
colormap = gif->Image.ColorMap;
|
||||
if (gif->Image.ColorMap)
|
||||
colormap = gif->Image.ColorMap;
|
||||
|
||||
/* the gif specs talk about a default colormap, but it
|
||||
* doesnt say what the heck is this default colormap */
|
||||
if (!colormap) {
|
||||
/*
|
||||
* Well, since the spec says the colormap can be anything,
|
||||
* lets just render it with whatever garbage the stack
|
||||
* has :)
|
||||
*
|
||||
/* the gif specs talk about a default colormap, but it
|
||||
* doesnt say what the heck is this default colormap */
|
||||
if (!colormap) {
|
||||
/*
|
||||
* Well, since the spec says the colormap can be anything,
|
||||
* lets just render it with whatever garbage the stack
|
||||
* has :)
|
||||
*
|
||||
|
||||
goto bye;
|
||||
*/
|
||||
} else {
|
||||
for (j = 0; j < colormap->ColorCount; j++) {
|
||||
rmap[j] = colormap->Colors[j].Red;
|
||||
gmap[j] = colormap->Colors[j].Green;
|
||||
bmap[j] = colormap->Colors[j].Blue;
|
||||
}
|
||||
}
|
||||
goto bye;
|
||||
*/
|
||||
} else {
|
||||
for (j = 0; j < colormap->ColorCount; j++) {
|
||||
rmap[j] = colormap->Colors[j].Red;
|
||||
gmap[j] = colormap->Colors[j].Green;
|
||||
bmap[j] = colormap->Colors[j].Blue;
|
||||
}
|
||||
}
|
||||
|
||||
buffer = malloc(width * sizeof(GifColorType));
|
||||
if (!buffer) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
goto bye;
|
||||
}
|
||||
buffer = malloc(width * sizeof(GifColorType));
|
||||
if (!buffer) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
goto bye;
|
||||
}
|
||||
|
||||
image = RCreateImage(width, height, False);
|
||||
if (!image) {
|
||||
goto bye;
|
||||
}
|
||||
image = RCreateImage(width, height, False);
|
||||
if (!image) {
|
||||
goto bye;
|
||||
}
|
||||
|
||||
if (gif->Image.Interlace) {
|
||||
int l;
|
||||
int pelsPerLine;
|
||||
if (gif->Image.Interlace) {
|
||||
int l;
|
||||
int pelsPerLine;
|
||||
|
||||
if (RRGBAFormat==image->format)
|
||||
pelsPerLine = width * 4;
|
||||
else
|
||||
pelsPerLine = width * 3;
|
||||
if (RRGBAFormat == image->format)
|
||||
pelsPerLine = width * 4;
|
||||
else
|
||||
pelsPerLine = width * 3;
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (k = InterlacedOffset[j]; k < height;
|
||||
k += InterlacedJumps[j]) {
|
||||
if (DGifGetLine(gif, buffer, width)==GIF_ERROR) {
|
||||
goto giferr;
|
||||
}
|
||||
cptr = image->data + (k*pelsPerLine);
|
||||
for (l = 0; l < width; l++) {
|
||||
int pixel = buffer[l];
|
||||
*cptr++ = rmap[pixel];
|
||||
*cptr++ = gmap[pixel];
|
||||
*cptr++ = bmap[pixel];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cptr = image->data;
|
||||
for (j = 0; j < height; j++) {
|
||||
if (DGifGetLine(gif, buffer, width)==GIF_ERROR) {
|
||||
goto giferr;
|
||||
}
|
||||
for (k = 0; k < width; k++) {
|
||||
int pixel = buffer[k];
|
||||
*cptr++ = rmap[pixel];
|
||||
*cptr++ = gmap[pixel];
|
||||
*cptr++ = bmap[pixel];
|
||||
if (RRGBAFormat==image->format)
|
||||
cptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (k = InterlacedOffset[j]; k < height; k += InterlacedJumps[j]) {
|
||||
if (DGifGetLine(gif, buffer, width) == GIF_ERROR) {
|
||||
goto giferr;
|
||||
}
|
||||
cptr = image->data + (k * pelsPerLine);
|
||||
for (l = 0; l < width; l++) {
|
||||
int pixel = buffer[l];
|
||||
*cptr++ = rmap[pixel];
|
||||
*cptr++ = gmap[pixel];
|
||||
*cptr++ = bmap[pixel];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cptr = image->data;
|
||||
for (j = 0; j < height; j++) {
|
||||
if (DGifGetLine(gif, buffer, width) == GIF_ERROR) {
|
||||
goto giferr;
|
||||
}
|
||||
for (k = 0; k < width; k++) {
|
||||
int pixel = buffer[k];
|
||||
*cptr++ = rmap[pixel];
|
||||
*cptr++ = gmap[pixel];
|
||||
*cptr++ = bmap[pixel];
|
||||
if (RRGBAFormat == image->format)
|
||||
cptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EXTENSION_RECORD_TYPE:
|
||||
/* skip all extension blocks */
|
||||
if (DGifGetExtension(gif, &extCode, &extension)==GIF_ERROR) {
|
||||
goto giferr;
|
||||
}
|
||||
while (extension) {
|
||||
if (DGifGetExtensionNext(gif, &extension)==GIF_ERROR) {
|
||||
goto giferr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXTENSION_RECORD_TYPE:
|
||||
/* skip all extension blocks */
|
||||
if (DGifGetExtension(gif, &extCode, &extension) == GIF_ERROR) {
|
||||
goto giferr;
|
||||
}
|
||||
while (extension) {
|
||||
if (DGifGetExtensionNext(gif, &extension) == GIF_ERROR) {
|
||||
goto giferr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while (recType != TERMINATE_RECORD_TYPE && i <= index);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while (recType != TERMINATE_RECORD_TYPE && i <= index);
|
||||
|
||||
/* yuck! */
|
||||
goto did_not_get_any_errors;
|
||||
giferr:
|
||||
switch (GifLastError()) {
|
||||
case D_GIF_ERR_OPEN_FAILED:
|
||||
RErrorCode = RERR_OPEN;
|
||||
break;
|
||||
case D_GIF_ERR_READ_FAILED:
|
||||
RErrorCode = RERR_READ;
|
||||
break;
|
||||
default:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
}
|
||||
bye:
|
||||
if (image)
|
||||
RReleaseImage(image);
|
||||
image = NULL;
|
||||
did_not_get_any_errors:
|
||||
/* yuck! */
|
||||
goto did_not_get_any_errors;
|
||||
giferr:
|
||||
switch (GifLastError()) {
|
||||
case D_GIF_ERR_OPEN_FAILED:
|
||||
RErrorCode = RERR_OPEN;
|
||||
break;
|
||||
case D_GIF_ERR_READ_FAILED:
|
||||
RErrorCode = RERR_READ;
|
||||
break;
|
||||
default:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
}
|
||||
bye:
|
||||
if (image)
|
||||
RReleaseImage(image);
|
||||
image = NULL;
|
||||
did_not_get_any_errors:
|
||||
|
||||
if (buffer)
|
||||
free(buffer);
|
||||
if (buffer)
|
||||
free(buffer);
|
||||
|
||||
if (gif)
|
||||
DGifCloseFile(gif);
|
||||
if (gif)
|
||||
DGifCloseFile(gif);
|
||||
|
||||
return image;
|
||||
return image;
|
||||
}
|
||||
|
||||
#endif /* USE_GIF */
|
||||
|
||||
#endif /* USE_GIF */
|
||||
|
||||
915
wrlib/gradient.c
915
wrlib/gradient.c
File diff suppressed because it is too large
Load Diff
224
wrlib/jpeg.c
224
wrlib/jpeg.c
@@ -21,12 +21,9 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
/* Avoid a compiler warning */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
|
||||
|
||||
#ifdef USE_JPEG
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -68,149 +65,144 @@
|
||||
*/
|
||||
|
||||
struct my_error_mgr {
|
||||
struct jpeg_error_mgr pub; /* "public" fields */
|
||||
struct jpeg_error_mgr pub; /* "public" fields */
|
||||
|
||||
jmp_buf setjmp_buffer; /* for return to caller */
|
||||
jmp_buf setjmp_buffer; /* for return to caller */
|
||||
};
|
||||
|
||||
typedef struct my_error_mgr * my_error_ptr;
|
||||
typedef struct my_error_mgr *my_error_ptr;
|
||||
|
||||
/*
|
||||
* Here's the routine that will replace the standard error_exit method:
|
||||
*/
|
||||
|
||||
static void
|
||||
my_error_exit(j_common_ptr cinfo)
|
||||
static void my_error_exit(j_common_ptr cinfo)
|
||||
{
|
||||
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
|
||||
my_error_ptr myerr = (my_error_ptr) cinfo->err;
|
||||
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
|
||||
my_error_ptr myerr = (my_error_ptr) cinfo->err;
|
||||
|
||||
/* Always display the message. */
|
||||
/* We could postpone this until after returning, if we chose. */
|
||||
(*cinfo->err->output_message) (cinfo);
|
||||
/* Always display the message. */
|
||||
/* We could postpone this until after returning, if we chose. */
|
||||
(*cinfo->err->output_message) (cinfo);
|
||||
|
||||
/* Return control to the setjmp point */
|
||||
longjmp(myerr->setjmp_buffer, 1);
|
||||
/* Return control to the setjmp point */
|
||||
longjmp(myerr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
|
||||
RImage*
|
||||
RLoadJPEG(RContext *context, char *file_name, int index)
|
||||
RImage *RLoadJPEG(RContext * context, char *file_name, int index)
|
||||
{
|
||||
RImage *image = NULL;
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
int i;
|
||||
unsigned char *ptr;
|
||||
JSAMPROW buffer[1], bptr;
|
||||
FILE *file;
|
||||
/* We use our private extension JPEG error handler.
|
||||
* Note that this struct must live as long as the main JPEG parameter
|
||||
* struct, to avoid dangling-pointer problems.
|
||||
*/
|
||||
struct my_error_mgr jerr;
|
||||
RImage *image = NULL;
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
int i;
|
||||
unsigned char *ptr;
|
||||
JSAMPROW buffer[1], bptr;
|
||||
FILE *file;
|
||||
/* We use our private extension JPEG error handler.
|
||||
* Note that this struct must live as long as the main JPEG parameter
|
||||
* struct, to avoid dangling-pointer problems.
|
||||
*/
|
||||
struct my_error_mgr jerr;
|
||||
|
||||
file = fopen(file_name, "rb");
|
||||
if (!file) {
|
||||
RErrorCode = RERR_OPEN;
|
||||
return NULL;
|
||||
}
|
||||
file = fopen(file_name, "rb");
|
||||
if (!file) {
|
||||
RErrorCode = RERR_OPEN;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = my_error_exit;
|
||||
/* Establish the setjmp return context for my_error_exit to use. */
|
||||
if (setjmp(jerr.setjmp_buffer)) {
|
||||
/* If we get here, the JPEG code has signaled an error.
|
||||
* We need to clean up the JPEG object, close the input file, and return.
|
||||
*/
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = my_error_exit;
|
||||
/* Establish the setjmp return context for my_error_exit to use. */
|
||||
if (setjmp(jerr.setjmp_buffer)) {
|
||||
/* If we get here, the JPEG code has signaled an error.
|
||||
* We need to clean up the JPEG object, close the input file, and return.
|
||||
*/
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jpeg_create_decompress(&cinfo);
|
||||
jpeg_create_decompress(&cinfo);
|
||||
|
||||
jpeg_stdio_src(&cinfo, file);
|
||||
jpeg_stdio_src(&cinfo, file);
|
||||
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
|
||||
if (cinfo.image_width < 1 || cinfo.image_height < 1) {
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
goto bye;
|
||||
}
|
||||
if (cinfo.image_width < 1 || cinfo.image_height < 1) {
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
goto bye;
|
||||
}
|
||||
|
||||
bptr = buffer[0] = (JSAMPROW)malloc(cinfo.image_width*cinfo.num_components);
|
||||
if (!buffer[0]) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
goto bye;
|
||||
}
|
||||
bptr = buffer[0] = (JSAMPROW) malloc(cinfo.image_width * cinfo.num_components);
|
||||
if (!buffer[0]) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
goto bye;
|
||||
}
|
||||
|
||||
if(cinfo.jpeg_color_space==JCS_GRAYSCALE) {
|
||||
cinfo.out_color_space=JCS_GRAYSCALE;
|
||||
} else
|
||||
cinfo.out_color_space = JCS_RGB;
|
||||
cinfo.quantize_colors = FALSE;
|
||||
cinfo.do_fancy_upsampling = FALSE;
|
||||
cinfo.do_block_smoothing = FALSE;
|
||||
jpeg_calc_output_dimensions(&cinfo);
|
||||
if (cinfo.jpeg_color_space == JCS_GRAYSCALE) {
|
||||
cinfo.out_color_space = JCS_GRAYSCALE;
|
||||
} else
|
||||
cinfo.out_color_space = JCS_RGB;
|
||||
cinfo.quantize_colors = FALSE;
|
||||
cinfo.do_fancy_upsampling = FALSE;
|
||||
cinfo.do_block_smoothing = FALSE;
|
||||
jpeg_calc_output_dimensions(&cinfo);
|
||||
|
||||
if (context->flags.optimize_for_speed)
|
||||
image = RCreateImage(cinfo.image_width, cinfo.image_height, True);
|
||||
else
|
||||
image = RCreateImage(cinfo.image_width, cinfo.image_height, False);
|
||||
if (context->flags.optimize_for_speed)
|
||||
image = RCreateImage(cinfo.image_width, cinfo.image_height, True);
|
||||
else
|
||||
image = RCreateImage(cinfo.image_width, cinfo.image_height, False);
|
||||
|
||||
if (!image) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
goto bye;
|
||||
}
|
||||
jpeg_start_decompress(&cinfo);
|
||||
if (!image) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
goto bye;
|
||||
}
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
ptr = image->data;
|
||||
ptr = image->data;
|
||||
|
||||
if (cinfo.out_color_space == JCS_RGB) {
|
||||
if (context->flags.optimize_for_speed) {
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
jpeg_read_scanlines(&cinfo, buffer, (JDIMENSION) 1);
|
||||
bptr = buffer[0];
|
||||
for (i = 0; i < cinfo.image_width; i++) {
|
||||
*ptr++ = *bptr++;
|
||||
*ptr++ = *bptr++;
|
||||
*ptr++ = *bptr++;
|
||||
ptr++; /* skip alpha channel */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
jpeg_read_scanlines(&cinfo, buffer, (JDIMENSION) 1);
|
||||
bptr = buffer[0];
|
||||
memcpy(ptr, bptr, cinfo.image_width * 3);
|
||||
ptr += cinfo.image_width * 3;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
jpeg_read_scanlines(&cinfo, buffer, (JDIMENSION) 1);
|
||||
bptr = buffer[0];
|
||||
for (i = 0; i < cinfo.image_width; i++) {
|
||||
*ptr++ = *bptr;
|
||||
*ptr++ = *bptr;
|
||||
*ptr++ = *bptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cinfo.out_color_space==JCS_RGB) {
|
||||
if (context->flags.optimize_for_speed) {
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
jpeg_read_scanlines(&cinfo, buffer,(JDIMENSION) 1);
|
||||
bptr = buffer[0];
|
||||
for (i=0; i<cinfo.image_width; i++) {
|
||||
*ptr++ = *bptr++;
|
||||
*ptr++ = *bptr++;
|
||||
*ptr++ = *bptr++;
|
||||
ptr++; /* skip alpha channel */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
jpeg_read_scanlines(&cinfo, buffer,(JDIMENSION) 1);
|
||||
bptr = buffer[0];
|
||||
memcpy(ptr, bptr, cinfo.image_width*3);
|
||||
ptr += cinfo.image_width*3;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
jpeg_read_scanlines(&cinfo, buffer,(JDIMENSION) 1);
|
||||
bptr = buffer[0];
|
||||
for (i=0; i<cinfo.image_width; i++) {
|
||||
*ptr++ = *bptr;
|
||||
*ptr++ = *bptr;
|
||||
*ptr++ = *bptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
bye:
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
|
||||
bye:
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(file);
|
||||
|
||||
fclose(file);
|
||||
if (buffer[0])
|
||||
free(buffer[0]);
|
||||
|
||||
if (buffer[0])
|
||||
free(buffer[0]);
|
||||
|
||||
return image;
|
||||
return image;
|
||||
}
|
||||
|
||||
#endif /* USE_JPEG */
|
||||
|
||||
#endif /* USE_JPEG */
|
||||
|
||||
400
wrlib/load.c
400
wrlib/load.c
@@ -43,13 +43,12 @@
|
||||
#endif
|
||||
|
||||
typedef struct RCachedImage {
|
||||
RImage *image;
|
||||
char *file;
|
||||
time_t last_modif; /* last time file was modified */
|
||||
time_t last_use; /* last time image was used */
|
||||
RImage *image;
|
||||
char *file;
|
||||
time_t last_modif; /* last time file was modified */
|
||||
time_t last_use; /* last time image was used */
|
||||
} RCachedImage;
|
||||
|
||||
|
||||
/*
|
||||
* Size of image cache
|
||||
*/
|
||||
@@ -58,7 +57,7 @@ static int RImageCacheSize = -1;
|
||||
/*
|
||||
* Max. size of image to store in cache
|
||||
*/
|
||||
static int RImageCacheMaxImage = -1; /* 0 = any size */
|
||||
static int RImageCacheMaxImage = -1; /* 0 = any size */
|
||||
|
||||
#define IMAGE_CACHE_SIZE 8
|
||||
|
||||
@@ -66,10 +65,6 @@ static int RImageCacheMaxImage = -1; /* 0 = any size */
|
||||
|
||||
static RCachedImage *RImageCache;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define IM_ERROR -1
|
||||
#define IM_UNKNOWN 0
|
||||
#define IM_XPM 1
|
||||
@@ -82,290 +77,271 @@ static RCachedImage *RImageCache;
|
||||
/* Increase this when adding new image types! */
|
||||
#define IM_TYPES 6
|
||||
|
||||
|
||||
static int identFile(char *path);
|
||||
|
||||
extern RImage *RLoadPPM(RContext *context, char *file_name, int index);
|
||||
|
||||
extern RImage *RLoadXPM(RContext *context, char *file, int index);
|
||||
extern RImage *RLoadPPM(RContext * context, char *file_name, int index);
|
||||
|
||||
extern RImage *RLoadXPM(RContext * context, char *file, int index);
|
||||
|
||||
#ifdef USE_TIFF
|
||||
extern RImage *RLoadTIFF(RContext *context, char *file, int index);
|
||||
extern RImage *RLoadTIFF(RContext * context, char *file, int index);
|
||||
#endif
|
||||
#ifdef USE_PNG
|
||||
extern RImage *RLoadPNG(RContext *context, char *file, int index);
|
||||
extern RImage *RLoadPNG(RContext * context, char *file, int index);
|
||||
#endif
|
||||
#ifdef USE_JPEG
|
||||
extern RImage *RLoadJPEG(RContext *context, char *file_name, int index);
|
||||
extern RImage *RLoadJPEG(RContext * context, char *file_name, int index);
|
||||
#endif
|
||||
#ifdef USE_GIF
|
||||
extern RImage *RLoadGIF(RContext *context, char *file_name, int index);
|
||||
extern RImage *RLoadGIF(RContext * context, char *file_name, int index);
|
||||
#endif
|
||||
|
||||
|
||||
char**
|
||||
RSupportedFileFormats(void)
|
||||
char **RSupportedFileFormats(void)
|
||||
{
|
||||
static char *tmp[IM_TYPES+1];
|
||||
int i = 0;
|
||||
static char *tmp[IM_TYPES + 1];
|
||||
int i = 0;
|
||||
|
||||
/* built-in */
|
||||
tmp[i++] = "XPM";
|
||||
/* built-in */
|
||||
tmp[i++] = "PPM";
|
||||
/* built-in */
|
||||
tmp[i++] = "XPM";
|
||||
/* built-in */
|
||||
tmp[i++] = "PPM";
|
||||
#ifdef USE_TIFF
|
||||
tmp[i++] = "TIFF";
|
||||
tmp[i++] = "TIFF";
|
||||
#endif
|
||||
#ifdef USE_PNG
|
||||
tmp[i++] = "PNG";
|
||||
tmp[i++] = "PNG";
|
||||
#endif
|
||||
#ifdef USE_JPEG
|
||||
tmp[i++] = "JPEG";
|
||||
tmp[i++] = "JPEG";
|
||||
#endif
|
||||
#ifdef USE_GIF
|
||||
tmp[i++] = "GIF";
|
||||
tmp[i++] = "GIF";
|
||||
#endif
|
||||
tmp[i] = NULL;
|
||||
tmp[i] = NULL;
|
||||
|
||||
return tmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_cache()
|
||||
static void init_cache()
|
||||
{
|
||||
char *tmp;
|
||||
char *tmp;
|
||||
|
||||
tmp = getenv("RIMAGE_CACHE");
|
||||
if (!tmp || sscanf(tmp, "%i", &RImageCacheSize)!=1) {
|
||||
RImageCacheSize = IMAGE_CACHE_SIZE;
|
||||
}
|
||||
if (RImageCacheSize<0)
|
||||
RImageCacheSize = 0;
|
||||
tmp = getenv("RIMAGE_CACHE");
|
||||
if (!tmp || sscanf(tmp, "%i", &RImageCacheSize) != 1) {
|
||||
RImageCacheSize = IMAGE_CACHE_SIZE;
|
||||
}
|
||||
if (RImageCacheSize < 0)
|
||||
RImageCacheSize = 0;
|
||||
|
||||
tmp = getenv("RIMAGE_CACHE_SIZE");
|
||||
if (!tmp || sscanf(tmp, "%i", &RImageCacheMaxImage)!=1) {
|
||||
RImageCacheMaxImage = IMAGE_CACHE_MAX_IMAGE;
|
||||
}
|
||||
tmp = getenv("RIMAGE_CACHE_SIZE");
|
||||
if (!tmp || sscanf(tmp, "%i", &RImageCacheMaxImage) != 1) {
|
||||
RImageCacheMaxImage = IMAGE_CACHE_MAX_IMAGE;
|
||||
}
|
||||
|
||||
if (RImageCacheSize>0) {
|
||||
RImageCache = malloc(sizeof(RCachedImage)*RImageCacheSize);
|
||||
if (RImageCache==NULL) {
|
||||
printf("wrlib: out of memory for image cache\n");
|
||||
return;
|
||||
}
|
||||
memset(RImageCache, 0, sizeof(RCachedImage)*RImageCacheSize);
|
||||
}
|
||||
if (RImageCacheSize > 0) {
|
||||
RImageCache = malloc(sizeof(RCachedImage) * RImageCacheSize);
|
||||
if (RImageCache == NULL) {
|
||||
printf("wrlib: out of memory for image cache\n");
|
||||
return;
|
||||
}
|
||||
memset(RImageCache, 0, sizeof(RCachedImage) * RImageCacheSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RImage*
|
||||
RLoadImage(RContext *context, char *file, int index)
|
||||
RImage *RLoadImage(RContext * context, char *file, int index)
|
||||
{
|
||||
RImage *image = NULL;
|
||||
int i;
|
||||
struct stat st;
|
||||
RImage *image = NULL;
|
||||
int i;
|
||||
struct stat st;
|
||||
|
||||
assert(file!=NULL);
|
||||
assert(file != NULL);
|
||||
|
||||
if (RImageCacheSize<0) {
|
||||
init_cache();
|
||||
}
|
||||
if (RImageCacheSize < 0) {
|
||||
init_cache();
|
||||
}
|
||||
|
||||
if (RImageCacheSize>0) {
|
||||
if (RImageCacheSize > 0) {
|
||||
|
||||
for (i=0; i<RImageCacheSize; i++) {
|
||||
if (RImageCache[i].file
|
||||
&& strcmp(file, RImageCache[i].file)==0) {
|
||||
for (i = 0; i < RImageCacheSize; i++) {
|
||||
if (RImageCache[i].file && strcmp(file, RImageCache[i].file) == 0) {
|
||||
|
||||
if (stat(file, &st)==0
|
||||
&& st.st_mtime == RImageCache[i].last_modif) {
|
||||
RImageCache[i].last_use = time(NULL);
|
||||
if (stat(file, &st) == 0 && st.st_mtime == RImageCache[i].last_modif) {
|
||||
RImageCache[i].last_use = time(NULL);
|
||||
|
||||
return RCloneImage(RImageCache[i].image);
|
||||
return RCloneImage(RImageCache[i].image);
|
||||
|
||||
} else {
|
||||
free(RImageCache[i].file);
|
||||
RImageCache[i].file = NULL;
|
||||
RReleaseImage(RImageCache[i].image);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
free(RImageCache[i].file);
|
||||
RImageCache[i].file = NULL;
|
||||
RReleaseImage(RImageCache[i].image);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (identFile(file)) {
|
||||
case IM_ERROR:
|
||||
return NULL;
|
||||
switch (identFile(file)) {
|
||||
case IM_ERROR:
|
||||
return NULL;
|
||||
|
||||
case IM_UNKNOWN:
|
||||
RErrorCode = RERR_BADFORMAT;
|
||||
return NULL;
|
||||
case IM_UNKNOWN:
|
||||
RErrorCode = RERR_BADFORMAT;
|
||||
return NULL;
|
||||
|
||||
case IM_XPM:
|
||||
image = RLoadXPM(context, file, index);
|
||||
break;
|
||||
case IM_XPM:
|
||||
image = RLoadXPM(context, file, index);
|
||||
break;
|
||||
|
||||
#ifdef USE_TIFF
|
||||
case IM_TIFF:
|
||||
image = RLoadTIFF(context, file, index);
|
||||
break;
|
||||
#endif /* USE_TIFF */
|
||||
case IM_TIFF:
|
||||
image = RLoadTIFF(context, file, index);
|
||||
break;
|
||||
#endif /* USE_TIFF */
|
||||
|
||||
#ifdef USE_PNG
|
||||
case IM_PNG:
|
||||
image = RLoadPNG(context, file, index);
|
||||
break;
|
||||
#endif /* USE_PNG */
|
||||
case IM_PNG:
|
||||
image = RLoadPNG(context, file, index);
|
||||
break;
|
||||
#endif /* USE_PNG */
|
||||
|
||||
#ifdef USE_JPEG
|
||||
case IM_JPEG:
|
||||
image = RLoadJPEG(context, file, index);
|
||||
break;
|
||||
#endif /* USE_JPEG */
|
||||
case IM_JPEG:
|
||||
image = RLoadJPEG(context, file, index);
|
||||
break;
|
||||
#endif /* USE_JPEG */
|
||||
|
||||
#ifdef USE_GIF
|
||||
case IM_GIF:
|
||||
image = RLoadGIF(context, file, index);
|
||||
break;
|
||||
#endif /* USE_GIF */
|
||||
case IM_GIF:
|
||||
image = RLoadGIF(context, file, index);
|
||||
break;
|
||||
#endif /* USE_GIF */
|
||||
|
||||
case IM_PPM:
|
||||
image = RLoadPPM(context, file, index);
|
||||
break;
|
||||
case IM_PPM:
|
||||
image = RLoadPPM(context, file, index);
|
||||
break;
|
||||
|
||||
default:
|
||||
RErrorCode = RERR_BADFORMAT;
|
||||
return NULL;
|
||||
}
|
||||
default:
|
||||
RErrorCode = RERR_BADFORMAT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* store image in cache */
|
||||
if (RImageCacheSize > 0 && image &&
|
||||
(RImageCacheMaxImage == 0 || RImageCacheMaxImage >= image->width * image->height)) {
|
||||
time_t oldest = time(NULL);
|
||||
int oldest_idx = 0;
|
||||
int done = 0;
|
||||
|
||||
/* store image in cache */
|
||||
if (RImageCacheSize>0 && image &&
|
||||
(RImageCacheMaxImage==0
|
||||
|| RImageCacheMaxImage >= image->width*image->height)) {
|
||||
time_t oldest=time(NULL);
|
||||
int oldest_idx = 0;
|
||||
int done = 0;
|
||||
for (i = 0; i < RImageCacheSize; i++) {
|
||||
if (!RImageCache[i].file) {
|
||||
RImageCache[i].file = malloc(strlen(file) + 1);
|
||||
strcpy(RImageCache[i].file, file);
|
||||
RImageCache[i].image = RCloneImage(image);
|
||||
RImageCache[i].last_modif = st.st_mtime;
|
||||
RImageCache[i].last_use = time(NULL);
|
||||
done = 1;
|
||||
break;
|
||||
} else {
|
||||
if (oldest > RImageCache[i].last_use) {
|
||||
oldest = RImageCache[i].last_use;
|
||||
oldest_idx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<RImageCacheSize; i++) {
|
||||
if (!RImageCache[i].file) {
|
||||
RImageCache[i].file = malloc(strlen(file)+1);
|
||||
strcpy(RImageCache[i].file, file);
|
||||
RImageCache[i].image = RCloneImage(image);
|
||||
RImageCache[i].last_modif = st.st_mtime;
|
||||
RImageCache[i].last_use = time(NULL);
|
||||
done = 1;
|
||||
break;
|
||||
} else {
|
||||
if (oldest > RImageCache[i].last_use) {
|
||||
oldest = RImageCache[i].last_use;
|
||||
oldest_idx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* if no slot available, dump least recently used one */
|
||||
if (!done) {
|
||||
free(RImageCache[oldest_idx].file);
|
||||
RReleaseImage(RImageCache[oldest_idx].image);
|
||||
RImageCache[oldest_idx].file = malloc(strlen(file) + 1);
|
||||
strcpy(RImageCache[oldest_idx].file, file);
|
||||
RImageCache[oldest_idx].image = RCloneImage(image);
|
||||
RImageCache[oldest_idx].last_modif = st.st_mtime;
|
||||
RImageCache[oldest_idx].last_use = time(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* if no slot available, dump least recently used one */
|
||||
if (!done) {
|
||||
free(RImageCache[oldest_idx].file);
|
||||
RReleaseImage(RImageCache[oldest_idx].image);
|
||||
RImageCache[oldest_idx].file = malloc(strlen(file)+1);
|
||||
strcpy(RImageCache[oldest_idx].file, file);
|
||||
RImageCache[oldest_idx].image = RCloneImage(image);
|
||||
RImageCache[oldest_idx].last_modif = st.st_mtime;
|
||||
RImageCache[oldest_idx].last_use = time(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
RGetImageFileFormat(char *file)
|
||||
char *RGetImageFileFormat(char *file)
|
||||
{
|
||||
switch (identFile(file)) {
|
||||
case IM_XPM:
|
||||
return "XPM";
|
||||
switch (identFile(file)) {
|
||||
case IM_XPM:
|
||||
return "XPM";
|
||||
|
||||
#ifdef USE_TIFF
|
||||
case IM_TIFF:
|
||||
return "TIFF";
|
||||
#endif /* USE_TIFF */
|
||||
case IM_TIFF:
|
||||
return "TIFF";
|
||||
#endif /* USE_TIFF */
|
||||
|
||||
#ifdef USE_PNG
|
||||
case IM_PNG:
|
||||
return "PNG";
|
||||
#endif /* USE_PNG */
|
||||
case IM_PNG:
|
||||
return "PNG";
|
||||
#endif /* USE_PNG */
|
||||
|
||||
#ifdef USE_JPEG
|
||||
case IM_JPEG:
|
||||
return "JPEG";
|
||||
#endif /* USE_JPEG */
|
||||
case IM_JPEG:
|
||||
return "JPEG";
|
||||
#endif /* USE_JPEG */
|
||||
|
||||
#ifdef USE_GIF
|
||||
case IM_GIF:
|
||||
return "GIF";
|
||||
#endif /* USE_GIF */
|
||||
case IM_GIF:
|
||||
return "GIF";
|
||||
#endif /* USE_GIF */
|
||||
|
||||
case IM_PPM:
|
||||
return "PPM";
|
||||
case IM_PPM:
|
||||
return "PPM";
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
identFile(char *path)
|
||||
static int identFile(char *path)
|
||||
{
|
||||
int fd;
|
||||
unsigned char buffer[32];
|
||||
int fd;
|
||||
unsigned char buffer[32];
|
||||
|
||||
assert(path!=NULL);
|
||||
assert(path != NULL);
|
||||
|
||||
fd = open(path, O_RDONLY|O_BINARY);
|
||||
if (fd < 0) {
|
||||
RErrorCode = RERR_OPEN;
|
||||
return IM_ERROR;
|
||||
}
|
||||
if (read(fd, buffer, 32)<1) {
|
||||
close(fd);
|
||||
RErrorCode = RERR_READ;
|
||||
return IM_ERROR;
|
||||
}
|
||||
close(fd);
|
||||
fd = open(path, O_RDONLY | O_BINARY);
|
||||
if (fd < 0) {
|
||||
RErrorCode = RERR_OPEN;
|
||||
return IM_ERROR;
|
||||
}
|
||||
if (read(fd, buffer, 32) < 1) {
|
||||
close(fd);
|
||||
RErrorCode = RERR_READ;
|
||||
return IM_ERROR;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
/* check for XPM */
|
||||
if (strncmp((char*)buffer, "/* XPM */", 9)==0)
|
||||
return IM_XPM;
|
||||
/* check for XPM */
|
||||
if (strncmp((char *)buffer, "/* XPM */", 9) == 0)
|
||||
return IM_XPM;
|
||||
|
||||
/* check for TIFF */
|
||||
if ((buffer[0]=='I' && buffer[1]=='I' && buffer[2]=='*' && buffer[3]==0)
|
||||
||(buffer[0]=='M' && buffer[1]=='M' && buffer[2]==0 && buffer[3]=='*'))
|
||||
return IM_TIFF;
|
||||
/* check for TIFF */
|
||||
if ((buffer[0] == 'I' && buffer[1] == 'I' && buffer[2] == '*' && buffer[3] == 0)
|
||||
|| (buffer[0] == 'M' && buffer[1] == 'M' && buffer[2] == 0 && buffer[3] == '*'))
|
||||
return IM_TIFF;
|
||||
|
||||
#ifdef USE_PNG
|
||||
/* check for PNG */
|
||||
if (png_check_sig(buffer, 8))
|
||||
return IM_PNG;
|
||||
/* check for PNG */
|
||||
if (png_check_sig(buffer, 8))
|
||||
return IM_PNG;
|
||||
#endif
|
||||
|
||||
/* check for raw PPM or PGM */
|
||||
if (buffer[0]=='P' && (buffer[1]=='5' || buffer[1]=='6'))
|
||||
return IM_PPM;
|
||||
/* check for raw PPM or PGM */
|
||||
if (buffer[0] == 'P' && (buffer[1] == '5' || buffer[1] == '6'))
|
||||
return IM_PPM;
|
||||
|
||||
/* check for JPEG */
|
||||
if (buffer[0] == 0xff && buffer[1] == 0xd8)
|
||||
return IM_JPEG;
|
||||
/* check for JPEG */
|
||||
if (buffer[0] == 0xff && buffer[1] == 0xd8)
|
||||
return IM_JPEG;
|
||||
|
||||
/* check for GIF */
|
||||
if (buffer[0] == 'G' && buffer[1] == 'I' && buffer[2] == 'F')
|
||||
return IM_GIF;
|
||||
/* check for GIF */
|
||||
if (buffer[0] == 'G' && buffer[1] == 'I' && buffer[2] == 'F')
|
||||
return IM_GIF;
|
||||
|
||||
return IM_UNKNOWN;
|
||||
return IM_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
307
wrlib/misc.c
307
wrlib/misc.c
@@ -26,194 +26,183 @@
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
void
|
||||
RBevelImage(RImage *image, int bevel_type)
|
||||
void RBevelImage(RImage * image, int bevel_type)
|
||||
{
|
||||
RColor color;
|
||||
RColor cdelta;
|
||||
int w, h;
|
||||
RColor color;
|
||||
RColor cdelta;
|
||||
int w, h;
|
||||
|
||||
if (image->width<3 || image->height<3)
|
||||
return;
|
||||
if (image->width < 3 || image->height < 3)
|
||||
return;
|
||||
|
||||
w = image->width;
|
||||
h = image->height;
|
||||
if (bevel_type>0) { /* raised */
|
||||
/* top */
|
||||
cdelta.alpha = 0;
|
||||
cdelta.red = cdelta.green = cdelta.blue = 80;
|
||||
ROperateLine(image, RAddOperation, 0, 0, w-1, 0, &cdelta);
|
||||
if (bevel_type==RBEV_RAISED3 && w>3)
|
||||
ROperateLine(image, RAddOperation, 1, 1, w-3, 1,&cdelta);
|
||||
w = image->width;
|
||||
h = image->height;
|
||||
if (bevel_type > 0) { /* raised */
|
||||
/* top */
|
||||
cdelta.alpha = 0;
|
||||
cdelta.red = cdelta.green = cdelta.blue = 80;
|
||||
ROperateLine(image, RAddOperation, 0, 0, w - 1, 0, &cdelta);
|
||||
if (bevel_type == RBEV_RAISED3 && w > 3)
|
||||
ROperateLine(image, RAddOperation, 1, 1, w - 3, 1, &cdelta);
|
||||
|
||||
/* left */
|
||||
ROperateLine(image, RAddOperation, 0, 1, 0, h-1, &cdelta);
|
||||
if (bevel_type==RBEV_RAISED3 && h>3)
|
||||
ROperateLine(image, RAddOperation, 1, 2, 1, h-3, &cdelta);
|
||||
/* left */
|
||||
ROperateLine(image, RAddOperation, 0, 1, 0, h - 1, &cdelta);
|
||||
if (bevel_type == RBEV_RAISED3 && h > 3)
|
||||
ROperateLine(image, RAddOperation, 1, 2, 1, h - 3, &cdelta);
|
||||
|
||||
/* bottom */
|
||||
color.alpha = 255;
|
||||
color.red = color.green = color.blue = 0;
|
||||
cdelta.red = cdelta.green = cdelta.blue = 40;
|
||||
if (bevel_type==RBEV_RAISED2 || bevel_type==RBEV_RAISED3) {
|
||||
ROperateLine(image, RSubtractOperation, 0, h-2, w-3,
|
||||
h-2, &cdelta);
|
||||
RDrawLine(image, 0, h-1, w-1, h-1, &color);
|
||||
} else {
|
||||
ROperateLine(image, RSubtractOperation, 0, h-1, w-1, h-1,
|
||||
&cdelta);
|
||||
}
|
||||
/* bottom */
|
||||
color.alpha = 255;
|
||||
color.red = color.green = color.blue = 0;
|
||||
cdelta.red = cdelta.green = cdelta.blue = 40;
|
||||
if (bevel_type == RBEV_RAISED2 || bevel_type == RBEV_RAISED3) {
|
||||
ROperateLine(image, RSubtractOperation, 0, h - 2, w - 3, h - 2, &cdelta);
|
||||
RDrawLine(image, 0, h - 1, w - 1, h - 1, &color);
|
||||
} else {
|
||||
ROperateLine(image, RSubtractOperation, 0, h - 1, w - 1, h - 1, &cdelta);
|
||||
}
|
||||
|
||||
/* right */
|
||||
if (bevel_type==RBEV_RAISED2 || bevel_type==RBEV_RAISED3) {
|
||||
ROperateLine(image, RSubtractOperation, w-2, 0, w-2, h-2,
|
||||
&cdelta);
|
||||
RDrawLine(image, w-1, 0, w-1, h-2, &color);
|
||||
} else {
|
||||
ROperateLine(image, RSubtractOperation, w-1, 0, w-1, h-2,
|
||||
&cdelta);
|
||||
}
|
||||
} else { /* sunken */
|
||||
cdelta.alpha = 0;
|
||||
cdelta.red = cdelta.green = cdelta.blue = 40;
|
||||
ROperateLine(image, RSubtractOperation, 0, 0, w-1, 0,
|
||||
&cdelta); /* top */
|
||||
ROperateLine(image, RSubtractOperation, 0, 1, 0, h-1,
|
||||
&cdelta); /* left */
|
||||
cdelta.red = cdelta.green = cdelta.blue = 80;
|
||||
ROperateLine(image, RAddOperation, 0, h-1, w-1, h-1, &cdelta); /* bottom */
|
||||
ROperateLine(image, RAddOperation, w-1, 0, w-1, h-2, &cdelta); /* right */
|
||||
}
|
||||
/* right */
|
||||
if (bevel_type == RBEV_RAISED2 || bevel_type == RBEV_RAISED3) {
|
||||
ROperateLine(image, RSubtractOperation, w - 2, 0, w - 2, h - 2, &cdelta);
|
||||
RDrawLine(image, w - 1, 0, w - 1, h - 2, &color);
|
||||
} else {
|
||||
ROperateLine(image, RSubtractOperation, w - 1, 0, w - 1, h - 2, &cdelta);
|
||||
}
|
||||
} else { /* sunken */
|
||||
cdelta.alpha = 0;
|
||||
cdelta.red = cdelta.green = cdelta.blue = 40;
|
||||
ROperateLine(image, RSubtractOperation, 0, 0, w - 1, 0, &cdelta); /* top */
|
||||
ROperateLine(image, RSubtractOperation, 0, 1, 0, h - 1, &cdelta); /* left */
|
||||
cdelta.red = cdelta.green = cdelta.blue = 80;
|
||||
ROperateLine(image, RAddOperation, 0, h - 1, w - 1, h - 1, &cdelta); /* bottom */
|
||||
ROperateLine(image, RAddOperation, w - 1, 0, w - 1, h - 2, &cdelta); /* right */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RFillImage(RImage *image, RColor *color)
|
||||
void RFillImage(RImage * image, RColor * color)
|
||||
{
|
||||
unsigned char *d = image->data;
|
||||
unsigned lineSize;
|
||||
int i;
|
||||
unsigned char *d = image->data;
|
||||
unsigned lineSize;
|
||||
int i;
|
||||
|
||||
if (image->format == RRGBAFormat) {
|
||||
for (i = 0; i < image->width; i++) {
|
||||
*d++ = color->red;
|
||||
*d++ = color->green;
|
||||
*d++ = color->blue;
|
||||
*d++ = color->alpha;
|
||||
}
|
||||
lineSize = image->width*4;
|
||||
for (i = 1; i < image->height; i++, d+=lineSize) {
|
||||
memcpy(d, image->data, lineSize);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < image->width; i++) {
|
||||
*d++ = color->red;
|
||||
*d++ = color->green;
|
||||
*d++ = color->blue;
|
||||
}
|
||||
lineSize = image->width*3;
|
||||
for (i = 1; i < image->height; i++, d+=lineSize) {
|
||||
memcpy(d, image->data, lineSize);
|
||||
}
|
||||
}
|
||||
if (image->format == RRGBAFormat) {
|
||||
for (i = 0; i < image->width; i++) {
|
||||
*d++ = color->red;
|
||||
*d++ = color->green;
|
||||
*d++ = color->blue;
|
||||
*d++ = color->alpha;
|
||||
}
|
||||
lineSize = image->width * 4;
|
||||
for (i = 1; i < image->height; i++, d += lineSize) {
|
||||
memcpy(d, image->data, lineSize);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < image->width; i++) {
|
||||
*d++ = color->red;
|
||||
*d++ = color->green;
|
||||
*d++ = color->blue;
|
||||
}
|
||||
lineSize = image->width * 3;
|
||||
for (i = 1; i < image->height; i++, d += lineSize) {
|
||||
memcpy(d, image->data, lineSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RClearImage(RImage *image, RColor *color)
|
||||
void RClearImage(RImage * image, RColor * color)
|
||||
{
|
||||
unsigned char *d = image->data;
|
||||
unsigned lineSize;
|
||||
int i;
|
||||
unsigned char *d = image->data;
|
||||
unsigned lineSize;
|
||||
int i;
|
||||
|
||||
if (color->alpha==255) {
|
||||
if (image->format == RRGBAFormat) {
|
||||
for (i = 0; i < image->width; i++) {
|
||||
*d++ = color->red;
|
||||
*d++ = color->green;
|
||||
*d++ = color->blue;
|
||||
*d++ = 0xff;
|
||||
}
|
||||
lineSize = image->width*4;
|
||||
for (i = 1; i < image->height; i++, d+=lineSize) {
|
||||
memcpy(d, image->data, lineSize);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < image->width; i++) {
|
||||
*d++ = color->red;
|
||||
*d++ = color->green;
|
||||
*d++ = color->blue;
|
||||
}
|
||||
lineSize = image->width*3;
|
||||
for (i = 1; i < image->height; i++, d+=lineSize) {
|
||||
memcpy(d, image->data, lineSize);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int bytes = image->width*image->height;
|
||||
int alpha, nalpha, r, g, b;
|
||||
if (color->alpha == 255) {
|
||||
if (image->format == RRGBAFormat) {
|
||||
for (i = 0; i < image->width; i++) {
|
||||
*d++ = color->red;
|
||||
*d++ = color->green;
|
||||
*d++ = color->blue;
|
||||
*d++ = 0xff;
|
||||
}
|
||||
lineSize = image->width * 4;
|
||||
for (i = 1; i < image->height; i++, d += lineSize) {
|
||||
memcpy(d, image->data, lineSize);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < image->width; i++) {
|
||||
*d++ = color->red;
|
||||
*d++ = color->green;
|
||||
*d++ = color->blue;
|
||||
}
|
||||
lineSize = image->width * 3;
|
||||
for (i = 1; i < image->height; i++, d += lineSize) {
|
||||
memcpy(d, image->data, lineSize);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int bytes = image->width * image->height;
|
||||
int alpha, nalpha, r, g, b;
|
||||
|
||||
alpha = color->alpha;
|
||||
r = color->red * alpha;
|
||||
g = color->green * alpha;
|
||||
b = color->blue * alpha;
|
||||
nalpha = 255 - alpha;
|
||||
alpha = color->alpha;
|
||||
r = color->red * alpha;
|
||||
g = color->green * alpha;
|
||||
b = color->blue * alpha;
|
||||
nalpha = 255 - alpha;
|
||||
|
||||
for (i=0; i<bytes; i++) {
|
||||
*d = (((int)*d * nalpha) + r)/256; d++;
|
||||
*d = (((int)*d * nalpha) + g)/256; d++;
|
||||
*d = (((int)*d * nalpha) + b)/256; d++;
|
||||
if (image->format == RRGBAFormat) {
|
||||
d++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < bytes; i++) {
|
||||
*d = (((int)*d * nalpha) + r) / 256;
|
||||
d++;
|
||||
*d = (((int)*d * nalpha) + g) / 256;
|
||||
d++;
|
||||
*d = (((int)*d * nalpha) + b) / 256;
|
||||
d++;
|
||||
if (image->format == RRGBAFormat) {
|
||||
d++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
RMessageForError(int errorCode)
|
||||
const char *RMessageForError(int errorCode)
|
||||
{
|
||||
switch (errorCode) {
|
||||
case RERR_NONE:
|
||||
return "no error";
|
||||
switch (errorCode) {
|
||||
case RERR_NONE:
|
||||
return "no error";
|
||||
|
||||
case RERR_OPEN:
|
||||
return "could not open file";
|
||||
case RERR_OPEN:
|
||||
return "could not open file";
|
||||
|
||||
case RERR_READ:
|
||||
return "error reading from file";
|
||||
case RERR_READ:
|
||||
return "error reading from file";
|
||||
|
||||
case RERR_WRITE:
|
||||
return "error writing to file";
|
||||
case RERR_WRITE:
|
||||
return "error writing to file";
|
||||
|
||||
case RERR_NOMEMORY:
|
||||
return "out of memory";
|
||||
case RERR_NOMEMORY:
|
||||
return "out of memory";
|
||||
|
||||
case RERR_NOCOLOR:
|
||||
return "out of color cells";
|
||||
case RERR_NOCOLOR:
|
||||
return "out of color cells";
|
||||
|
||||
case RERR_BADIMAGEFILE:
|
||||
return "invalid or corrupted image file";
|
||||
case RERR_BADIMAGEFILE:
|
||||
return "invalid or corrupted image file";
|
||||
|
||||
case RERR_BADFORMAT:
|
||||
return "the image format in the file is not supported and can't be loaded";
|
||||
case RERR_BADFORMAT:
|
||||
return "the image format in the file is not supported and can't be loaded";
|
||||
|
||||
case RERR_BADINDEX:
|
||||
return "image file does not contain requested image index";
|
||||
case RERR_BADINDEX:
|
||||
return "image file does not contain requested image index";
|
||||
|
||||
case RERR_BADVISUALID:
|
||||
return "request for an invalid visual ID";
|
||||
case RERR_BADVISUALID:
|
||||
return "request for an invalid visual ID";
|
||||
|
||||
case RERR_STDCMAPFAIL:
|
||||
return "failed to create standard colormap";
|
||||
case RERR_STDCMAPFAIL:
|
||||
return "failed to create standard colormap";
|
||||
|
||||
case RERR_XERROR:
|
||||
return "internal X error";
|
||||
case RERR_XERROR:
|
||||
return "internal X error";
|
||||
|
||||
default:
|
||||
case RERR_INTERNAL:
|
||||
return "internal error";
|
||||
}
|
||||
default:
|
||||
case RERR_INTERNAL:
|
||||
return "internal error";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
959
wrlib/nxpm.c
959
wrlib/nxpm.c
File diff suppressed because it is too large
Load Diff
308
wrlib/png.c
308
wrlib/png.c
@@ -31,14 +31,13 @@
|
||||
# ifdef _AIX
|
||||
# pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
char *alloca ();
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
char *alloca();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_PNG
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -49,193 +48,184 @@ char *alloca ();
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
RImage*
|
||||
RLoadPNG(RContext *context, char *file, int index)
|
||||
RImage *RLoadPNG(RContext * context, char *file, int index)
|
||||
{
|
||||
char *tmp;
|
||||
RImage *image=NULL;
|
||||
FILE *f;
|
||||
png_structp png;
|
||||
png_infop pinfo, einfo;
|
||||
png_color_16p bkcolor;
|
||||
int alpha;
|
||||
int x, y, i;
|
||||
double gamma, sgamma;
|
||||
png_uint_32 width, height;
|
||||
int depth, junk, color_type;
|
||||
png_bytep *png_rows;
|
||||
unsigned char *ptr;
|
||||
char *tmp;
|
||||
RImage *image = NULL;
|
||||
FILE *f;
|
||||
png_structp png;
|
||||
png_infop pinfo, einfo;
|
||||
png_color_16p bkcolor;
|
||||
int alpha;
|
||||
int x, y, i;
|
||||
double gamma, sgamma;
|
||||
png_uint_32 width, height;
|
||||
int depth, junk, color_type;
|
||||
png_bytep *png_rows;
|
||||
unsigned char *ptr;
|
||||
|
||||
f = fopen(file, "rb");
|
||||
if (!f) {
|
||||
RErrorCode = RERR_OPEN;
|
||||
return NULL;
|
||||
}
|
||||
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
|
||||
(png_error_ptr)NULL, (png_error_ptr)NULL);
|
||||
if (!png) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
f = fopen(file, "rb");
|
||||
if (!f) {
|
||||
RErrorCode = RERR_OPEN;
|
||||
return NULL;
|
||||
}
|
||||
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr) NULL, (png_error_ptr) NULL);
|
||||
if (!png) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pinfo = png_create_info_struct(png);
|
||||
if (!pinfo) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, NULL, NULL);
|
||||
return NULL;
|
||||
}
|
||||
pinfo = png_create_info_struct(png);
|
||||
if (!pinfo) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, NULL, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
einfo = png_create_info_struct(png);
|
||||
if (!einfo) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, &pinfo, NULL);
|
||||
return NULL;
|
||||
}
|
||||
einfo = png_create_info_struct(png);
|
||||
if (!einfo) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, &pinfo, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RErrorCode = RERR_INTERNAL;
|
||||
if (setjmp(png->jmpbuf)) {
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
if (image)
|
||||
RReleaseImage(image);
|
||||
return NULL;
|
||||
}
|
||||
RErrorCode = RERR_INTERNAL;
|
||||
if (setjmp(png->jmpbuf)) {
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
if (image)
|
||||
RReleaseImage(image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
png_init_io(png, f);
|
||||
png_init_io(png, f);
|
||||
|
||||
png_read_info(png, pinfo);
|
||||
png_read_info(png, pinfo);
|
||||
|
||||
png_get_IHDR(png, pinfo, &width, &height, &depth, &color_type,
|
||||
&junk, &junk, &junk);
|
||||
png_get_IHDR(png, pinfo, &width, &height, &depth, &color_type, &junk, &junk, &junk);
|
||||
|
||||
/* sanity check */
|
||||
if (width < 1 || height < 1) {
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
if (width < 1 || height < 1) {
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
return NULL;
|
||||
}
|
||||
/* check for an alpha channel */
|
||||
if (png_get_valid(png, pinfo, PNG_INFO_tRNS))
|
||||
alpha = True;
|
||||
else
|
||||
alpha = (color_type & PNG_COLOR_MASK_ALPHA);
|
||||
|
||||
/* allocate RImage */
|
||||
image = RCreateImage(width, height, alpha);
|
||||
if (!image) {
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* check for an alpha channel */
|
||||
if (png_get_valid(png, pinfo, PNG_INFO_tRNS))
|
||||
alpha = True;
|
||||
else
|
||||
alpha = (color_type & PNG_COLOR_MASK_ALPHA);
|
||||
/* normalize to 8bpp with alpha channel */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE && depth <= 8)
|
||||
png_set_expand(png);
|
||||
|
||||
/* allocate RImage */
|
||||
image = RCreateImage(width, height, alpha);
|
||||
if (!image) {
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
return NULL;
|
||||
}
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && depth <= 8)
|
||||
png_set_expand(png);
|
||||
|
||||
/* normalize to 8bpp with alpha channel */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE && depth <= 8)
|
||||
png_set_expand(png);
|
||||
if (png_get_valid(png, pinfo, PNG_INFO_tRNS))
|
||||
png_set_expand(png);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && depth <= 8)
|
||||
png_set_expand(png);
|
||||
if (depth == 16)
|
||||
png_set_strip_16(png);
|
||||
|
||||
if (png_get_valid(png, pinfo, PNG_INFO_tRNS))
|
||||
png_set_expand(png);
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
png_set_gray_to_rgb(png);
|
||||
|
||||
if (depth == 16)
|
||||
png_set_strip_16(png);
|
||||
/* set gamma correction */
|
||||
if ((context->attribs->flags & RC_GammaCorrection)
|
||||
&& context->depth != 8) {
|
||||
sgamma = (context->attribs->rgamma + context->attribs->ggamma + context->attribs->bgamma) / 3;
|
||||
} else if ((tmp = getenv("DISPLAY_GAMMA")) != NULL) {
|
||||
sgamma = atof(tmp);
|
||||
if (sgamma == 0)
|
||||
sgamma = 1;
|
||||
} else {
|
||||
/* blah */
|
||||
sgamma = 2.2;
|
||||
}
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
png_set_gray_to_rgb(png);
|
||||
if (png_get_gAMA(png, pinfo, &gamma))
|
||||
png_set_gamma(png, sgamma, gamma);
|
||||
else
|
||||
png_set_gamma(png, sgamma, 0.45);
|
||||
|
||||
/* set gamma correction */
|
||||
if ((context->attribs->flags & RC_GammaCorrection)
|
||||
&& context->depth != 8) {
|
||||
sgamma = (context->attribs->rgamma + context->attribs->ggamma +
|
||||
context->attribs->bgamma) / 3;
|
||||
} else if ((tmp = getenv("DISPLAY_GAMMA")) != NULL) {
|
||||
sgamma = atof(tmp);
|
||||
if (sgamma==0)
|
||||
sgamma = 1;
|
||||
} else {
|
||||
/* blah */
|
||||
sgamma = 2.2;
|
||||
}
|
||||
/* do the transforms */
|
||||
png_read_update_info(png, pinfo);
|
||||
|
||||
if (png_get_gAMA(png, pinfo, &gamma))
|
||||
png_set_gamma(png, sgamma, gamma);
|
||||
else
|
||||
png_set_gamma(png, sgamma, 0.45);
|
||||
/* set background color */
|
||||
if (png_get_bKGD(png, pinfo, &bkcolor)) {
|
||||
image->background.red = bkcolor->red >> 8;
|
||||
image->background.green = bkcolor->green >> 8;
|
||||
image->background.blue = bkcolor->blue >> 8;
|
||||
}
|
||||
|
||||
/* do the transforms */
|
||||
png_read_update_info(png, pinfo);
|
||||
|
||||
/* set background color */
|
||||
if (png_get_bKGD(png, pinfo, &bkcolor)) {
|
||||
image->background.red = bkcolor->red >> 8;
|
||||
image->background.green = bkcolor->green >> 8;
|
||||
image->background.blue = bkcolor->blue >> 8;
|
||||
}
|
||||
|
||||
png_rows = alloca(sizeof(char*)*height);
|
||||
if (!png_rows) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
RReleaseImage(image);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
png_rows = alloca(sizeof(char *) * height);
|
||||
if (!png_rows) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
RReleaseImage(image);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
alloca(0);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
for (y=0; y<height; y++) {
|
||||
png_rows[y] = alloca(png_get_rowbytes(png, pinfo));
|
||||
if (!png_rows[y]) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
RReleaseImage(image);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
return NULL;
|
||||
}
|
||||
for (y = 0; y < height; y++) {
|
||||
png_rows[y] = alloca(png_get_rowbytes(png, pinfo));
|
||||
if (!png_rows[y]) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
RReleaseImage(image);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
alloca(0);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* read data */
|
||||
png_read_image(png, png_rows);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* read data */
|
||||
png_read_image(png, png_rows);
|
||||
|
||||
png_read_end(png, einfo);
|
||||
png_read_end(png, einfo);
|
||||
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
|
||||
fclose(f);
|
||||
fclose(f);
|
||||
|
||||
ptr = image->data;
|
||||
ptr = image->data;
|
||||
|
||||
/* convert to RImage */
|
||||
if (alpha) {
|
||||
for (y=0; y<height; y++) {
|
||||
for (x=0, i=width*4; x<i; x++, ptr++) {
|
||||
*ptr = *(png_rows[y]+x);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (y=0; y<height; y++) {
|
||||
for (x=0, i=width*3; x<i; x++, ptr++) {
|
||||
*ptr = *(png_rows[y]+x);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* convert to RImage */
|
||||
if (alpha) {
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0, i = width * 4; x < i; x++, ptr++) {
|
||||
*ptr = *(png_rows[y] + x);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0, i = width * 3; x < i; x++, ptr++) {
|
||||
*ptr = *(png_rows[y] + x);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
alloca(0);
|
||||
#endif
|
||||
return image;
|
||||
return image;
|
||||
}
|
||||
|
||||
#endif /* USE_PNG */
|
||||
|
||||
#endif /* USE_PNG */
|
||||
|
||||
225
wrlib/ppm.c
225
wrlib/ppm.c
@@ -21,7 +21,6 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@@ -29,152 +28,144 @@
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
static RImage*
|
||||
load_graymap(char *file_name, FILE *file, int w, int h, int max, int raw)
|
||||
static RImage *load_graymap(char *file_name, FILE * file, int w, int h, int max, int raw)
|
||||
{
|
||||
RImage *image;
|
||||
RImage *image;
|
||||
|
||||
image = RCreateImage(w, h, 0);
|
||||
if (!image) {
|
||||
return NULL;
|
||||
}
|
||||
if (!raw) {
|
||||
image = RCreateImage(w, h, 0);
|
||||
if (!image) {
|
||||
return NULL;
|
||||
}
|
||||
if (!raw) {
|
||||
|
||||
} else {
|
||||
if (max<256) {
|
||||
unsigned char *ptr;
|
||||
char *buf;
|
||||
int x, y;
|
||||
} else {
|
||||
if (max < 256) {
|
||||
unsigned char *ptr;
|
||||
char *buf;
|
||||
int x, y;
|
||||
|
||||
buf = malloc(w+1);
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
buf = malloc(w + 1);
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = image->data;
|
||||
for (y = 0; y < h; y++) {
|
||||
if (!fread(buf, w, 1, file)) {
|
||||
free(buf);
|
||||
goto short_file;
|
||||
}
|
||||
for (x = 0; x < w; x++) {
|
||||
*(ptr++) = buf[x];
|
||||
*(ptr++) = buf[x];
|
||||
*(ptr++) = buf[x];
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
} else {
|
||||
ptr = image->data;
|
||||
for (y = 0; y < h; y++) {
|
||||
if (!fread(buf, w, 1, file)) {
|
||||
free(buf);
|
||||
goto short_file;
|
||||
}
|
||||
for (x = 0; x < w; x++) {
|
||||
*(ptr++) = buf[x];
|
||||
*(ptr++) = buf[x];
|
||||
*(ptr++) = buf[x];
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
return image;
|
||||
|
||||
short_file:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
return NULL;
|
||||
short_file:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static RImage*
|
||||
load_pixmap(char *file_name, FILE *file, int w, int h, int max, int raw)
|
||||
static RImage *load_pixmap(char *file_name, FILE * file, int w, int h, int max, int raw)
|
||||
{
|
||||
RImage *image;
|
||||
int i;
|
||||
char buf[3];
|
||||
unsigned char *ptr;
|
||||
RImage *image;
|
||||
int i;
|
||||
char buf[3];
|
||||
unsigned char *ptr;
|
||||
|
||||
image = RCreateImage(w, h, 0);
|
||||
if (!image) {
|
||||
return NULL;
|
||||
}
|
||||
ptr = image->data;
|
||||
if (!raw) {
|
||||
image = RCreateImage(w, h, 0);
|
||||
if (!image) {
|
||||
return NULL;
|
||||
}
|
||||
ptr = image->data;
|
||||
if (!raw) {
|
||||
|
||||
} else {
|
||||
if (max<256) {
|
||||
i = 0;
|
||||
while (i < w*h) {
|
||||
if (fread(buf, 1, 3, file)!=3)
|
||||
goto short_file;
|
||||
*(ptr++) = buf[0];
|
||||
*(ptr++) = buf[1];
|
||||
*(ptr++) = buf[2];
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
if (max < 256) {
|
||||
i = 0;
|
||||
while (i < w * h) {
|
||||
if (fread(buf, 1, 3, file) != 3)
|
||||
goto short_file;
|
||||
*(ptr++) = buf[0];
|
||||
*(ptr++) = buf[1];
|
||||
*(ptr++) = buf[2];
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
return image;
|
||||
|
||||
short_file:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
return NULL;
|
||||
short_file:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
RImage*
|
||||
RLoadPPM(RContext *context, char *file_name, int index)
|
||||
RImage *RLoadPPM(RContext * context, char *file_name, int index)
|
||||
{
|
||||
FILE *file;
|
||||
RImage *image = NULL;
|
||||
char buffer[256];
|
||||
int w, h, m;
|
||||
int type;
|
||||
FILE *file;
|
||||
RImage *image = NULL;
|
||||
char buffer[256];
|
||||
int w, h, m;
|
||||
int type;
|
||||
|
||||
#define GETL() if (!fgets(buffer, 255, file)) goto short_file
|
||||
|
||||
file = fopen(file_name, "rb");
|
||||
if (!file) {
|
||||
RErrorCode = RERR_OPEN;
|
||||
return NULL;
|
||||
}
|
||||
file = fopen(file_name, "rb");
|
||||
if (!file) {
|
||||
RErrorCode = RERR_OPEN;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get signature */
|
||||
GETL();
|
||||
/* get signature */
|
||||
GETL();
|
||||
|
||||
/* only accept raw pixmaps or graymaps */
|
||||
if (buffer[0] != 'P' || (buffer[1] != '5' && buffer[1] != '6')) {
|
||||
RErrorCode = RERR_BADFORMAT;
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
/* only accept raw pixmaps or graymaps */
|
||||
if (buffer[0] != 'P' || (buffer[1] != '5' && buffer[1] != '6')) {
|
||||
RErrorCode = RERR_BADFORMAT;
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type = buffer[1];
|
||||
type = buffer[1];
|
||||
|
||||
/* skip comments */
|
||||
while (1) {
|
||||
GETL();
|
||||
/* skip comments */
|
||||
while (1) {
|
||||
GETL();
|
||||
|
||||
if (buffer[0]!='#')
|
||||
break;
|
||||
}
|
||||
if (buffer[0] != '#')
|
||||
break;
|
||||
}
|
||||
|
||||
/* get size */
|
||||
if (sscanf(buffer, "%i %i", &w, &h)!=2 || w < 1 || h < 1)
|
||||
goto bad_file;
|
||||
/* get size */
|
||||
if (sscanf(buffer, "%i %i", &w, &h) != 2 || w < 1 || h < 1)
|
||||
goto bad_file;
|
||||
|
||||
GETL();
|
||||
if (sscanf(buffer, "%i", &m) != 1 || m < 1)
|
||||
goto bad_file;
|
||||
|
||||
GETL();
|
||||
if (sscanf(buffer, "%i", &m)!=1 || m < 1)
|
||||
goto bad_file;
|
||||
if (type == '5')
|
||||
image = load_graymap(file_name, file, w, h, m, type == '5');
|
||||
else if (type == '6')
|
||||
image = load_pixmap(file_name, file, w, h, m, type == '6');
|
||||
|
||||
if (type=='5')
|
||||
image = load_graymap(file_name, file, w, h, m, type=='5');
|
||||
else if (type=='6')
|
||||
image = load_pixmap(file_name, file, w, h, m, type=='6');
|
||||
fclose(file);
|
||||
return image;
|
||||
|
||||
fclose(file);
|
||||
return image;
|
||||
|
||||
bad_file:
|
||||
short_file:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
fclose(file);
|
||||
return NULL;
|
||||
bad_file:
|
||||
short_file:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
998
wrlib/raster.c
998
wrlib/raster.c
File diff suppressed because it is too large
Load Diff
530
wrlib/rotate.c
530
wrlib/rotate.c
@@ -33,159 +33,151 @@
|
||||
#define PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
static RImage *rotateImage(RImage * image, float angle);
|
||||
|
||||
static RImage *rotateImage(RImage *image, float angle);
|
||||
|
||||
|
||||
RImage*
|
||||
RRotateImage(RImage *image, float angle)
|
||||
RImage *RRotateImage(RImage * image, float angle)
|
||||
{
|
||||
RImage *img;
|
||||
int nwidth, nheight;
|
||||
int x, y;
|
||||
int bpp = image->format == RRGBAFormat ? 4 : 3;
|
||||
RImage *img;
|
||||
int nwidth, nheight;
|
||||
int x, y;
|
||||
int bpp = image->format == RRGBAFormat ? 4 : 3;
|
||||
|
||||
angle = ((int)angle % 360) + (angle - (int)angle);
|
||||
angle = ((int)angle % 360) + (angle - (int)angle);
|
||||
|
||||
if (angle == 0.0) {
|
||||
return RCloneImage(image);
|
||||
if (angle == 0.0) {
|
||||
return RCloneImage(image);
|
||||
|
||||
} else if (angle == 90.0) {
|
||||
nwidth = image->height;
|
||||
nheight = image->width;
|
||||
} else if (angle == 90.0) {
|
||||
nwidth = image->height;
|
||||
nheight = image->width;
|
||||
|
||||
img = RCreateImage(nwidth, nheight, True);
|
||||
if (!img) {
|
||||
return NULL;
|
||||
}
|
||||
img = RCreateImage(nwidth, nheight, True);
|
||||
if (!img) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bpp == 3) {
|
||||
unsigned char *optr, *nptr;
|
||||
unsigned offs;
|
||||
if (bpp == 3) {
|
||||
unsigned char *optr, *nptr;
|
||||
unsigned offs;
|
||||
|
||||
offs = nwidth * 4;
|
||||
|
||||
offs = nwidth * 4;
|
||||
optr = image->data;
|
||||
nptr = img->data;
|
||||
|
||||
optr = image->data;
|
||||
nptr = img->data;
|
||||
for (x = 0; x < nwidth; x++) {
|
||||
nptr = img->data + x * 4;
|
||||
for (y = nheight; y; y--) {
|
||||
nptr[0] = *optr++;
|
||||
nptr[1] = *optr++;
|
||||
nptr[2] = *optr++;
|
||||
nptr[3] = 255;
|
||||
|
||||
for (x = 0; x < nwidth; x++) {
|
||||
nptr = img->data + x*4;
|
||||
for (y = nheight; y; y--) {
|
||||
nptr[0] = *optr++;
|
||||
nptr[1] = *optr++;
|
||||
nptr[2] = *optr++;
|
||||
nptr[3] = 255;
|
||||
nptr += offs;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsigned *optr, *nptr;
|
||||
unsigned *p;
|
||||
|
||||
nptr += offs;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsigned *optr, *nptr;
|
||||
unsigned *p;
|
||||
optr = (unsigned *)image->data;
|
||||
p = (unsigned *)img->data;
|
||||
for (x = 0; x < nwidth; x++) {
|
||||
nptr = p++;
|
||||
for (y = nheight; y; y--) {
|
||||
*nptr = *optr++;
|
||||
nptr += nwidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (angle == 180.0) {
|
||||
|
||||
optr = (unsigned*)image->data;
|
||||
p = (unsigned*)img->data;
|
||||
for (x = 0; x < nwidth; x++) {
|
||||
nptr = p++;
|
||||
for (y = nheight; y; y--) {
|
||||
*nptr = *optr++;
|
||||
nptr += nwidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (angle == 180.0) {
|
||||
nwidth = image->width;
|
||||
nheight = image->height;
|
||||
img = RCreateImage(nwidth, nheight, True);
|
||||
if (!img) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nwidth = image->width;
|
||||
nheight = image->height;
|
||||
img = RCreateImage(nwidth, nheight, True);
|
||||
if (!img) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpp == 3) {
|
||||
unsigned char *optr, *nptr;
|
||||
|
||||
if (bpp == 3) {
|
||||
unsigned char *optr, *nptr;
|
||||
optr = image->data;
|
||||
nptr = img->data + nwidth * nheight * 4 - 4;
|
||||
|
||||
optr = image->data;
|
||||
nptr = img->data + nwidth * nheight * 4 - 4;
|
||||
for (y = 0; y < nheight; y++) {
|
||||
for (x = 0; x < nwidth; x++) {
|
||||
nptr[0] = optr[0];
|
||||
nptr[1] = optr[1];
|
||||
nptr[2] = optr[2];
|
||||
nptr[3] = 255;
|
||||
|
||||
for (y = 0; y < nheight; y++) {
|
||||
for (x = 0; x < nwidth; x++) {
|
||||
nptr[0] = optr[0];
|
||||
nptr[1] = optr[1];
|
||||
nptr[2] = optr[2];
|
||||
nptr[3] = 255;
|
||||
optr += 3;
|
||||
nptr -= 4;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsigned *optr, *nptr;
|
||||
|
||||
optr += 3;
|
||||
nptr -= 4;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsigned *optr, *nptr;
|
||||
optr = (unsigned *)image->data;
|
||||
nptr = (unsigned *)img->data + nwidth * nheight - 1;
|
||||
|
||||
optr = (unsigned*)image->data;
|
||||
nptr = (unsigned*)img->data + nwidth * nheight - 1;
|
||||
for (y = nheight * nwidth - 1; y >= 0; y--) {
|
||||
*nptr = *optr;
|
||||
optr++;
|
||||
nptr--;
|
||||
}
|
||||
}
|
||||
} else if (angle == 270.0) {
|
||||
nwidth = image->height;
|
||||
nheight = image->width;
|
||||
|
||||
for (y = nheight*nwidth-1; y >= 0; y--) {
|
||||
*nptr = *optr;
|
||||
optr++;
|
||||
nptr--;
|
||||
}
|
||||
}
|
||||
} else if (angle == 270.0) {
|
||||
nwidth = image->height;
|
||||
nheight = image->width;
|
||||
img = RCreateImage(nwidth, nheight, True);
|
||||
if (!img) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
img = RCreateImage(nwidth, nheight, True);
|
||||
if (!img) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpp == 3) {
|
||||
unsigned char *optr, *nptr;
|
||||
unsigned offs;
|
||||
|
||||
if (bpp == 3) {
|
||||
unsigned char *optr, *nptr;
|
||||
unsigned offs;
|
||||
offs = nwidth * 4;
|
||||
|
||||
optr = image->data;
|
||||
nptr = img->data;
|
||||
|
||||
offs = nwidth * 4;
|
||||
for (x = 0; x < nwidth; x++) {
|
||||
nptr = img->data + x * 4;
|
||||
for (y = nheight; y; y--) {
|
||||
nptr[0] = *optr++;
|
||||
nptr[1] = *optr++;
|
||||
nptr[2] = *optr++;
|
||||
nptr[3] = 255;
|
||||
|
||||
optr = image->data;
|
||||
nptr = img->data;
|
||||
nptr += offs;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsigned *optr, *nptr;
|
||||
unsigned *p;
|
||||
|
||||
for (x = 0; x < nwidth; x++) {
|
||||
nptr = img->data + x*4;
|
||||
for (y = nheight; y; y--) {
|
||||
nptr[0] = *optr++;
|
||||
nptr[1] = *optr++;
|
||||
nptr[2] = *optr++;
|
||||
nptr[3] = 255;
|
||||
optr = (unsigned *)image->data;
|
||||
p = (unsigned *)img->data + nwidth * nheight;
|
||||
for (x = 0; x < nwidth; x++) {
|
||||
nptr = p--;
|
||||
for (y = nheight; y; y--) {
|
||||
*nptr = *optr++;
|
||||
nptr -= nwidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
img = rotateImage(image, angle);
|
||||
}
|
||||
|
||||
nptr += offs;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsigned *optr, *nptr;
|
||||
unsigned *p;
|
||||
|
||||
optr = (unsigned*)image->data;
|
||||
p = (unsigned*)img->data + nwidth*nheight;
|
||||
for (x = 0; x < nwidth; x++) {
|
||||
nptr = p--;
|
||||
for (y = nheight; y; y--) {
|
||||
*nptr = *optr++;
|
||||
nptr -= nwidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
img = rotateImage(image, angle);
|
||||
}
|
||||
|
||||
return img;
|
||||
return img;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Image rotation through Bresenham's line algorithm:
|
||||
*
|
||||
@@ -207,183 +199,187 @@ RRotateImage(RImage *image, float angle)
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
static void
|
||||
copyLine(int x1, int y1, int x2, int y2, int nwidth, int format,
|
||||
unsigned char *dst, unsigned char **src)
|
||||
copyLine(int x1, int y1, int x2, int y2, int nwidth, int format, unsigned char *dst, unsigned char **src)
|
||||
{
|
||||
unsigned char *s = *src;
|
||||
int dx, dy;
|
||||
int xi, yi;
|
||||
int offset;
|
||||
int dpr, dpru, p;
|
||||
unsigned char *s = *src;
|
||||
int dx, dy;
|
||||
int xi, yi;
|
||||
int offset;
|
||||
int dpr, dpru, p;
|
||||
|
||||
dx = abs(x2 - x1);
|
||||
dy = abs(y2 - y1);
|
||||
dx = abs(x2 - x1);
|
||||
dy = abs(y2 - y1);
|
||||
|
||||
if (x1 > x2) xi = -1; else xi = 1;
|
||||
if (y1 > y2) yi = -1; else yi = 1;
|
||||
if (x1 > x2)
|
||||
xi = -1;
|
||||
else
|
||||
xi = 1;
|
||||
if (y1 > y2)
|
||||
yi = -1;
|
||||
else
|
||||
yi = 1;
|
||||
|
||||
if (dx >= dy) {
|
||||
if (dx >= dy) {
|
||||
|
||||
dpr = dy << 1;
|
||||
dpru = dpr - (dx << 1);
|
||||
p = dpr - dx;
|
||||
dpr = dy << 1;
|
||||
dpru = dpr - (dx << 1);
|
||||
p = dpr - dx;
|
||||
|
||||
while (dx-- >= 0) {
|
||||
/* fetch and draw the pixel */
|
||||
offset = (x1 + y1 * nwidth) << 2;
|
||||
dst[offset++] = *s++;
|
||||
dst[offset++] = *s++;
|
||||
dst[offset++] = *s++;
|
||||
if (format == RRGBAFormat)
|
||||
dst[offset++] = *s++;
|
||||
else
|
||||
dst[offset++] = 255;
|
||||
while (dx-- >= 0) {
|
||||
/* fetch and draw the pixel */
|
||||
offset = (x1 + y1 * nwidth) << 2;
|
||||
dst[offset++] = *s++;
|
||||
dst[offset++] = *s++;
|
||||
dst[offset++] = *s++;
|
||||
if (format == RRGBAFormat)
|
||||
dst[offset++] = *s++;
|
||||
else
|
||||
dst[offset++] = 255;
|
||||
|
||||
/* calc next step */
|
||||
if (p > 0) {
|
||||
x1 += xi;
|
||||
y1 += yi;
|
||||
p += dpru;
|
||||
} else {
|
||||
x1 += xi;
|
||||
p += dpr;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* calc next step */
|
||||
if (p > 0) {
|
||||
x1 += xi;
|
||||
y1 += yi;
|
||||
p += dpru;
|
||||
} else {
|
||||
x1 += xi;
|
||||
p += dpr;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
dpr = dx << 1;
|
||||
dpru = dpr - (dy << 1);
|
||||
p = dpr - dy;
|
||||
dpr = dx << 1;
|
||||
dpru = dpr - (dy << 1);
|
||||
p = dpr - dy;
|
||||
|
||||
while (dy-- >= 0) {
|
||||
/* fetch and draw the pixel */
|
||||
offset = (x1 + y1 * nwidth) << 2;
|
||||
dst[offset++] = *s++;
|
||||
dst[offset++] = *s++;
|
||||
dst[offset++] = *s++;
|
||||
if (format == RRGBAFormat)
|
||||
dst[offset++] = *s++;
|
||||
else
|
||||
dst[offset++] = 255;
|
||||
while (dy-- >= 0) {
|
||||
/* fetch and draw the pixel */
|
||||
offset = (x1 + y1 * nwidth) << 2;
|
||||
dst[offset++] = *s++;
|
||||
dst[offset++] = *s++;
|
||||
dst[offset++] = *s++;
|
||||
if (format == RRGBAFormat)
|
||||
dst[offset++] = *s++;
|
||||
else
|
||||
dst[offset++] = 255;
|
||||
|
||||
/* calc next step */
|
||||
if (p > 0) {
|
||||
x1 += xi;
|
||||
y1 += yi;
|
||||
p += dpru;
|
||||
} else {
|
||||
y1 += yi;
|
||||
p += dpr;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* calc next step */
|
||||
if (p > 0) {
|
||||
x1 += xi;
|
||||
y1 += yi;
|
||||
p += dpru;
|
||||
} else {
|
||||
y1 += yi;
|
||||
p += dpr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*src = s;
|
||||
*src = s;
|
||||
}
|
||||
|
||||
|
||||
static RImage*
|
||||
rotateImage(RImage *image, float angle)
|
||||
static RImage *rotateImage(RImage * image, float angle)
|
||||
{
|
||||
RImage *img;
|
||||
int nwidth, nheight;
|
||||
int x1, y1;
|
||||
int x2, y2;
|
||||
int dx, dy;
|
||||
int xi, yi;
|
||||
int xx, yy;
|
||||
unsigned char *src, *dst;
|
||||
int dpr, dpru, p;
|
||||
RImage *img;
|
||||
int nwidth, nheight;
|
||||
int x1, y1;
|
||||
int x2, y2;
|
||||
int dx, dy;
|
||||
int xi, yi;
|
||||
int xx, yy;
|
||||
unsigned char *src, *dst;
|
||||
int dpr, dpru, p;
|
||||
|
||||
/* only 180o for now */
|
||||
if (angle > 180.0)
|
||||
angle -= 180.0;
|
||||
/* only 180o for now */
|
||||
if (angle > 180.0)
|
||||
angle -= 180.0;
|
||||
|
||||
angle = (angle * PI) / 180.0;
|
||||
|
||||
angle = (angle * PI) / 180.0;
|
||||
nwidth = ceil(abs(cos(angle) * image->width))
|
||||
+ ceil(abs(cos(PI / 2 - angle) * image->width));
|
||||
|
||||
nwidth = ceil(abs(cos(angle) * image->width))
|
||||
+ ceil(abs(cos(PI/2 - angle) * image->width));
|
||||
nheight = ceil(abs(sin(angle) * image->height))
|
||||
+ ceil(abs(cos(PI / 2 - angle) * image->height));
|
||||
|
||||
nheight = ceil(abs(sin(angle) * image->height))
|
||||
+ ceil(abs(cos(PI/2 - angle) * image->height));
|
||||
img = RCreateImage(nwidth, nheight, True);
|
||||
if (!img)
|
||||
return NULL;
|
||||
|
||||
img = RCreateImage(nwidth, nheight, True);
|
||||
if (!img)
|
||||
return NULL;
|
||||
src = image->data;
|
||||
dst = img->data;
|
||||
|
||||
src = image->data;
|
||||
dst = img->data;
|
||||
x1 = floor(abs(cos(PI / 2 - angle) * image->width));
|
||||
y1 = 0;
|
||||
|
||||
x1 = floor(abs(cos(PI/2 - angle)*image->width));
|
||||
y1 = 0;
|
||||
x2 = 0;
|
||||
y2 = floor(abs(sin(PI / 2 - angle) * image->width));
|
||||
|
||||
x2 = 0;
|
||||
y2 = floor(abs(sin(PI/2 - angle)*image->width));
|
||||
xx = floor(abs(cos(angle) * image->height)) - 1;
|
||||
yy = nheight - 1;
|
||||
|
||||
xx = floor(abs(cos(angle)*image->height)) - 1;
|
||||
yy = nheight - 1;
|
||||
printf("%ix%i, %i %i %i %i %i\n", nwidth, nheight, x1, y1, x2, y2, (int)((angle * 180.0) / PI));
|
||||
|
||||
printf("%ix%i, %i %i %i %i %i\n",
|
||||
nwidth, nheight, x1, y1, x2, y2, (int)((angle*180.0)/PI));
|
||||
dx = abs(x2 - x1);
|
||||
dy = abs(y2 - y1);
|
||||
|
||||
dx = abs(x2 - x1);
|
||||
dy = abs(y2 - y1);
|
||||
if (x1 > x2)
|
||||
xi = -1;
|
||||
else
|
||||
xi = 1;
|
||||
if (y1 > y2)
|
||||
yi = -1;
|
||||
else
|
||||
yi = 1;
|
||||
|
||||
if (x1 > x2) xi = -1; else xi = 1;
|
||||
if (y1 > y2) yi = -1; else yi = 1;
|
||||
if (dx >= dy) {
|
||||
dpr = dy << 1;
|
||||
dpru = dpr - (dx << 1);
|
||||
p = dpr - dx;
|
||||
|
||||
if (dx >= dy) {
|
||||
dpr = dy << 1;
|
||||
dpru = dpr - (dx << 1);
|
||||
p = dpr - dx;
|
||||
while (dx-- >= 0) {
|
||||
|
||||
while (dx-- >= 0) {
|
||||
copyLine(x1, y1, xx, yy, nwidth, image->format, dst, &src);
|
||||
|
||||
copyLine(x1, y1, xx, yy, nwidth, image->format, dst, &src);
|
||||
/* calc next step */
|
||||
|
||||
/* calc next step */
|
||||
if (p > 0) {
|
||||
x1 += xi;
|
||||
y1 += yi;
|
||||
xx += xi;
|
||||
yy += yi;
|
||||
p += dpru;
|
||||
} else {
|
||||
x1 += xi;
|
||||
xx += xi;
|
||||
p += dpr;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
puts("NOT IMPLEMTENED");
|
||||
return img;
|
||||
dpr = dx << 1;
|
||||
dpru = dpr - (dy << 1);
|
||||
p = dpr - dy;
|
||||
|
||||
if (p > 0) {
|
||||
x1 += xi;
|
||||
y1 += yi;
|
||||
xx += xi;
|
||||
yy += yi;
|
||||
p += dpru;
|
||||
} else {
|
||||
x1 += xi;
|
||||
xx += xi;
|
||||
p += dpr;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
puts("NOT IMPLEMTENED");
|
||||
return img;
|
||||
dpr = dx << 1;
|
||||
dpru = dpr - (dy << 1);
|
||||
p = dpr - dy;
|
||||
while (dy-- >= 0) {
|
||||
xx = abs(x1 * sin(angle * PI / 180.0));
|
||||
yy = abs(y1 * cos(angle * PI / 180.0));
|
||||
|
||||
while (dy-- >= 0) {
|
||||
xx = abs(x1*sin(angle*PI/180.0));
|
||||
yy = abs(y1*cos(angle*PI/180.0));
|
||||
copyLine(x1, y1, xx, yy, nwidth, image->format, dst, &src);
|
||||
|
||||
copyLine(x1, y1, xx, yy, nwidth, image->format, dst, &src);
|
||||
/* calc next step */
|
||||
if (p > 0) {
|
||||
x1 += xi;
|
||||
y1 += yi;
|
||||
p += dpru;
|
||||
} else {
|
||||
y1 += yi;
|
||||
p += dpr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* calc next step*/
|
||||
if (p > 0) {
|
||||
x1 += xi;
|
||||
y1 += yi;
|
||||
p += dpru;
|
||||
} else {
|
||||
y1 += yi;
|
||||
p += dpr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return img;
|
||||
return img;
|
||||
}
|
||||
|
||||
|
||||
19
wrlib/save.c
19
wrlib/save.c
@@ -30,20 +30,15 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
extern Bool RSaveXPM(RImage * image, char *filename);
|
||||
|
||||
extern Bool RSaveXPM(RImage *image, char *filename);
|
||||
|
||||
|
||||
Bool
|
||||
RSaveImage(RImage *image, char *filename, char *format)
|
||||
Bool RSaveImage(RImage * image, char *filename, char *format)
|
||||
{
|
||||
if (strcmp(format, "XPM")!=0) {
|
||||
RErrorCode = RERR_BADFORMAT;
|
||||
return False;
|
||||
}
|
||||
return RSaveXPM(image, filename);
|
||||
if (strcmp(format, "XPM") != 0) {
|
||||
RErrorCode = RERR_BADFORMAT;
|
||||
return False;
|
||||
}
|
||||
return RSaveXPM(image, filename);
|
||||
}
|
||||
|
||||
|
||||
845
wrlib/scale.c
845
wrlib/scale.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,4 @@
|
||||
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include "wraster.h"
|
||||
#include <stdio.h>
|
||||
@@ -10,7 +9,6 @@
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
|
||||
Display *dpy;
|
||||
Window win;
|
||||
RContext *ctx;
|
||||
@@ -18,16 +16,14 @@ RImage *imgh, *imgv, *imgd;
|
||||
Pixmap pix;
|
||||
char *ProgName;
|
||||
|
||||
|
||||
void
|
||||
print_help()
|
||||
void print_help()
|
||||
{
|
||||
printf("usage: %s [-options] color1 [color2 ...]\n", ProgName);
|
||||
puts("options:");
|
||||
puts(" -m match colors");
|
||||
puts(" -d dither colors (default)");
|
||||
puts(" -c <cpc> colors per channel to use");
|
||||
puts(" -v <vis-id> visual id to use");
|
||||
printf("usage: %s [-options] color1 [color2 ...]\n", ProgName);
|
||||
puts("options:");
|
||||
puts(" -m match colors");
|
||||
puts(" -d dither colors (default)");
|
||||
puts(" -c <cpc> colors per channel to use");
|
||||
puts(" -v <vis-id> visual id to use");
|
||||
}
|
||||
|
||||
#ifdef BENCH
|
||||
@@ -35,179 +31,175 @@ print_help()
|
||||
#endif
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
RContextAttributes attr;
|
||||
RColor **colors = NULL;
|
||||
int i, rmode = RDitheredRendering, ncolors = 0, cpc = 4;
|
||||
char **color_name;
|
||||
XColor color;
|
||||
XSetWindowAttributes val;
|
||||
int visualID = -1;
|
||||
RContextAttributes attr;
|
||||
RColor **colors = NULL;
|
||||
int i, rmode = RDitheredRendering, ncolors = 0, cpc = 4;
|
||||
char **color_name;
|
||||
XColor color;
|
||||
XSetWindowAttributes val;
|
||||
int visualID = -1;
|
||||
#ifdef BENCH
|
||||
double t1, t2, total, t, rt;
|
||||
struct timeval timev;
|
||||
double t1, t2, total, t, rt;
|
||||
struct timeval timev;
|
||||
#endif
|
||||
|
||||
ProgName = strrchr(argv[0],'/');
|
||||
if (!ProgName)
|
||||
ProgName = argv[0];
|
||||
else
|
||||
ProgName++;
|
||||
ProgName = strrchr(argv[0], '/');
|
||||
if (!ProgName)
|
||||
ProgName = argv[0];
|
||||
else
|
||||
ProgName++;
|
||||
|
||||
color_name = (char **) malloc(sizeof(char*) * argc);
|
||||
if(color_name == NULL) {
|
||||
fprintf(stderr, "Cannot allocate memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
color_name = (char **)malloc(sizeof(char *) * argc);
|
||||
if (color_name == NULL) {
|
||||
fprintf(stderr, "Cannot allocate memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (argc>1) {
|
||||
for (i=1; i<argc; i++) {
|
||||
if (strcmp(argv[i], "-m")==0) {
|
||||
rmode = RBestMatchRendering;
|
||||
} else if (strcmp(argv[i], "-d")==0) {
|
||||
rmode = RDitheredRendering;
|
||||
} else if (strcmp(argv[i], "-c")==0) {
|
||||
i++;
|
||||
if (i>=argc) {
|
||||
fprintf(stderr, "too few arguments for %s\n", argv[i-1]);
|
||||
exit(0);
|
||||
}
|
||||
if (sscanf(argv[i], "%i", &cpc)!=1) {
|
||||
fprintf(stderr, "bad value for colors per channel: \"%s\"\n", argv[i]);
|
||||
exit(0);
|
||||
}
|
||||
} else if (strcmp(argv[i], "-v")==0) {
|
||||
i++;
|
||||
if (i>=argc) {
|
||||
fprintf(stderr, "too few arguments for %s\n", argv[i-1]);
|
||||
exit(0);
|
||||
}
|
||||
if (sscanf(argv[i], "%i", &visualID)!=1) {
|
||||
fprintf(stderr, "bad value for visual ID: \"%s\"\n", argv[i]);
|
||||
exit(0);
|
||||
}
|
||||
} else if (argv[i][0] != '-') {
|
||||
color_name[ncolors++] = argv[i];
|
||||
} else {
|
||||
print_help();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (argc > 1) {
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-m") == 0) {
|
||||
rmode = RBestMatchRendering;
|
||||
} else if (strcmp(argv[i], "-d") == 0) {
|
||||
rmode = RDitheredRendering;
|
||||
} else if (strcmp(argv[i], "-c") == 0) {
|
||||
i++;
|
||||
if (i >= argc) {
|
||||
fprintf(stderr, "too few arguments for %s\n", argv[i - 1]);
|
||||
exit(0);
|
||||
}
|
||||
if (sscanf(argv[i], "%i", &cpc) != 1) {
|
||||
fprintf(stderr, "bad value for colors per channel: \"%s\"\n", argv[i]);
|
||||
exit(0);
|
||||
}
|
||||
} else if (strcmp(argv[i], "-v") == 0) {
|
||||
i++;
|
||||
if (i >= argc) {
|
||||
fprintf(stderr, "too few arguments for %s\n", argv[i - 1]);
|
||||
exit(0);
|
||||
}
|
||||
if (sscanf(argv[i], "%i", &visualID) != 1) {
|
||||
fprintf(stderr, "bad value for visual ID: \"%s\"\n", argv[i]);
|
||||
exit(0);
|
||||
}
|
||||
} else if (argv[i][0] != '-') {
|
||||
color_name[ncolors++] = argv[i];
|
||||
} else {
|
||||
print_help();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ncolors == 0) {
|
||||
print_help();
|
||||
exit(1);
|
||||
}
|
||||
if (ncolors == 0) {
|
||||
print_help();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
dpy = XOpenDisplay("");
|
||||
if (!dpy) {
|
||||
puts("cant open display");
|
||||
exit(1);
|
||||
}
|
||||
attr.flags = RC_RenderMode | RC_ColorsPerChannel;
|
||||
dpy = XOpenDisplay("");
|
||||
if (!dpy) {
|
||||
puts("cant open display");
|
||||
exit(1);
|
||||
}
|
||||
attr.flags = RC_RenderMode | RC_ColorsPerChannel;
|
||||
|
||||
attr.render_mode = rmode;
|
||||
attr.colors_per_channel = cpc;
|
||||
attr.render_mode = rmode;
|
||||
attr.colors_per_channel = cpc;
|
||||
|
||||
if (visualID >= 0) {
|
||||
attr.flags |= RC_VisualID;
|
||||
attr.visualid = visualID;
|
||||
}
|
||||
if (visualID >= 0) {
|
||||
attr.flags |= RC_VisualID;
|
||||
attr.visualid = visualID;
|
||||
}
|
||||
|
||||
ctx = RCreateContext(dpy, DefaultScreen(dpy), &attr);
|
||||
ctx = RCreateContext(dpy, DefaultScreen(dpy), &attr);
|
||||
|
||||
if (!ctx) {
|
||||
printf("could not initialize graphics library context: %s\n",
|
||||
RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
if (!ctx) {
|
||||
printf("could not initialize graphics library context: %s\n", RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
colors = malloc(sizeof(RColor*)*(ncolors+1));
|
||||
for (i=0; i<ncolors; i++) {
|
||||
if (!XParseColor(dpy, ctx->cmap, color_name[i], &color)) {
|
||||
printf("could not parse color \"%s\"\n", color_name[i]);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
colors[i] = malloc(sizeof(RColor));
|
||||
colors[i]->red = color.red >> 8;
|
||||
colors[i]->green = color.green >> 8;
|
||||
colors[i]->blue = color.blue >> 8;
|
||||
printf("0x%02x%02x%02x\n", colors[i]->red, colors[i]->green,
|
||||
colors[i]->blue);
|
||||
}
|
||||
}
|
||||
colors[i] = NULL;
|
||||
colors = malloc(sizeof(RColor *) * (ncolors + 1));
|
||||
for (i = 0; i < ncolors; i++) {
|
||||
if (!XParseColor(dpy, ctx->cmap, color_name[i], &color)) {
|
||||
printf("could not parse color \"%s\"\n", color_name[i]);
|
||||
exit(1);
|
||||
} else {
|
||||
colors[i] = malloc(sizeof(RColor));
|
||||
colors[i]->red = color.red >> 8;
|
||||
colors[i]->green = color.green >> 8;
|
||||
colors[i]->blue = color.blue >> 8;
|
||||
printf("0x%02x%02x%02x\n", colors[i]->red, colors[i]->green, colors[i]->blue);
|
||||
}
|
||||
}
|
||||
colors[i] = NULL;
|
||||
|
||||
val.background_pixel = ctx->black;
|
||||
val.colormap = ctx->cmap;
|
||||
val.backing_store = Always;
|
||||
val.background_pixel = ctx->black;
|
||||
val.colormap = ctx->cmap;
|
||||
val.backing_store = Always;
|
||||
#ifdef BENCH
|
||||
win = XCreateWindow(dpy, DefaultRootWindow(dpy), 10, 10, 250, 250,
|
||||
0, ctx->depth, InputOutput, ctx->visual,
|
||||
CWColormap|CWBackPixel|CWBackingStore, &val);
|
||||
win = XCreateWindow(dpy, DefaultRootWindow(dpy), 10, 10, 250, 250,
|
||||
0, ctx->depth, InputOutput, ctx->visual,
|
||||
CWColormap | CWBackPixel | CWBackingStore, &val);
|
||||
#else
|
||||
win = XCreateWindow(dpy, DefaultRootWindow(dpy), 10, 10, 750, 250,
|
||||
0, ctx->depth, InputOutput, ctx->visual,
|
||||
CWColormap|CWBackPixel|CWBackingStore, &val);
|
||||
win = XCreateWindow(dpy, DefaultRootWindow(dpy), 10, 10, 750, 250,
|
||||
0, ctx->depth, InputOutput, ctx->visual,
|
||||
CWColormap | CWBackPixel | CWBackingStore, &val);
|
||||
#endif
|
||||
XMapRaised(dpy, win);
|
||||
XFlush(dpy);
|
||||
XMapRaised(dpy, win);
|
||||
XFlush(dpy);
|
||||
|
||||
#ifdef BENCH
|
||||
rt = 0;
|
||||
gettimeofday(&timev, NULL);
|
||||
t = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
for (i=0; i<9; i++) {
|
||||
if (i>0)
|
||||
printf("\nrepeating...\n\n");
|
||||
gettimeofday(&timev, NULL);
|
||||
t1 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
if (i%3==0)
|
||||
imgh = RRenderMultiGradient(550, 550, colors, RGRD_HORIZONTAL);
|
||||
else if (i%3==1)
|
||||
imgh = RRenderMultiGradient(550, 550, colors, RGRD_VERTICAL);
|
||||
else
|
||||
imgh = RRenderMultiGradient(550, 550, colors, RGRD_DIAGONAL);
|
||||
rt = 0;
|
||||
gettimeofday(&timev, NULL);
|
||||
t = (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
|
||||
for (i = 0; i < 9; i++) {
|
||||
if (i > 0)
|
||||
printf("\nrepeating...\n\n");
|
||||
gettimeofday(&timev, NULL);
|
||||
t1 = (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
|
||||
if (i % 3 == 0)
|
||||
imgh = RRenderMultiGradient(550, 550, colors, RGRD_HORIZONTAL);
|
||||
else if (i % 3 == 1)
|
||||
imgh = RRenderMultiGradient(550, 550, colors, RGRD_VERTICAL);
|
||||
else
|
||||
imgh = RRenderMultiGradient(550, 550, colors, RGRD_DIAGONAL);
|
||||
|
||||
gettimeofday(&timev, NULL);
|
||||
t2 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
total = t2 - t1;
|
||||
printf("gradient rendered in %f sec\n", total);
|
||||
gettimeofday(&timev, NULL);
|
||||
t2 = (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
|
||||
total = t2 - t1;
|
||||
printf("gradient rendered in %f sec\n", total);
|
||||
|
||||
RConvertImage(ctx, imgh, &pix);
|
||||
gettimeofday(&timev, NULL);
|
||||
t1 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
total = t1 - t2;
|
||||
rt += total;
|
||||
printf("image converted in %f sec\n", total);
|
||||
RConvertImage(ctx, imgh, &pix);
|
||||
gettimeofday(&timev, NULL);
|
||||
t1 = (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
|
||||
total = t1 - t2;
|
||||
rt += total;
|
||||
printf("image converted in %f sec\n", total);
|
||||
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 0, 0);
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 0, 0);
|
||||
|
||||
XFlush(dpy);
|
||||
}
|
||||
t1 = (double)timev.tv_sec + (((double)timev.tv_usec)/1000000);
|
||||
printf("------------------------------------------\n");
|
||||
printf("%i images processed in %f sec\n", i, t1-t);
|
||||
printf("average time per convertion %f sec\n", rt/i);
|
||||
printf("------------------------------------------\n");
|
||||
XFlush(dpy);
|
||||
}
|
||||
t1 = (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
|
||||
printf("------------------------------------------\n");
|
||||
printf("%i images processed in %f sec\n", i, t1 - t);
|
||||
printf("average time per convertion %f sec\n", rt / i);
|
||||
printf("------------------------------------------\n");
|
||||
#else
|
||||
imgh = RRenderMultiGradient(250, 250, colors, RGRD_HORIZONTAL);
|
||||
imgv = RRenderMultiGradient(250, 250, colors, RGRD_VERTICAL);
|
||||
imgd = RRenderMultiGradient(250, 250, colors, RGRD_DIAGONAL);
|
||||
RConvertImage(ctx, imgh, &pix);
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 0, 0);
|
||||
imgh = RRenderMultiGradient(250, 250, colors, RGRD_HORIZONTAL);
|
||||
imgv = RRenderMultiGradient(250, 250, colors, RGRD_VERTICAL);
|
||||
imgd = RRenderMultiGradient(250, 250, colors, RGRD_DIAGONAL);
|
||||
RConvertImage(ctx, imgh, &pix);
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 0, 0);
|
||||
|
||||
RConvertImage(ctx, imgv, &pix);
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 250, 0);
|
||||
RConvertImage(ctx, imgv, &pix);
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 250, 0);
|
||||
|
||||
RConvertImage(ctx, imgd, &pix);
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 500, 0);
|
||||
RConvertImage(ctx, imgd, &pix);
|
||||
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 500, 0);
|
||||
|
||||
XFlush(dpy);
|
||||
XFlush(dpy);
|
||||
#endif
|
||||
|
||||
getchar();
|
||||
return 0;
|
||||
getchar();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include "wraster.h"
|
||||
#include <stdlib.h>
|
||||
@@ -12,59 +11,56 @@ RContext *ctx;
|
||||
RImage *img;
|
||||
Pixmap pix;
|
||||
|
||||
|
||||
#define MAX(a,b) (a)>(b) ? (a) : (b)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
RContextAttributes attr;
|
||||
float a;
|
||||
RContextAttributes attr;
|
||||
float a;
|
||||
|
||||
dpy = XOpenDisplay("");
|
||||
if (!dpy) {
|
||||
puts("cant open display");
|
||||
exit(1);
|
||||
}
|
||||
dpy = XOpenDisplay("");
|
||||
if (!dpy) {
|
||||
puts("cant open display");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
attr.flags = RC_RenderMode | RC_ColorsPerChannel;
|
||||
attr.render_mode = RDitheredRendering;
|
||||
attr.colors_per_channel = 4;
|
||||
ctx = RCreateContext(dpy, DefaultScreen(dpy), &attr);
|
||||
attr.flags = RC_RenderMode | RC_ColorsPerChannel;
|
||||
attr.render_mode = RDitheredRendering;
|
||||
attr.colors_per_channel = 4;
|
||||
ctx = RCreateContext(dpy, DefaultScreen(dpy), &attr);
|
||||
|
||||
if (argc<2)
|
||||
img = RGetImageFromXPMData(ctx, image_name);
|
||||
else
|
||||
img = RLoadImage(ctx, argv[1], 0);
|
||||
if (argc < 2)
|
||||
img = RGetImageFromXPMData(ctx, image_name);
|
||||
else
|
||||
img = RLoadImage(ctx, argv[1], 0);
|
||||
|
||||
if (!img) {
|
||||
puts(RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 10, 10,
|
||||
MAX(img->width, img->height),
|
||||
MAX(img->height, img->width), 0, 0, 0);
|
||||
XMapRaised(dpy, win);
|
||||
XFlush(dpy);
|
||||
if (!img) {
|
||||
puts(RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 10, 10,
|
||||
MAX(img->width, img->height), MAX(img->height, img->width), 0, 0, 0);
|
||||
XMapRaised(dpy, win);
|
||||
XFlush(dpy);
|
||||
|
||||
a = 0;
|
||||
while (1) {
|
||||
RImage *tmp;
|
||||
a = 0;
|
||||
while (1) {
|
||||
RImage *tmp;
|
||||
|
||||
a = a + 1.0;
|
||||
a = a + 1.0;
|
||||
|
||||
tmp = RRotateImage(img, a);
|
||||
if (!RConvertImage(ctx, tmp, &pix)) {
|
||||
puts(RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
RReleaseImage(tmp);
|
||||
tmp = RRotateImage(img, a);
|
||||
if (!RConvertImage(ctx, tmp, &pix)) {
|
||||
puts(RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
RReleaseImage(tmp);
|
||||
|
||||
XSetWindowBackgroundPixmap(dpy, win, pix);
|
||||
XFreePixmap(dpy, pix);
|
||||
XClearWindow(dpy, win);
|
||||
XSync(dpy, 0);
|
||||
usleep(50000);
|
||||
}
|
||||
exit(0);
|
||||
XSetWindowBackgroundPixmap(dpy, win, pix);
|
||||
XFreePixmap(dpy, pix);
|
||||
XClearWindow(dpy, win);
|
||||
XSync(dpy, 0);
|
||||
usleep(50000);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,85 +9,75 @@ RContext *ctx;
|
||||
RImage *img;
|
||||
Pixmap pix;
|
||||
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
RContextAttributes attr;
|
||||
RContextAttributes attr;
|
||||
|
||||
dpy = XOpenDisplay("");
|
||||
if (!dpy) {
|
||||
puts("cant open display");
|
||||
exit(1);
|
||||
}
|
||||
dpy = XOpenDisplay("");
|
||||
if (!dpy) {
|
||||
puts("cant open display");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
attr.flags = RC_RenderMode | RC_ColorsPerChannel;
|
||||
attr.render_mode = RDitheredRendering;
|
||||
attr.colors_per_channel = 4;
|
||||
ctx = RCreateContext(dpy, DefaultScreen(dpy), &attr);
|
||||
attr.flags = RC_RenderMode | RC_ColorsPerChannel;
|
||||
attr.render_mode = RDitheredRendering;
|
||||
attr.colors_per_channel = 4;
|
||||
ctx = RCreateContext(dpy, DefaultScreen(dpy), &attr);
|
||||
|
||||
if (argc<2)
|
||||
img = RGetImageFromXPMData(ctx, image_name);
|
||||
else
|
||||
img = RLoadImage(ctx, argv[1], 0);
|
||||
if (argc < 2)
|
||||
img = RGetImageFromXPMData(ctx, image_name);
|
||||
else
|
||||
img = RLoadImage(ctx, argv[1], 0);
|
||||
|
||||
if (!img) {
|
||||
puts(RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
if (!img) {
|
||||
puts(RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
RImage *tmp = img;
|
||||
if (argc > 2) {
|
||||
RImage *tmp = img;
|
||||
|
||||
img = RScaleImage(tmp, tmp->width*atol(argv[2]),
|
||||
tmp->height*atol(argv[2]));
|
||||
/*img = RSmoothScaleImage(tmp, tmp->width*atol(argv[2]),
|
||||
tmp->height*atol(argv[2]));
|
||||
*/
|
||||
|
||||
RReleaseImage(tmp);
|
||||
}
|
||||
img = RScaleImage(tmp, tmp->width * atol(argv[2]), tmp->height * atol(argv[2]));
|
||||
/*img = RSmoothScaleImage(tmp, tmp->width*atol(argv[2]),
|
||||
tmp->height*atol(argv[2]));
|
||||
*/
|
||||
|
||||
RReleaseImage(tmp);
|
||||
}
|
||||
#if 0
|
||||
if (argc > 2) {
|
||||
img = RScaleImage(img, img->width*atof(argv[2]),
|
||||
img->height*atof(argv[2]));
|
||||
}
|
||||
if (argc > 2) {
|
||||
img = RScaleImage(img, img->width * atof(argv[2]), img->height * atof(argv[2]));
|
||||
}
|
||||
|
||||
{
|
||||
RImage *tmp = RCreateImage(200, 200, True);
|
||||
RColor col = {0,0,255,255};
|
||||
{
|
||||
RImage *tmp = RCreateImage(200, 200, True);
|
||||
RColor col = { 0, 0, 255, 255 };
|
||||
|
||||
if (img->format == RRGBAFormat)
|
||||
puts("alpha");
|
||||
else
|
||||
puts("no alpha");
|
||||
if (img->format == RRGBAFormat)
|
||||
puts("alpha");
|
||||
else
|
||||
puts("no alpha");
|
||||
|
||||
RClearImage(tmp, &col);
|
||||
RClearImage(tmp, &col);
|
||||
|
||||
RCombineArea(tmp, img, 0, 0, 20, 20, 10, 10);
|
||||
img = tmp;
|
||||
}
|
||||
RCombineArea(tmp, img, 0, 0, 20, 20, 10, 10);
|
||||
img = tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!RConvertImage(ctx, img, &pix)) {
|
||||
puts(RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
if (!RConvertImage(ctx, img, &pix)) {
|
||||
puts(RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("%ix%i\n", img->width, img->height);
|
||||
printf("%ix%i\n", img->width, img->height);
|
||||
|
||||
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 10, 10, img->width, img->height, 0, 0, 0);
|
||||
XSetWindowBackgroundPixmap(dpy, win, pix);
|
||||
XClearWindow(dpy, win);
|
||||
XMapRaised(dpy, win);
|
||||
XFlush(dpy);
|
||||
getchar();
|
||||
|
||||
|
||||
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 10, 10,
|
||||
img->width, img->height, 0, 0, 0);
|
||||
XSetWindowBackgroundPixmap(dpy, win, pix);
|
||||
XClearWindow(dpy, win);
|
||||
XMapRaised(dpy, win);
|
||||
XFlush(dpy);
|
||||
getchar();
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
177
wrlib/tiff.c
177
wrlib/tiff.c
@@ -21,7 +21,6 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#ifdef USE_TIFF
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -31,118 +30,114 @@
|
||||
#include <tiff.h>
|
||||
#include <tiffio.h>
|
||||
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
RImage*
|
||||
RLoadTIFF(RContext *context, char *file, int index)
|
||||
RImage *RLoadTIFF(RContext * context, char *file, int index)
|
||||
{
|
||||
RImage *image = NULL;
|
||||
TIFF *tif;
|
||||
int i;
|
||||
unsigned char *r, *g, *b, *a;
|
||||
uint16 alpha, amode;
|
||||
uint32 width, height;
|
||||
uint32 *data, *ptr;
|
||||
uint16 extrasamples;
|
||||
uint16 *sampleinfo;
|
||||
int ch;
|
||||
RImage *image = NULL;
|
||||
TIFF *tif;
|
||||
int i;
|
||||
unsigned char *r, *g, *b, *a;
|
||||
uint16 alpha, amode;
|
||||
uint32 width, height;
|
||||
uint32 *data, *ptr;
|
||||
uint16 extrasamples;
|
||||
uint16 *sampleinfo;
|
||||
int ch;
|
||||
|
||||
tif = TIFFOpen(file, "r");
|
||||
if (!tif)
|
||||
return NULL;
|
||||
|
||||
tif = TIFFOpen(file, "r");
|
||||
if (!tif)
|
||||
return NULL;
|
||||
/* seek index */
|
||||
i = index;
|
||||
while (i > 0) {
|
||||
if (!TIFFReadDirectory(tif)) {
|
||||
RErrorCode = RERR_BADINDEX;
|
||||
TIFFClose(tif);
|
||||
return NULL;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
|
||||
/* seek index */
|
||||
i = index;
|
||||
while (i>0) {
|
||||
if (!TIFFReadDirectory(tif)) {
|
||||
RErrorCode = RERR_BADINDEX;
|
||||
TIFFClose(tif);
|
||||
return NULL;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
/* get info */
|
||||
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
|
||||
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
|
||||
|
||||
/* get info */
|
||||
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
|
||||
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
|
||||
TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo);
|
||||
|
||||
TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
|
||||
&extrasamples, &sampleinfo);
|
||||
alpha = (extrasamples == 1 &&
|
||||
((sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA) || (sampleinfo[0] == EXTRASAMPLE_UNASSALPHA)));
|
||||
amode = (extrasamples == 1 && sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
|
||||
|
||||
alpha = (extrasamples == 1 &&
|
||||
((sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA) || (sampleinfo[0] == EXTRASAMPLE_UNASSALPHA)));
|
||||
amode = (extrasamples == 1 && sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
|
||||
if (width < 1 || height < 1) {
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
TIFFClose(tif);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (width<1 || height<1) {
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
TIFFClose(tif);
|
||||
return NULL;
|
||||
}
|
||||
/* read data */
|
||||
ptr = data = (uint32 *) _TIFFmalloc(width * height * sizeof(uint32));
|
||||
|
||||
/* read data */
|
||||
ptr = data = (uint32*)_TIFFmalloc(width * height * sizeof(uint32));
|
||||
if (!data) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
} else {
|
||||
if (!TIFFReadRGBAImage(tif, width, height, data, 0)) {
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
} else {
|
||||
|
||||
if (!data) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
} else {
|
||||
if (!TIFFReadRGBAImage(tif, width, height, data, 0)) {
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
} else {
|
||||
/* convert data */
|
||||
image = RCreateImage(width, height, alpha);
|
||||
|
||||
/* convert data */
|
||||
image = RCreateImage(width, height, alpha);
|
||||
if (alpha)
|
||||
ch = 4;
|
||||
else
|
||||
ch = 3;
|
||||
|
||||
if (alpha)
|
||||
ch = 4;
|
||||
else
|
||||
ch = 3;
|
||||
if (image) {
|
||||
int x, y;
|
||||
|
||||
if (image) {
|
||||
int x, y;
|
||||
r = image->data;
|
||||
g = image->data + 1;
|
||||
b = image->data + 2;
|
||||
a = image->data + 3;
|
||||
|
||||
r = image->data;
|
||||
g = image->data+1;
|
||||
b = image->data+2;
|
||||
a = image->data+3;
|
||||
/* data seems to be stored upside down */
|
||||
data += width * (height - 1);
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
|
||||
/* data seems to be stored upside down */
|
||||
data += width * (height-1);
|
||||
for (y=0; y<height; y++) {
|
||||
for (x=0; x<width; x++) {
|
||||
*(r) = (*data) & 0xff;
|
||||
*(g) = (*data >> 8) & 0xff;
|
||||
*(b) = (*data >> 16) & 0xff;
|
||||
|
||||
*(r) = (*data) & 0xff;
|
||||
*(g) = (*data >> 8) & 0xff;
|
||||
*(b) = (*data >> 16) & 0xff;
|
||||
if (alpha) {
|
||||
*(a) = (*data >> 24) & 0xff;
|
||||
|
||||
if (alpha) {
|
||||
*(a) = (*data >> 24) & 0xff;
|
||||
if (amode && (*a > 0)) {
|
||||
*r = (*r * 255) / *(a);
|
||||
*g = (*g * 255) / *(a);
|
||||
*b = (*b * 255) / *(a);
|
||||
}
|
||||
|
||||
if (amode && (*a > 0)) {
|
||||
*r = (*r * 255) / *(a);
|
||||
*g = (*g * 255) / *(a);
|
||||
*b = (*b * 255) / *(a);
|
||||
}
|
||||
a += 4;
|
||||
}
|
||||
|
||||
a+=4;
|
||||
}
|
||||
r += ch;
|
||||
g += ch;
|
||||
b += ch;
|
||||
data++;
|
||||
}
|
||||
data -= 2 * width;
|
||||
}
|
||||
}
|
||||
}
|
||||
_TIFFfree(ptr);
|
||||
}
|
||||
|
||||
r+=ch; g+=ch; b+=ch;
|
||||
data++;
|
||||
}
|
||||
data -= 2*width;
|
||||
}
|
||||
}
|
||||
}
|
||||
_TIFFfree(ptr);
|
||||
}
|
||||
TIFFClose(tif);
|
||||
|
||||
TIFFClose(tif);
|
||||
|
||||
return image;
|
||||
return image;
|
||||
}
|
||||
|
||||
#endif /* USE_TIFF */
|
||||
|
||||
#endif /* USE_TIFF */
|
||||
|
||||
1150
wrlib/x86_specific.c
1150
wrlib/x86_specific.c
File diff suppressed because it is too large
Load Diff
249
wrlib/xpixmap.c
249
wrlib/xpixmap.c
@@ -19,7 +19,6 @@
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
@@ -31,18 +30,15 @@
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
|
||||
static int
|
||||
get_shifts(unsigned long mask)
|
||||
static int get_shifts(unsigned long mask)
|
||||
{
|
||||
int i=0;
|
||||
int i = 0;
|
||||
|
||||
while (mask) {
|
||||
mask>>=1;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
while (mask) {
|
||||
mask >>= 1;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
#define NORMALIZE_RED(pixel) ((rshift>0) ? ((pixel) & rmask) >> rshift \
|
||||
@@ -52,142 +48,133 @@ get_shifts(unsigned long mask)
|
||||
#define NORMALIZE_BLUE(pixel) ((bshift>0) ? ((pixel) & bmask) >> bshift \
|
||||
: ((pixel) & bmask) << -bshift)
|
||||
|
||||
RImage*
|
||||
RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask)
|
||||
RImage *RCreateImageFromXImage(RContext * context, XImage * image, XImage * mask)
|
||||
{
|
||||
RImage *img;
|
||||
int x, y;
|
||||
unsigned long pixel;
|
||||
unsigned char *data;
|
||||
int rshift, gshift, bshift;
|
||||
int rmask, gmask, bmask;
|
||||
RImage *img;
|
||||
int x, y;
|
||||
unsigned long pixel;
|
||||
unsigned char *data;
|
||||
int rshift, gshift, bshift;
|
||||
int rmask, gmask, bmask;
|
||||
|
||||
assert(image!=NULL);
|
||||
assert(image->format==ZPixmap);
|
||||
assert(!mask || mask->format==ZPixmap);
|
||||
assert(image != NULL);
|
||||
assert(image->format == ZPixmap);
|
||||
assert(!mask || mask->format == ZPixmap);
|
||||
|
||||
img = RCreateImage(image->width, image->height, mask!=NULL);
|
||||
if (!img) {
|
||||
return NULL;
|
||||
}
|
||||
img = RCreateImage(image->width, image->height, mask != NULL);
|
||||
if (!img) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* I don't know why, but XGetImage() for pixmaps don't set the
|
||||
* {red,green,blue}_mask values correctly.
|
||||
*/
|
||||
if (context->depth == image->depth) {
|
||||
rmask = context->visual->red_mask;
|
||||
gmask = context->visual->green_mask;
|
||||
bmask = context->visual->blue_mask;
|
||||
} else {
|
||||
rmask = image->red_mask;
|
||||
gmask = image->green_mask;
|
||||
bmask = image->blue_mask;
|
||||
}
|
||||
|
||||
/* I don't know why, but XGetImage() for pixmaps don't set the
|
||||
* {red,green,blue}_mask values correctly.
|
||||
*/
|
||||
if (context->depth==image->depth) {
|
||||
rmask = context->visual->red_mask;
|
||||
gmask = context->visual->green_mask;
|
||||
bmask = context->visual->blue_mask;
|
||||
} else {
|
||||
rmask = image->red_mask;
|
||||
gmask = image->green_mask;
|
||||
bmask = image->blue_mask;
|
||||
}
|
||||
/* how many bits to shift to normalize the color into 8bpp */
|
||||
rshift = get_shifts(rmask) - 8;
|
||||
gshift = get_shifts(gmask) - 8;
|
||||
bshift = get_shifts(bmask) - 8;
|
||||
|
||||
/* how many bits to shift to normalize the color into 8bpp */
|
||||
rshift = get_shifts(rmask) - 8;
|
||||
gshift = get_shifts(gmask) - 8;
|
||||
bshift = get_shifts(bmask) - 8;
|
||||
data = img->data;
|
||||
|
||||
data = img->data;
|
||||
|
||||
if (image->depth==1) {
|
||||
for (y = 0; y < image->height; y++) {
|
||||
for (x = 0; x < image->width; x++) {
|
||||
pixel = XGetPixel(image, x, y);
|
||||
if (pixel) {
|
||||
*data++ = 0;
|
||||
*data++ = 0;
|
||||
*data++ = 0;
|
||||
} else {
|
||||
*data++ = 0xff;
|
||||
*data++ = 0xff;
|
||||
*data++ = 0xff;
|
||||
}
|
||||
if (mask) data++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (y = 0; y < image->height; y++) {
|
||||
for (x = 0; x < image->width; x++) {
|
||||
pixel = XGetPixel(image, x, y);
|
||||
*(data++) = NORMALIZE_RED(pixel);
|
||||
*(data++) = NORMALIZE_GREEN(pixel);
|
||||
*(data++) = NORMALIZE_BLUE(pixel);
|
||||
if (mask) data++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (image->depth == 1) {
|
||||
for (y = 0; y < image->height; y++) {
|
||||
for (x = 0; x < image->width; x++) {
|
||||
pixel = XGetPixel(image, x, y);
|
||||
if (pixel) {
|
||||
*data++ = 0;
|
||||
*data++ = 0;
|
||||
*data++ = 0;
|
||||
} else {
|
||||
*data++ = 0xff;
|
||||
*data++ = 0xff;
|
||||
*data++ = 0xff;
|
||||
}
|
||||
if (mask)
|
||||
data++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (y = 0; y < image->height; y++) {
|
||||
for (x = 0; x < image->width; x++) {
|
||||
pixel = XGetPixel(image, x, y);
|
||||
*(data++) = NORMALIZE_RED(pixel);
|
||||
*(data++) = NORMALIZE_GREEN(pixel);
|
||||
*(data++) = NORMALIZE_BLUE(pixel);
|
||||
if (mask)
|
||||
data++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
if (mask) {
|
||||
data = img->data + 3; /* Skip R, G & B */
|
||||
for (y = 0; y < MIN(mask->height, image->height); y++) {
|
||||
for (x = 0; x < MIN(mask->width, image->width); x++) {
|
||||
if (mask->width <= image->width && XGetPixel(mask, x, y)) {
|
||||
*data = 0xff;
|
||||
} else {
|
||||
*data = 0;
|
||||
}
|
||||
data += 4;
|
||||
}
|
||||
for (; x < image->width; x++) {
|
||||
*data = 0;
|
||||
data += 4;
|
||||
}
|
||||
}
|
||||
for (; y < image->height; y++) {
|
||||
for (x = 0; x < image->width; x++) {
|
||||
*data = 0;
|
||||
data += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
return img;
|
||||
if (mask) {
|
||||
data = img->data + 3; /* Skip R, G & B */
|
||||
for (y = 0; y < MIN(mask->height, image->height); y++) {
|
||||
for (x = 0; x < MIN(mask->width, image->width); x++) {
|
||||
if (mask->width <= image->width && XGetPixel(mask, x, y)) {
|
||||
*data = 0xff;
|
||||
} else {
|
||||
*data = 0;
|
||||
}
|
||||
data += 4;
|
||||
}
|
||||
for (; x < image->width; x++) {
|
||||
*data = 0;
|
||||
data += 4;
|
||||
}
|
||||
}
|
||||
for (; y < image->height; y++) {
|
||||
for (x = 0; x < image->width; x++) {
|
||||
*data = 0;
|
||||
data += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RImage*
|
||||
RCreateImageFromDrawable(RContext *context, Drawable drawable, Pixmap mask)
|
||||
RImage *RCreateImageFromDrawable(RContext * context, Drawable drawable, Pixmap mask)
|
||||
{
|
||||
RImage *image;
|
||||
XImage *pimg, *mimg;
|
||||
unsigned int w, h, bar;
|
||||
int foo;
|
||||
Window baz;
|
||||
RImage *image;
|
||||
XImage *pimg, *mimg;
|
||||
unsigned int w, h, bar;
|
||||
int foo;
|
||||
Window baz;
|
||||
|
||||
assert(drawable != None);
|
||||
|
||||
assert(drawable!=None);
|
||||
if (!XGetGeometry(context->dpy, drawable, &baz, &foo, &foo, &w, &h, &bar, &bar)) {
|
||||
printf("wrlib: invalid window or pixmap passed to RCreateImageFromPixmap\n");
|
||||
return NULL;
|
||||
}
|
||||
pimg = XGetImage(context->dpy, drawable, 0, 0, w, h, AllPlanes, ZPixmap);
|
||||
|
||||
if (!XGetGeometry(context->dpy, drawable, &baz, &foo, &foo,
|
||||
&w, &h, &bar, &bar)) {
|
||||
printf("wrlib: invalid window or pixmap passed to RCreateImageFromPixmap\n");
|
||||
return NULL;
|
||||
}
|
||||
pimg = XGetImage(context->dpy, drawable, 0, 0, w, h, AllPlanes,
|
||||
ZPixmap);
|
||||
if (!pimg) {
|
||||
RErrorCode = RERR_XERROR;
|
||||
return NULL;
|
||||
}
|
||||
mimg = NULL;
|
||||
if (mask) {
|
||||
if (XGetGeometry(context->dpy, mask, &baz, &foo, &foo, &w, &h, &bar, &bar)) {
|
||||
mimg = XGetImage(context->dpy, mask, 0, 0, w, h, AllPlanes, ZPixmap);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pimg) {
|
||||
RErrorCode = RERR_XERROR;
|
||||
return NULL;
|
||||
}
|
||||
mimg = NULL;
|
||||
if (mask) {
|
||||
if (XGetGeometry(context->dpy, mask, &baz, &foo, &foo,
|
||||
&w, &h, &bar, &bar)) {
|
||||
mimg = XGetImage(context->dpy, mask, 0, 0, w, h, AllPlanes,
|
||||
ZPixmap);
|
||||
}
|
||||
}
|
||||
image = RCreateImageFromXImage(context, pimg, mimg);
|
||||
|
||||
image = RCreateImageFromXImage(context, pimg, mimg);
|
||||
XDestroyImage(pimg);
|
||||
if (mimg)
|
||||
XDestroyImage(mimg);
|
||||
|
||||
XDestroyImage(pimg);
|
||||
if (mimg)
|
||||
XDestroyImage(mimg);
|
||||
|
||||
return image;
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
446
wrlib/xpm.c
446
wrlib/xpm.c
@@ -21,7 +21,6 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#ifdef USE_XPM
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
@@ -32,248 +31,243 @@
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
RImage*
|
||||
RGetImageFromXPMData(RContext *context, char **xpmData)
|
||||
RImage *RGetImageFromXPMData(RContext * context, char **xpmData)
|
||||
{
|
||||
Display *dpy = context->dpy;
|
||||
Colormap cmap = context->cmap;
|
||||
RImage *image;
|
||||
XpmImage xpm;
|
||||
unsigned char *color_table[4];
|
||||
unsigned char *data;
|
||||
int *p;
|
||||
int i;
|
||||
Display *dpy = context->dpy;
|
||||
Colormap cmap = context->cmap;
|
||||
RImage *image;
|
||||
XpmImage xpm;
|
||||
unsigned char *color_table[4];
|
||||
unsigned char *data;
|
||||
int *p;
|
||||
int i;
|
||||
|
||||
i = XpmCreateXpmImageFromData(xpmData, &xpm, (XpmInfo *)NULL);
|
||||
if (i!=XpmSuccess) {
|
||||
switch (i) {
|
||||
case XpmOpenFailed:
|
||||
RErrorCode = RERR_OPEN;
|
||||
break;
|
||||
case XpmFileInvalid:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
case XpmNoMemory:
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
break;
|
||||
default:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (xpm.height<1 || xpm.width < 1) {
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
i = XpmCreateXpmImageFromData(xpmData, &xpm, (XpmInfo *) NULL);
|
||||
if (i != XpmSuccess) {
|
||||
switch (i) {
|
||||
case XpmOpenFailed:
|
||||
RErrorCode = RERR_OPEN;
|
||||
break;
|
||||
case XpmFileInvalid:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
case XpmNoMemory:
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
break;
|
||||
default:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (xpm.height < 1 || xpm.width < 1) {
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (xpm.colorTable==NULL) {
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
image = RCreateImage(xpm.width, xpm.height, True);
|
||||
if (!image) {
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
if (xpm.colorTable == NULL) {
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
image = RCreateImage(xpm.width, xpm.height, True);
|
||||
if (!image) {
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* make color table */
|
||||
for (i=0; i<4; i++) {
|
||||
color_table[i] = malloc(xpm.ncolors*sizeof(char));
|
||||
if (!color_table[i]) {
|
||||
for (i=i-1;i>=0; i--) {
|
||||
if (color_table[i])
|
||||
free(color_table[i]);
|
||||
}
|
||||
RReleaseImage(image);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* make color table */
|
||||
for (i = 0; i < 4; i++) {
|
||||
color_table[i] = malloc(xpm.ncolors * sizeof(char));
|
||||
if (!color_table[i]) {
|
||||
for (i = i - 1; i >= 0; i--) {
|
||||
if (color_table[i])
|
||||
free(color_table[i]);
|
||||
}
|
||||
RReleaseImage(image);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<xpm.ncolors; i++) {
|
||||
XColor xcolor;
|
||||
char * color = NULL;
|
||||
for (i = 0; i < xpm.ncolors; i++) {
|
||||
XColor xcolor;
|
||||
char *color = NULL;
|
||||
|
||||
if (xpm.colorTable[i].c_color)
|
||||
color = xpm.colorTable[i].c_color;
|
||||
else if (xpm.colorTable[i].g_color)
|
||||
color = xpm.colorTable[i].g_color;
|
||||
else if (xpm.colorTable[i].g4_color)
|
||||
color = xpm.colorTable[i].g4_color;
|
||||
else if (xpm.colorTable[i].m_color)
|
||||
color = xpm.colorTable[i].m_color;
|
||||
else if (xpm.colorTable[i].symbolic)
|
||||
color = xpm.colorTable[i].symbolic;
|
||||
if (xpm.colorTable[i].c_color)
|
||||
color = xpm.colorTable[i].c_color;
|
||||
else if (xpm.colorTable[i].g_color)
|
||||
color = xpm.colorTable[i].g_color;
|
||||
else if (xpm.colorTable[i].g4_color)
|
||||
color = xpm.colorTable[i].g4_color;
|
||||
else if (xpm.colorTable[i].m_color)
|
||||
color = xpm.colorTable[i].m_color;
|
||||
else if (xpm.colorTable[i].symbolic)
|
||||
color = xpm.colorTable[i].symbolic;
|
||||
|
||||
if (!color) {
|
||||
color_table[0][i] = 0xbe;
|
||||
color_table[1][i] = 0xbe;
|
||||
color_table[2][i] = 0xbe;
|
||||
color_table[3][i] = 0xff;
|
||||
continue;
|
||||
}
|
||||
if (!color) {
|
||||
color_table[0][i] = 0xbe;
|
||||
color_table[1][i] = 0xbe;
|
||||
color_table[2][i] = 0xbe;
|
||||
color_table[3][i] = 0xff;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(color,"None",4)==0) {
|
||||
color_table[0][i]=0;
|
||||
color_table[1][i]=0;
|
||||
color_table[2][i]=0;
|
||||
color_table[3][i]=0;
|
||||
continue;
|
||||
}
|
||||
if (XParseColor(dpy, cmap, color, &xcolor)) {
|
||||
color_table[0][i] = xcolor.red>>8;
|
||||
color_table[1][i] = xcolor.green>>8;
|
||||
color_table[2][i] = xcolor.blue>>8;
|
||||
color_table[3][i] = 0xff;
|
||||
} else {
|
||||
color_table[0][i] = 0xbe;
|
||||
color_table[1][i] = 0xbe;
|
||||
color_table[2][i] = 0xbe;
|
||||
color_table[3][i] = 0xff;
|
||||
}
|
||||
}
|
||||
/* convert pixmap to RImage */
|
||||
p = (int*)xpm.data;
|
||||
data = image->data;
|
||||
for (i=0; i<xpm.width*xpm.height; i++) {
|
||||
*(data++)=color_table[0][*p];
|
||||
*(data++)=color_table[1][*p];
|
||||
*(data++)=color_table[2][*p];
|
||||
*(data++)=color_table[3][*p];
|
||||
p++;
|
||||
}
|
||||
for(i=0; i<4; i++) {
|
||||
free(color_table[i]);
|
||||
}
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return image;
|
||||
if (strncmp(color, "None", 4) == 0) {
|
||||
color_table[0][i] = 0;
|
||||
color_table[1][i] = 0;
|
||||
color_table[2][i] = 0;
|
||||
color_table[3][i] = 0;
|
||||
continue;
|
||||
}
|
||||
if (XParseColor(dpy, cmap, color, &xcolor)) {
|
||||
color_table[0][i] = xcolor.red >> 8;
|
||||
color_table[1][i] = xcolor.green >> 8;
|
||||
color_table[2][i] = xcolor.blue >> 8;
|
||||
color_table[3][i] = 0xff;
|
||||
} else {
|
||||
color_table[0][i] = 0xbe;
|
||||
color_table[1][i] = 0xbe;
|
||||
color_table[2][i] = 0xbe;
|
||||
color_table[3][i] = 0xff;
|
||||
}
|
||||
}
|
||||
/* convert pixmap to RImage */
|
||||
p = (int *)xpm.data;
|
||||
data = image->data;
|
||||
for (i = 0; i < xpm.width * xpm.height; i++) {
|
||||
*(data++) = color_table[0][*p];
|
||||
*(data++) = color_table[1][*p];
|
||||
*(data++) = color_table[2][*p];
|
||||
*(data++) = color_table[3][*p];
|
||||
p++;
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
free(color_table[i]);
|
||||
}
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RImage*
|
||||
RLoadXPM(RContext *context, char *file, int index)
|
||||
RImage *RLoadXPM(RContext * context, char *file, int index)
|
||||
{
|
||||
Display *dpy = context->dpy;
|
||||
Colormap cmap = context->cmap;
|
||||
RImage *image;
|
||||
XpmImage xpm;
|
||||
unsigned char *color_table[4];
|
||||
unsigned char *data;
|
||||
int *p;
|
||||
int i;
|
||||
Display *dpy = context->dpy;
|
||||
Colormap cmap = context->cmap;
|
||||
RImage *image;
|
||||
XpmImage xpm;
|
||||
unsigned char *color_table[4];
|
||||
unsigned char *data;
|
||||
int *p;
|
||||
int i;
|
||||
|
||||
i = XpmReadFileToXpmImage(file, &xpm, (XpmInfo *)NULL);
|
||||
if (i!=XpmSuccess) {
|
||||
switch (i) {
|
||||
case XpmOpenFailed:
|
||||
RErrorCode = RERR_OPEN;
|
||||
break;
|
||||
case XpmFileInvalid:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
case XpmNoMemory:
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
break;
|
||||
default:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (xpm.height<1 || xpm.width < 1) {
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
i = XpmReadFileToXpmImage(file, &xpm, (XpmInfo *) NULL);
|
||||
if (i != XpmSuccess) {
|
||||
switch (i) {
|
||||
case XpmOpenFailed:
|
||||
RErrorCode = RERR_OPEN;
|
||||
break;
|
||||
case XpmFileInvalid:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
case XpmNoMemory:
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
break;
|
||||
default:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (xpm.height < 1 || xpm.width < 1) {
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (xpm.colorTable==NULL) {
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
image = RCreateImage(xpm.width, xpm.height, True);
|
||||
if (!image) {
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
if (xpm.colorTable == NULL) {
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
image = RCreateImage(xpm.width, xpm.height, True);
|
||||
if (!image) {
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* make color table */
|
||||
for (i=0; i<4; i++) {
|
||||
color_table[i] = malloc(xpm.ncolors*sizeof(char));
|
||||
if (!color_table[i]) {
|
||||
for (i=i-1;i>=0; i--) {
|
||||
if (color_table[i])
|
||||
free(color_table[i]);
|
||||
}
|
||||
RReleaseImage(image);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* make color table */
|
||||
for (i = 0; i < 4; i++) {
|
||||
color_table[i] = malloc(xpm.ncolors * sizeof(char));
|
||||
if (!color_table[i]) {
|
||||
for (i = i - 1; i >= 0; i--) {
|
||||
if (color_table[i])
|
||||
free(color_table[i]);
|
||||
}
|
||||
RReleaseImage(image);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<xpm.ncolors; i++) {
|
||||
XColor xcolor;
|
||||
char * color = NULL;
|
||||
for (i = 0; i < xpm.ncolors; i++) {
|
||||
XColor xcolor;
|
||||
char *color = NULL;
|
||||
|
||||
if (xpm.colorTable[i].c_color)
|
||||
color = xpm.colorTable[i].c_color;
|
||||
else if (xpm.colorTable[i].g_color)
|
||||
color = xpm.colorTable[i].g_color;
|
||||
else if (xpm.colorTable[i].g4_color)
|
||||
color = xpm.colorTable[i].g4_color;
|
||||
else if (xpm.colorTable[i].m_color)
|
||||
color = xpm.colorTable[i].m_color;
|
||||
else if (xpm.colorTable[i].symbolic)
|
||||
color = xpm.colorTable[i].symbolic;
|
||||
if (xpm.colorTable[i].c_color)
|
||||
color = xpm.colorTable[i].c_color;
|
||||
else if (xpm.colorTable[i].g_color)
|
||||
color = xpm.colorTable[i].g_color;
|
||||
else if (xpm.colorTable[i].g4_color)
|
||||
color = xpm.colorTable[i].g4_color;
|
||||
else if (xpm.colorTable[i].m_color)
|
||||
color = xpm.colorTable[i].m_color;
|
||||
else if (xpm.colorTable[i].symbolic)
|
||||
color = xpm.colorTable[i].symbolic;
|
||||
|
||||
if (!color) {
|
||||
color_table[0][i] = 0xbe;
|
||||
color_table[1][i] = 0xbe;
|
||||
color_table[2][i] = 0xbe;
|
||||
color_table[3][i] = 0xff;
|
||||
continue;
|
||||
}
|
||||
if (!color) {
|
||||
color_table[0][i] = 0xbe;
|
||||
color_table[1][i] = 0xbe;
|
||||
color_table[2][i] = 0xbe;
|
||||
color_table[3][i] = 0xff;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(color,"None",4)==0) {
|
||||
color_table[0][i]=0;
|
||||
color_table[1][i]=0;
|
||||
color_table[2][i]=0;
|
||||
color_table[3][i]=0;
|
||||
continue;
|
||||
}
|
||||
if (XParseColor(dpy, cmap, color, &xcolor)) {
|
||||
color_table[0][i] = xcolor.red>>8;
|
||||
color_table[1][i] = xcolor.green>>8;
|
||||
color_table[2][i] = xcolor.blue>>8;
|
||||
color_table[3][i] = 0xff;
|
||||
} else {
|
||||
color_table[0][i] = 0xbe;
|
||||
color_table[1][i] = 0xbe;
|
||||
color_table[2][i] = 0xbe;
|
||||
color_table[3][i] = 0xff;
|
||||
}
|
||||
}
|
||||
/* convert pixmap to RImage */
|
||||
p = (int*)xpm.data;
|
||||
data = image->data;
|
||||
for (i=0; i<xpm.width*xpm.height; i++, p++) {
|
||||
*(data++)=color_table[0][*p];
|
||||
*(data++)=color_table[1][*p];
|
||||
*(data++)=color_table[2][*p];
|
||||
*(data++)=color_table[3][*p];
|
||||
}
|
||||
for(i=0; i<4; i++) {
|
||||
free(color_table[i]);
|
||||
}
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return image;
|
||||
if (strncmp(color, "None", 4) == 0) {
|
||||
color_table[0][i] = 0;
|
||||
color_table[1][i] = 0;
|
||||
color_table[2][i] = 0;
|
||||
color_table[3][i] = 0;
|
||||
continue;
|
||||
}
|
||||
if (XParseColor(dpy, cmap, color, &xcolor)) {
|
||||
color_table[0][i] = xcolor.red >> 8;
|
||||
color_table[1][i] = xcolor.green >> 8;
|
||||
color_table[2][i] = xcolor.blue >> 8;
|
||||
color_table[3][i] = 0xff;
|
||||
} else {
|
||||
color_table[0][i] = 0xbe;
|
||||
color_table[1][i] = 0xbe;
|
||||
color_table[2][i] = 0xbe;
|
||||
color_table[3][i] = 0xff;
|
||||
}
|
||||
}
|
||||
/* convert pixmap to RImage */
|
||||
p = (int *)xpm.data;
|
||||
data = image->data;
|
||||
for (i = 0; i < xpm.width * xpm.height; i++, p++) {
|
||||
*(data++) = color_table[0][*p];
|
||||
*(data++) = color_table[1][*p];
|
||||
*(data++) = color_table[2][*p];
|
||||
*(data++) = color_table[3][*p];
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
free(color_table[i]);
|
||||
}
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return image;
|
||||
}
|
||||
|
||||
#endif /* USE_XPM */
|
||||
|
||||
#endif /* USE_XPM */
|
||||
|
||||
352
wrlib/xutil.c
352
wrlib/xutil.c
@@ -21,7 +21,6 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <stdlib.h>
|
||||
@@ -33,252 +32,221 @@
|
||||
#ifdef XSHM
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#endif /* XSHM */
|
||||
#endif /* XSHM */
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
#ifdef XSHM
|
||||
|
||||
static int shmError;
|
||||
|
||||
static int (*oldErrorHandler)();
|
||||
static int (*oldErrorHandler) ();
|
||||
|
||||
static int
|
||||
errorHandler(Display *dpy, XErrorEvent *err)
|
||||
static int errorHandler(Display * dpy, XErrorEvent * err)
|
||||
{
|
||||
shmError=1;
|
||||
if(err->error_code!=BadAccess)
|
||||
(*oldErrorHandler)(dpy, err);
|
||||
shmError = 1;
|
||||
if (err->error_code != BadAccess)
|
||||
(*oldErrorHandler) (dpy, err);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
RXImage*
|
||||
RCreateXImage(RContext *context, int depth, unsigned width, unsigned height)
|
||||
RXImage *RCreateXImage(RContext * context, int depth, unsigned width, unsigned height)
|
||||
{
|
||||
RXImage *rximg;
|
||||
Visual *visual = context->visual;
|
||||
|
||||
rximg = malloc(sizeof(RXImage));
|
||||
if (!rximg) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
RXImage *rximg;
|
||||
Visual *visual = context->visual;
|
||||
|
||||
rximg = malloc(sizeof(RXImage));
|
||||
if (!rximg) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
#ifndef XSHM
|
||||
rximg->image = XCreateImage(context->dpy, visual, depth,
|
||||
ZPixmap, 0, NULL, width, height, 8, 0);
|
||||
if (!rximg->image) {
|
||||
free(rximg);
|
||||
RErrorCode = RERR_XERROR;
|
||||
return NULL;
|
||||
}
|
||||
rximg->image->data = malloc(rximg->image->bytes_per_line*height);
|
||||
if (!rximg->image->data) {
|
||||
XDestroyImage(rximg->image);
|
||||
free(rximg);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
rximg->image = XCreateImage(context->dpy, visual, depth, ZPixmap, 0, NULL, width, height, 8, 0);
|
||||
if (!rximg->image) {
|
||||
free(rximg);
|
||||
RErrorCode = RERR_XERROR;
|
||||
return NULL;
|
||||
}
|
||||
rximg->image->data = malloc(rximg->image->bytes_per_line * height);
|
||||
if (!rximg->image->data) {
|
||||
XDestroyImage(rximg->image);
|
||||
free(rximg);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
#else /* XSHM */
|
||||
if (!context->attribs->use_shared_memory) {
|
||||
retry_without_shm:
|
||||
|
||||
#else /* XSHM */
|
||||
if (!context->attribs->use_shared_memory) {
|
||||
retry_without_shm:
|
||||
context->attribs->use_shared_memory = 0;
|
||||
rximg->is_shared = 0;
|
||||
rximg->image = XCreateImage(context->dpy, visual, depth, ZPixmap, 0, NULL, width, height, 8, 0);
|
||||
if (!rximg->image) {
|
||||
free(rximg);
|
||||
RErrorCode = RERR_XERROR;
|
||||
return NULL;
|
||||
}
|
||||
rximg->image->data = malloc(rximg->image->bytes_per_line * height);
|
||||
if (!rximg->image->data) {
|
||||
XDestroyImage(rximg->image);
|
||||
free(rximg);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
rximg->is_shared = 1;
|
||||
|
||||
context->attribs->use_shared_memory = 0;
|
||||
rximg->is_shared = 0;
|
||||
rximg->image = XCreateImage(context->dpy, visual, depth,
|
||||
ZPixmap, 0, NULL, width, height, 8, 0);
|
||||
if (!rximg->image) {
|
||||
free(rximg);
|
||||
RErrorCode = RERR_XERROR;
|
||||
return NULL;
|
||||
}
|
||||
rximg->image->data = malloc(rximg->image->bytes_per_line*height);
|
||||
if (!rximg->image->data) {
|
||||
XDestroyImage(rximg->image);
|
||||
free(rximg);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
rximg->is_shared = 1;
|
||||
rximg->info.readOnly = False;
|
||||
|
||||
rximg->info.readOnly = False;
|
||||
rximg->image = XShmCreateImage(context->dpy, visual, depth,
|
||||
ZPixmap, NULL, &rximg->info, width, height);
|
||||
|
||||
rximg->image = XShmCreateImage(context->dpy, visual, depth,
|
||||
ZPixmap, NULL, &rximg->info, width,
|
||||
height);
|
||||
rximg->info.shmid = shmget(IPC_PRIVATE, rximg->image->bytes_per_line * height, IPC_CREAT | 0777);
|
||||
if (rximg->info.shmid < 0) {
|
||||
context->attribs->use_shared_memory = 0;
|
||||
perror("wrlib: could not allocate shared memory segment");
|
||||
XDestroyImage(rximg->image);
|
||||
goto retry_without_shm;
|
||||
}
|
||||
|
||||
rximg->info.shmid = shmget(IPC_PRIVATE,
|
||||
rximg->image->bytes_per_line*height,
|
||||
IPC_CREAT|0777);
|
||||
if (rximg->info.shmid < 0) {
|
||||
context->attribs->use_shared_memory = 0;
|
||||
perror("wrlib: could not allocate shared memory segment");
|
||||
XDestroyImage(rximg->image);
|
||||
goto retry_without_shm;
|
||||
}
|
||||
rximg->info.shmaddr = shmat(rximg->info.shmid, 0, 0);
|
||||
if (rximg->info.shmaddr == (void *)-1) {
|
||||
context->attribs->use_shared_memory = 0;
|
||||
if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib: shmctl");
|
||||
perror("wrlib: could not allocate shared memory");
|
||||
XDestroyImage(rximg->image);
|
||||
goto retry_without_shm;
|
||||
}
|
||||
|
||||
rximg->info.shmaddr = shmat(rximg->info.shmid, 0, 0);
|
||||
if (rximg->info.shmaddr == (void*)-1) {
|
||||
context->attribs->use_shared_memory = 0;
|
||||
if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib: shmctl");
|
||||
perror("wrlib: could not allocate shared memory");
|
||||
XDestroyImage(rximg->image);
|
||||
goto retry_without_shm;
|
||||
}
|
||||
shmError = 0;
|
||||
XSync(context->dpy, False);
|
||||
oldErrorHandler = XSetErrorHandler(errorHandler);
|
||||
XShmAttach(context->dpy, &rximg->info);
|
||||
XSync(context->dpy, False);
|
||||
XSetErrorHandler(oldErrorHandler);
|
||||
|
||||
shmError = 0;
|
||||
XSync(context->dpy, False);
|
||||
oldErrorHandler = XSetErrorHandler(errorHandler);
|
||||
XShmAttach(context->dpy, &rximg->info);
|
||||
XSync(context->dpy, False);
|
||||
XSetErrorHandler(oldErrorHandler);
|
||||
rximg->image->data = rximg->info.shmaddr;
|
||||
/* rximg->image->obdata = &(rximg->info); */
|
||||
|
||||
rximg->image->data = rximg->info.shmaddr;
|
||||
/* rximg->image->obdata = &(rximg->info);*/
|
||||
if (shmError) {
|
||||
context->attribs->use_shared_memory = 0;
|
||||
XDestroyImage(rximg->image);
|
||||
if (shmdt(rximg->info.shmaddr) < 0)
|
||||
perror("wrlib: shmdt");
|
||||
if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib: shmctl");
|
||||
/* printf("wrlib:error attaching shared memory segment to XImage\n");
|
||||
*/
|
||||
goto retry_without_shm;
|
||||
}
|
||||
}
|
||||
#endif /* XSHM */
|
||||
|
||||
if (shmError) {
|
||||
context->attribs->use_shared_memory = 0;
|
||||
XDestroyImage(rximg->image);
|
||||
if (shmdt(rximg->info.shmaddr) < 0)
|
||||
perror("wrlib: shmdt");
|
||||
if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib: shmctl");
|
||||
/* printf("wrlib:error attaching shared memory segment to XImage\n");
|
||||
*/
|
||||
goto retry_without_shm;
|
||||
}
|
||||
}
|
||||
#endif /* XSHM */
|
||||
|
||||
return rximg;
|
||||
return rximg;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RDestroyXImage(RContext *context, RXImage *rximage)
|
||||
void RDestroyXImage(RContext * context, RXImage * rximage)
|
||||
{
|
||||
#ifndef XSHM
|
||||
XDestroyImage(rximage->image);
|
||||
#else /* XSHM */
|
||||
if (rximage->is_shared) {
|
||||
XSync(context->dpy, False);
|
||||
XShmDetach(context->dpy, &rximage->info);
|
||||
XDestroyImage(rximage->image);
|
||||
if (shmdt(rximage->info.shmaddr) < 0)
|
||||
perror("wrlib: shmdt");
|
||||
if (shmctl(rximage->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib: shmctl");
|
||||
} else {
|
||||
XDestroyImage(rximage->image);
|
||||
}
|
||||
XDestroyImage(rximage->image);
|
||||
#else /* XSHM */
|
||||
if (rximage->is_shared) {
|
||||
XSync(context->dpy, False);
|
||||
XShmDetach(context->dpy, &rximage->info);
|
||||
XDestroyImage(rximage->image);
|
||||
if (shmdt(rximage->info.shmaddr) < 0)
|
||||
perror("wrlib: shmdt");
|
||||
if (shmctl(rximage->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib: shmctl");
|
||||
} else {
|
||||
XDestroyImage(rximage->image);
|
||||
}
|
||||
#endif
|
||||
free(rximage);
|
||||
free(rximage);
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
getDepth(Display *dpy, Drawable d)
|
||||
static unsigned getDepth(Display * dpy, Drawable d)
|
||||
{
|
||||
Window w;
|
||||
int foo;
|
||||
unsigned bar;
|
||||
unsigned depth;
|
||||
Window w;
|
||||
int foo;
|
||||
unsigned bar;
|
||||
unsigned depth;
|
||||
|
||||
XGetGeometry(dpy, d, &w, &foo, &foo, &bar, &bar, &bar, &depth);
|
||||
XGetGeometry(dpy, d, &w, &foo, &foo, &bar, &bar, &bar, &depth);
|
||||
|
||||
return depth;
|
||||
return depth;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RXImage*
|
||||
RGetXImage(RContext *context, Drawable d, int x, int y,
|
||||
unsigned width, unsigned height)
|
||||
RXImage *RGetXImage(RContext * context, Drawable d, int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
RXImage *ximg = NULL;
|
||||
RXImage *ximg = NULL;
|
||||
|
||||
#ifdef XSHM
|
||||
if (context->attribs->use_shared_memory && 0) {
|
||||
ximg = RCreateXImage(context, getDepth(context->dpy, d),
|
||||
width, height);
|
||||
if (context->attribs->use_shared_memory && 0) {
|
||||
ximg = RCreateXImage(context, getDepth(context->dpy, d), width, height);
|
||||
|
||||
if (ximg && !ximg->is_shared) {
|
||||
RDestroyXImage(context, ximg);
|
||||
ximg = NULL;
|
||||
}
|
||||
if (ximg) {
|
||||
XShmGetImage(context->dpy, d, ximg->image, x, y, AllPlanes);
|
||||
}
|
||||
}
|
||||
if (!ximg) {
|
||||
ximg = malloc(sizeof(RXImage));
|
||||
if (!ximg) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
ximg->is_shared = 0;
|
||||
ximg->image = XGetImage(context->dpy, d, x, y, width, height,
|
||||
AllPlanes, ZPixmap);
|
||||
}
|
||||
return ximg;
|
||||
#else /* !XSHM */
|
||||
ximg = malloc(sizeof(RXImage));
|
||||
if (!ximg) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
if (ximg && !ximg->is_shared) {
|
||||
RDestroyXImage(context, ximg);
|
||||
ximg = NULL;
|
||||
}
|
||||
if (ximg) {
|
||||
XShmGetImage(context->dpy, d, ximg->image, x, y, AllPlanes);
|
||||
}
|
||||
}
|
||||
if (!ximg) {
|
||||
ximg = malloc(sizeof(RXImage));
|
||||
if (!ximg) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
ximg->is_shared = 0;
|
||||
ximg->image = XGetImage(context->dpy, d, x, y, width, height, AllPlanes, ZPixmap);
|
||||
}
|
||||
return ximg;
|
||||
#else /* !XSHM */
|
||||
ximg = malloc(sizeof(RXImage));
|
||||
if (!ximg) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ximg->image = XGetImage(context->dpy, d, x, y, width, height,
|
||||
AllPlanes, ZPixmap);
|
||||
ximg->image = XGetImage(context->dpy, d, x, y, width, height, AllPlanes, ZPixmap);
|
||||
|
||||
return ximg;
|
||||
#endif /* !XSHM */
|
||||
return ximg;
|
||||
#endif /* !XSHM */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RPutXImage(RContext *context, Drawable d, GC gc, RXImage *ximage, int src_x,
|
||||
int src_y, int dest_x, int dest_y,
|
||||
unsigned int width, unsigned int height)
|
||||
RPutXImage(RContext * context, Drawable d, GC gc, RXImage * ximage, int src_x,
|
||||
int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height)
|
||||
{
|
||||
#ifndef XSHM
|
||||
XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x,
|
||||
dest_y, width, height);
|
||||
XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x, dest_y, width, height);
|
||||
#else
|
||||
if (ximage->is_shared) {
|
||||
XShmPutImage(context->dpy, d, gc, ximage->image, src_x, src_y,
|
||||
dest_x, dest_y, width, height, False);
|
||||
} else {
|
||||
XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x,
|
||||
dest_y, width, height);
|
||||
}
|
||||
XFlush(context->dpy);
|
||||
#endif /* XSHM */
|
||||
if (ximage->is_shared) {
|
||||
XShmPutImage(context->dpy, d, gc, ximage->image, src_x, src_y,
|
||||
dest_x, dest_y, width, height, False);
|
||||
} else {
|
||||
XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x, dest_y, width, height);
|
||||
}
|
||||
XFlush(context->dpy);
|
||||
#endif /* XSHM */
|
||||
}
|
||||
|
||||
|
||||
#ifdef XSHM
|
||||
Pixmap
|
||||
R_CreateXImageMappedPixmap(RContext *context, RXImage *rximage)
|
||||
Pixmap R_CreateXImageMappedPixmap(RContext * context, RXImage * rximage)
|
||||
{
|
||||
Pixmap pix;
|
||||
Pixmap pix;
|
||||
|
||||
pix = XShmCreatePixmap(context->dpy, context->drawable,
|
||||
rximage->image->data, &rximage->info,
|
||||
rximage->image->width, rximage->image->height,
|
||||
rximage->image->depth);
|
||||
pix = XShmCreatePixmap(context->dpy, context->drawable,
|
||||
rximage->image->data, &rximage->info,
|
||||
rximage->image->width, rximage->image->height, rximage->image->depth);
|
||||
|
||||
return pix;
|
||||
return pix;
|
||||
}
|
||||
|
||||
#endif /* XSHM */
|
||||
|
||||
#endif /* XSHM */
|
||||
|
||||
Reference in New Issue
Block a user