1
0
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:
Carlos R. Mafra
2009-08-20 00:59:40 +02:00
parent 59fc927dc9
commit 688a56e8ab
209 changed files with 87034 additions and 98138 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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 */

File diff suppressed because it is too large Load Diff

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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";
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 */

View File

@@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}

View File

@@ -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);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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 */

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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 */