fix tga loader....... :)

SVN revision: 2670
This commit is contained in:
Carsten Haitzler 2000-05-19 17:36:48 +00:00
parent 7ccc965fcb
commit e28f0b22e3
4 changed files with 1596 additions and 1579 deletions

View File

@ -4,7 +4,7 @@
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
# include <config.h>
#endif
#include "common.h"
@ -23,10 +23,10 @@ void formats (ImlibLoader *l);
typedef struct tagRGBQUAD
{
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
}
RGBQUAD;
@ -37,24 +37,24 @@ RGBQUAD;
int ReadleShort(FILE *file, unsigned short *ret)
{
unsigned char b[2];
if (fread(b, sizeof(unsigned char), 2, file) != 2)
return 0;
*ret = (b[1] << 8) | b[0];
return 1;
unsigned char b[2];
if (fread(b, sizeof(unsigned char), 2, file) != 2)
return 0;
*ret = (b[1] << 8) | b[0];
return 1;
}
int ReadleLong(FILE *file, unsigned long *ret)
{
unsigned char b[4];
if (fread(b, sizeof(unsigned char), 4, file) != 4)
return 0;
*ret = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
return 1;
unsigned char b[4];
if (fread(b, sizeof(unsigned char), 4, file) != 4)
return 0;
*ret = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
return 1;
}
char
@ -75,105 +75,105 @@ load (ImlibImage *im, ImlibProgressFunction progress,
RGBQUAD rgbQuads[256];
unsigned long rmask = 0xff, gmask = 0xff, bmask = 0xff;
unsigned long rshift = 0, gshift = 0, bshift = 0;
if (im->data)
return 0;
f = fopen(im->file, "rb");
if (!f)
return 0;
/* header */
{
struct stat statbuf;
if (stat(im->file, &statbuf) == -1) {
fclose(f);
return 0;
fclose(f);
return 0;
}
size = statbuf.st_size;
if (fread(type, 1, 2, f) != 2) {
fclose(f);
return 0;
fclose(f);
return 0;
}
if (strncmp(type, "BM", 2)) {
fclose(f);
return 0;
fclose(f);
return 0;
}
fseek(f, 8, SEEK_CUR);
ReadleLong(f, &offset);
ReadleLong(f, &headSize);
if (headSize == 12) {
ReadleShort(f, &tmpShort);
w = tmpShort;
ReadleShort(f, &tmpShort);
h = tmpShort;
ReadleShort(f, &planes);
ReadleShort(f, &bitcount);
imgsize = size - offset;
comp = BI_RGB;
ReadleShort(f, &tmpShort);
w = tmpShort;
ReadleShort(f, &tmpShort);
h = tmpShort;
ReadleShort(f, &planes);
ReadleShort(f, &bitcount);
imgsize = size - offset;
comp = BI_RGB;
}
else if (headSize == 40) {
ReadleLong(f, &w);
ReadleLong(f, &h);
ReadleShort(f, &planes);
ReadleShort(f, &bitcount);
ReadleLong(f, &comp);
ReadleLong(f, &imgsize);
imgsize = size - offset;
fseek(f, 16, SEEK_CUR);
ReadleLong(f, &w);
ReadleLong(f, &h);
ReadleShort(f, &planes);
ReadleShort(f, &bitcount);
ReadleLong(f, &comp);
ReadleLong(f, &imgsize);
imgsize = size - offset;
fseek(f, 16, SEEK_CUR);
}
else {
fclose(f);
return 0;
fclose(f);
return 0;
}
if (bitcount < 16) {
ncols = (offset - headSize - 14);
if (headSize == 12) {
ncols /= 3;
for (i = 0; i < ncols; i++)
fread(&rgbQuads[i], 3, 1, f);
}
else {
ncols /= 4;
fread(rgbQuads, 4, ncols, f);
}
ncols = (offset - headSize - 14);
if (headSize == 12) {
ncols /= 3;
for (i = 0; i < ncols; i++)
fread(&rgbQuads[i], 3, 1, f);
}
else {
ncols /= 4;
fread(rgbQuads, 4, ncols, f);
}
}
else if (bitcount == 16 || bitcount == 32) {
if (comp == BI_BITFIELDS) {
int bit;
ReadleLong(f, &bmask);
ReadleLong(f, &gmask);
ReadleLong(f, &rmask);
for (bit = bitcount - 1; bit >= 0; bit--) {
if (bmask & (1 << bit))
bshift = bit;
if (gmask & (1 << bit))
gshift = bit;
if (rmask & (1 << bit))
rshift = bit;
}
}
else if (bitcount == 16) {
rmask = 0x7C00;
gmask = 0x03E0;
bmask = 0x001F;
rshift = 10;
gshift = 5;
bshift = 0;
}
else if (bitcount == 32) {
rmask = 0x00FF0000;
gmask = 0x0000FF00;
bmask = 0x000000FF;
rshift = 16;
gshift = 8;
bshift = 0;
}
if (comp == BI_BITFIELDS) {
int bit;
ReadleLong(f, &bmask);
ReadleLong(f, &gmask);
ReadleLong(f, &rmask);
for (bit = bitcount - 1; bit >= 0; bit--) {
if (bmask & (1 << bit))
bshift = bit;
if (gmask & (1 << bit))
gshift = bit;
if (rmask & (1 << bit))
rshift = bit;
}
}
else if (bitcount == 16) {
rmask = 0x7C00;
gmask = 0x03E0;
bmask = 0x001F;
rshift = 10;
gshift = 5;
bshift = 0;
}
else if (bitcount == 32) {
rmask = 0x00FF0000;
gmask = 0x0000FF00;
bmask = 0x000000FF;
rshift = 16;
gshift = 8;
bshift = 0;
}
}
im->w = w;
im->h = h;
if (!im->format)
@ -187,387 +187,387 @@ load (ImlibImage *im, ImlibProgressFunction progress,
fseek(f, offset, SEEK_SET);
buffer = malloc(imgsize);
if (!buffer) {
fclose(f);
return 0;
fclose(f);
return 0;
}
im->data = malloc(w * h * sizeof(DATA32));
if (!im->data) {
fclose(f);
free(buffer);
return 0;
fclose(f);
free(buffer);
return 0;
}
fread(buffer, imgsize, 1, f);
fclose(f);
buffer_ptr = buffer;
buffer_end = buffer + imgsize;
data_end = im->data + w * h;
ptr = im->data + ((h - 1) * w);
if (bitcount == 4) {
if (comp == BI_RLE4) {
x = 0;
y = 0;
for (i = 0, g = 1; i < imgsize && g && buffer_ptr < buffer_end; i++) {
byte = *(buffer_ptr++);
if (byte) {
unsigned char t1, t2;
l = byte;
byte = *(buffer_ptr++);
t1 = byte & 0xF;
t2 = (byte >> 4) & 0xF;
for (j = 0; j < l; j++) {
k = (j & 1) ? t1 : t2;
if (x >= w)
break;
*ptr++ = 0xff000000 |
(rgbQuads[k].rgbRed << 16) |
(rgbQuads[k].rgbGreen << 8) |
rgbQuads[k].rgbBlue;
x++;
if (ptr > data_end)
ptr = data_end;
}
}
else {
byte = *(buffer_ptr++);
switch (byte) {
case 0:
x = 0;
y++;
ptr = im->data + ((h - y - 1)
* w * sizeof(DATA32));
if (ptr > data_end)
ptr = data_end;
break;
case 1:
g = 0;
break;
case 2:
x += *(buffer_ptr++);
y += *(buffer_ptr++);
ptr = im->data + ((h - y - 1) * w *
sizeof(DATA32)) + x;
if (ptr > data_end)
ptr = data_end;
break;
default:
l = byte;
for (j = 0; j < l; j++) {
char t1 = '\0', t2 = '\0';
if ((j & 1) == 0) {
byte = *(buffer_ptr++);
t1 = byte & 0xF;
t2 = (byte >> 4) & 0xF;
}
k = (j & 1) ? t1 : t2;
if (x >= w) {
buffer_ptr += (l - j) / 2;
break;
}
*ptr++ = 0xff000000 |
(rgbQuads[k].rgbRed << 16) |
(rgbQuads[k].rgbGreen << 8) |
rgbQuads[k].rgbBlue;
x++;
if (ptr > data_end)
ptr = data_end;
}
if ((l & 3) == 1) {
tempchar = *(buffer_ptr++);
tempchar = *(buffer_ptr++);
}
else if ((l & 3) == 2)
buffer_ptr++;
break;
}
}
if (progress) {
char per;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, im->h - y - 1, im->w, im->h - y + l))
{
free(buffer);
return 2;
}
pper = per;
pl = y;
}
}
}
}
else if (comp == BI_RGB) {
skip = ((((w + 7) / 8) * 8) - w) / 2;
for (y = 0; y < h; y++) {
for (x = 0; x < w && buffer_ptr < buffer_end; x++) {
if ((x & 1) == 0)
byte = *(buffer_ptr++);
k = (byte & 0xF0) >> 4;
*ptr++ = 0xff000000 |
(rgbQuads[k].rgbRed << 16) |
(rgbQuads[k].rgbGreen << 8) |
rgbQuads[k].rgbBlue;
byte <<= 4;
}
buffer_ptr += skip;
ptr -= w * 2;
if (progress) {
char per;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, im->h - y - 1, im->w, im->h - y + l))
{
free(buffer);
return 2;
}
pper = per;
pl = y;
}
}
}
}
if (comp == BI_RLE4) {
x = 0;
y = 0;
for (i = 0, g = 1; i < imgsize && g && buffer_ptr < buffer_end; i++) {
byte = *(buffer_ptr++);
if (byte) {
unsigned char t1, t2;
l = byte;
byte = *(buffer_ptr++);
t1 = byte & 0xF;
t2 = (byte >> 4) & 0xF;
for (j = 0; j < l; j++) {
k = (j & 1) ? t1 : t2;
if (x >= w)
break;
*ptr++ = 0xff000000 |
(rgbQuads[k].rgbRed << 16) |
(rgbQuads[k].rgbGreen << 8) |
rgbQuads[k].rgbBlue;
x++;
if (ptr > data_end)
ptr = data_end;
}
}
else {
byte = *(buffer_ptr++);
switch (byte) {
case 0:
x = 0;
y++;
ptr = im->data + ((h - y - 1)
* w * sizeof(DATA32));
if (ptr > data_end)
ptr = data_end;
break;
case 1:
g = 0;
break;
case 2:
x += *(buffer_ptr++);
y += *(buffer_ptr++);
ptr = im->data + ((h - y - 1) * w *
sizeof(DATA32)) + x;
if (ptr > data_end)
ptr = data_end;
break;
default:
l = byte;
for (j = 0; j < l; j++) {
char t1 = '\0', t2 = '\0';
if ((j & 1) == 0) {
byte = *(buffer_ptr++);
t1 = byte & 0xF;
t2 = (byte >> 4) & 0xF;
}
k = (j & 1) ? t1 : t2;
if (x >= w) {
buffer_ptr += (l - j) / 2;
break;
}
*ptr++ = 0xff000000 |
(rgbQuads[k].rgbRed << 16) |
(rgbQuads[k].rgbGreen << 8) |
rgbQuads[k].rgbBlue;
x++;
if (ptr > data_end)
ptr = data_end;
}
if ((l & 3) == 1) {
tempchar = *(buffer_ptr++);
tempchar = *(buffer_ptr++);
}
else if ((l & 3) == 2)
buffer_ptr++;
break;
}
}
if (progress) {
char per;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, im->h - y - 1, im->w, im->h - y + l))
{
free(buffer);
return 2;
}
pper = per;
pl = y;
}
}
}
}
else if (comp == BI_RGB) {
skip = ((((w + 7) / 8) * 8) - w) / 2;
for (y = 0; y < h; y++) {
for (x = 0; x < w && buffer_ptr < buffer_end; x++) {
if ((x & 1) == 0)
byte = *(buffer_ptr++);
k = (byte & 0xF0) >> 4;
*ptr++ = 0xff000000 |
(rgbQuads[k].rgbRed << 16) |
(rgbQuads[k].rgbGreen << 8) |
rgbQuads[k].rgbBlue;
byte <<= 4;
}
buffer_ptr += skip;
ptr -= w * 2;
if (progress) {
char per;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, im->h - y - 1, im->w, im->h - y + l))
{
free(buffer);
return 2;
}
pper = per;
pl = y;
}
}
}
}
}
if (bitcount == 8) {
if (comp == BI_RLE8) {
x = 0;
y = 0;
for (i = 0, g = 1; i < imgsize && buffer_ptr < buffer_end && g; i++) {
byte = *(buffer_ptr++);
if (byte) {
l = byte;
byte = *(buffer_ptr++);
for (j = 0; j < l; j++) {
if (x >= w)
break;
*ptr++ = 0xff000000 |
(rgbQuads[byte].rgbRed << 16) |
(rgbQuads[byte].rgbGreen << 8) |
rgbQuads[byte].rgbBlue;
x++;
if (ptr > data_end)
ptr = data_end;
}
}
else {
byte = *(buffer_ptr++);
switch (byte) {
case 0:
x = 0;
y++;
ptr = im->data + ((h - y - 1)
* w * sizeof(DATA32));
if (ptr > data_end)
ptr = data_end;
break;
case 1:
g = 0;
break;
case 2:
x += *(buffer_ptr++);
y += *(buffer_ptr++);
ptr = im->data + ((h - y - 1)
* w *
sizeof(DATA32)) + (x * sizeof(DATA32));
if (ptr > data_end)
ptr = data_end;
break;
default:
l = byte;
for (j = 0; j < l; j++) {
byte = *(buffer_ptr++);
if (x >= w) {
buffer_ptr += l - j;
break;
}
*ptr++ = 0xff000000 |
(rgbQuads[byte].rgbRed << 16) |
(rgbQuads[byte].rgbGreen << 8) |
rgbQuads[byte].rgbBlue;
x++;
if (ptr > data_end)
ptr = data_end;
}
if (l & 1)
buffer_ptr++;
break;
}
}
}
if (progress) {
char per;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, im->h - y - 1, im->w, im->h - y + l))
if (comp == BI_RLE8) {
x = 0;
y = 0;
for (i = 0, g = 1; i < imgsize && buffer_ptr < buffer_end && g; i++) {
byte = *(buffer_ptr++);
if (byte) {
l = byte;
byte = *(buffer_ptr++);
for (j = 0; j < l; j++) {
if (x >= w)
break;
*ptr++ = 0xff000000 |
(rgbQuads[byte].rgbRed << 16) |
(rgbQuads[byte].rgbGreen << 8) |
rgbQuads[byte].rgbBlue;
x++;
if (ptr > data_end)
ptr = data_end;
}
}
else {
byte = *(buffer_ptr++);
switch (byte) {
case 0:
x = 0;
y++;
ptr = im->data + ((h - y - 1)
* w * sizeof(DATA32));
if (ptr > data_end)
ptr = data_end;
break;
case 1:
g = 0;
break;
case 2:
x += *(buffer_ptr++);
y += *(buffer_ptr++);
ptr = im->data + ((h - y - 1)
* w *
sizeof(DATA32)) + (x * sizeof(DATA32));
if (ptr > data_end)
ptr = data_end;
break;
default:
l = byte;
for (j = 0; j < l; j++) {
byte = *(buffer_ptr++);
if (x >= w) {
buffer_ptr += l - j;
break;
}
*ptr++ = 0xff000000 |
(rgbQuads[byte].rgbRed << 16) |
(rgbQuads[byte].rgbGreen << 8) |
rgbQuads[byte].rgbBlue;
x++;
if (ptr > data_end)
ptr = data_end;
}
if (l & 1)
buffer_ptr++;
break;
}
}
}
if (progress) {
char per;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, im->h - y - 1, im->w, im->h - y + l))
{
free(buffer);
return 2;
free(buffer);
return 2;
}
pper = per;
pl = y;
}
}
}
else if (comp == BI_RGB) {
skip = (((w + 3) / 4) * 4) - w;
for (y = 0; y < h; y++) {
for (x = 0; x < w && buffer_ptr < buffer_end; x++) {
byte = *(buffer_ptr++);
*ptr++ = 0xff000000 |
(rgbQuads[byte].rgbRed << 16) |
(rgbQuads[byte].rgbGreen << 8) |
rgbQuads[byte].rgbBlue;
}
ptr -= w * 2;
buffer_ptr += skip;
if (progress) {
char per;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, im->h - y - 1, im->w, im->h - y + l))
{
free(buffer);
return 2;
}
pper = per;
pl = y;
}
}
}
}
pper = per;
pl = y;
}
}
}
else if (comp == BI_RGB) {
skip = (((w + 3) / 4) * 4) - w;
for (y = 0; y < h; y++) {
for (x = 0; x < w && buffer_ptr < buffer_end; x++) {
byte = *(buffer_ptr++);
*ptr++ = 0xff000000 |
(rgbQuads[byte].rgbRed << 16) |
(rgbQuads[byte].rgbGreen << 8) |
rgbQuads[byte].rgbBlue;
}
ptr -= w * 2;
buffer_ptr += skip;
if (progress) {
char per;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, im->h - y - 1, im->w, im->h - y + l))
{
free(buffer);
return 2;
}
pper = per;
pl = y;
}
}
}
}
}
else if (bitcount == 16) {
skip = (((w * 16 + 31) / 32) * 4) - (w * 2);
for (y = 0; y < h; y++) {
for (x = 0; x < w && buffer_ptr < buffer_end; x++) {
r = ((unsigned short)(*buffer_ptr) & rmask) >> rshift;
g = ((unsigned short)(*buffer_ptr) & gmask) >> gshift;
b = ((unsigned short)(*(buffer_ptr++)) & bmask) >> bshift;
*ptr++ = 0xff000000 | (r << 16) | (g << 8) | b;
}
ptr -= w * 2;
buffer_ptr += skip;
if (progress) {
char per;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, im->h - y - 1, im->w, im->h - y + l))
skip = (((w * 16 + 31) / 32) * 4) - (w * 2);
for (y = 0; y < h; y++) {
for (x = 0; x < w && buffer_ptr < buffer_end; x++) {
r = ((unsigned short)(*buffer_ptr) & rmask) >> rshift;
g = ((unsigned short)(*buffer_ptr) & gmask) >> gshift;
b = ((unsigned short)(*(buffer_ptr++)) & bmask) >> bshift;
*ptr++ = 0xff000000 | (r << 16) | (g << 8) | b;
}
ptr -= w * 2;
buffer_ptr += skip;
if (progress) {
char per;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, im->h - y - 1, im->w, im->h - y + l))
{
free(buffer);
return 2;
free(buffer);
return 2;
}
pper = per;
pl = y;
}
}
}
pper = per;
pl = y;
}
}
}
}
else if (bitcount == 24) {
skip = (4 - ((w * 3) % 4)) & 3;
for (y = 0; y < h; y++) {
for (x = 0; x < w && buffer_ptr < buffer_end; x++) {
b = *(buffer_ptr++);
g = *(buffer_ptr++);
r = *(buffer_ptr++);
*ptr++ = 0xff000000 | (r << 16) | (g << 8) | b;
}
ptr -= w * 2;
buffer_ptr += skip;
if (progress) {
char per;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, im->h - y - 1, im->w, im->h - y + l))
skip = (4 - ((w * 3) % 4)) & 3;
for (y = 0; y < h; y++) {
for (x = 0; x < w && buffer_ptr < buffer_end; x++) {
b = *(buffer_ptr++);
g = *(buffer_ptr++);
r = *(buffer_ptr++);
*ptr++ = 0xff000000 | (r << 16) | (g << 8) | b;
}
ptr -= w * 2;
buffer_ptr += skip;
if (progress) {
char per;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, im->h - y - 1, im->w, im->h - y + l))
{
free(buffer);
return 2;
free(buffer);
return 2;
}
pper = per;
pl = y;
}
}
}
pper = per;
pl = y;
}
}
}
}
else if (bitcount == 32) {
skip = (((w * 32 + 31) / 32) * 4) - (w * 4);
for (y = 0; y < h; y++) {
for (x = 0; x < w && buffer_ptr < buffer_end; x++) {
r = ((unsigned long)(*buffer_ptr) & rmask) >> rshift;
g = ((unsigned long)(*buffer_ptr) & gmask) >> gshift;
b = ((unsigned long)(*buffer_ptr) & bmask) >> bshift;
*ptr++ = 0xff000000 | (r << 16) | (g << 8) | b;
r = *(buffer_ptr++);
r = *(buffer_ptr++);
}
ptr -= w * 2;
buffer_ptr += skip;
if (progress) {
char per;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, im->h - y - 1, im->w, im->h - y + l))
skip = (((w * 32 + 31) / 32) * 4) - (w * 4);
for (y = 0; y < h; y++) {
for (x = 0; x < w && buffer_ptr < buffer_end; x++) {
r = ((unsigned long)(*buffer_ptr) & rmask) >> rshift;
g = ((unsigned long)(*buffer_ptr) & gmask) >> gshift;
b = ((unsigned long)(*buffer_ptr) & bmask) >> bshift;
*ptr++ = 0xff000000 | (r << 16) | (g << 8) | b;
r = *(buffer_ptr++);
r = *(buffer_ptr++);
}
ptr -= w * 2;
buffer_ptr += skip;
if (progress) {
char per;
int l;
per = (char)((100 * y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, im->h - y - 1, im->w, im->h - y + l))
{
free(buffer);
return 2;
free(buffer);
return 2;
}
pper = per;
pl = y;
}
}
}
pper = per;
pl = y;
}
}
}
}
free(buffer);
}
@ -578,8 +578,8 @@ char
save (ImlibImage *im, ImlibProgressFunction progress,
char progress_granularity)
{
/* TODO */
return 0;
/* TODO */
return 0;
}
void
@ -587,7 +587,7 @@ formats (ImlibLoader *l)
{
char *list_formats[] =
{ "bmp" };
{
int i;

File diff suppressed because it is too large Load Diff

View File

@ -75,66 +75,66 @@ put_separate_and_raster(TIFFRGBAImage* img, uint32* rast,
static void
raster(TIFFRGBAImage_Extra *img, uint32* rast,
uint32 x, uint32 y, uint32 w, uint32 h)
uint32 x, uint32 y, uint32 w, uint32 h)
{
uint32 image_width, image_height;
uint32 *pixel, pixel_value;
int i, j, dy, rast_offset;
DATA32 *buffer_pixel, *buffer = img->image->data;
image_width = img->image->w;
image_height = img->image->h;
uint32 image_width, image_height;
uint32 *pixel, pixel_value;
int i, j, dy, rast_offset;
DATA32 *buffer_pixel, *buffer = img->image->data;
image_width = img->image->w;
image_height = img->image->h;
dy = h > y ? -1 : y - h;
/* rast seems to point to the beginning of the last strip processed */
/* so you need use negative offsets. Bizzare. Someone please check this */
/* I don't understand why, but that seems to be what's going on. */
/* libtiff needs better docs! */
for (i = y, rast_offset = 0; i > dy; i--, rast_offset--)
{
pixel = rast + (rast_offset * image_width);
buffer_pixel = buffer + ((((image_height - 1) - i) * image_width) + x);
dy = h > y ? -1 : y - h;
for (j = 0; j < w; j++)
{
pixel_value = (*(pixel++));
(*(buffer_pixel++)) =
(TIFFGetA(pixel_value) << 24) |
(TIFFGetR(pixel_value) << 16) | (TIFFGetG(pixel_value) << 8) |
TIFFGetB(pixel_value);
}
}
if (img->progress)
{
char per;
uint32 real_y = (image_height - 1) - y;
/* rast seems to point to the beginning of the last strip processed */
/* so you need use negative offsets. Bizzare. Someone please check this */
/* I don't understand why, but that seems to be what's going on. */
/* libtiff needs better docs! */
for (i = y, rast_offset = 0; i > dy; i--, rast_offset--)
{
pixel = rast + (rast_offset * image_width);
buffer_pixel = buffer + ((((image_height - 1) - i) * image_width) + x);
for (j = 0; j < w; j++)
{
pixel_value = (*(pixel++));
(*(buffer_pixel++)) =
(TIFFGetA(pixel_value) << 24) |
(TIFFGetR(pixel_value) << 16) | (TIFFGetG(pixel_value) << 8) |
TIFFGetB(pixel_value);
}
}
if (img->progress)
{
char per;
uint32 real_y = (image_height - 1) - y;
if (w >= image_width)
{
per = (char)(((real_y + h - 1) * 100)/image_height);
if (((per - img->pper) >= img->progress_granularity) ||
(real_y + h) >= image_height)
{
(*img->progress)(img->image, per, 0, img->py, w,
(real_y + h) - img->py);
img->py = real_y + h;
img->pper = per;
}
}
else
{
/* for tile based images, we just progress each tile because */
/* of laziness. Couldn't think of a good way to do this */
per = (char)((w * h * 100) / img->num_pixels);
img->pper += per;
(*img->progress)(img->image, img->pper, x,
(image_height - 1) - y, w, h);
}
}
if (w >= image_width)
{
per = (char)(((real_y + h - 1) * 100)/image_height);
if (((per - img->pper) >= img->progress_granularity) ||
(real_y + h) >= image_height)
{
(*img->progress)(img->image, per, 0, img->py, w,
(real_y + h) - img->py);
img->py = real_y + h;
img->pper = per;
}
}
else
{
/* for tile based images, we just progress each tile because */
/* of laziness. Couldn't think of a good way to do this */
per = (char)((w * h * 100) / img->num_pixels);
img->pper += per;
(*img->progress)(img->image, img->pper, x,
(image_height - 1) - y, w, h);
}
}
}
@ -142,131 +142,131 @@ char
load (ImlibImage *im, ImlibProgressFunction progress,
char progress_granularity, char immediate_load)
{
TIFF *tif = NULL;
FILE *file;
int fd;
uint16 magic_number;
TIFFRGBAImage_Extra rgba_image;
uint32 *rast = NULL;
uint32 width, height, num_pixels;
if (im->data)
return 0;
file = fopen(im->file, "rb");
if (!file)
return 0;
fread(&magic_number, sizeof(uint16), 1, file);
rewind(file);
if ((magic_number != TIFF_BIGENDIAN) /* Checks if actually tiff file */
&& (magic_number != TIFF_LITTLEENDIAN))
{
fclose(file);
return 0;
}
fd = fileno(file);
fd = dup(fd);
TIFF *tif = NULL;
FILE *file;
int fd;
uint16 magic_number;
TIFFRGBAImage_Extra rgba_image;
uint32 *rast = NULL;
uint32 width, height, num_pixels;
if (im->data)
return 0;
file = fopen(im->file, "rb");
if (!file)
return 0;
fread(&magic_number, sizeof(uint16), 1, file);
rewind(file);
if ((magic_number != TIFF_BIGENDIAN) /* Checks if actually tiff file */
&& (magic_number != TIFF_LITTLEENDIAN))
{
fclose(file);
tif = TIFFFdOpen(fd, im->file, "r");
if (!tif)
return 0;
if ((!TIFFRGBAImageOK(tif, "Cannot be processed by libtiff"))
|| (!TIFFRGBAImageBegin((TIFFRGBAImage *) &rgba_image, tif, 0,
"Error reading tiff")))
{
TIFFClose(tif);
return 0;
}
rgba_image.image = im;
im->w = width = rgba_image.rgba.width;
im->h = height = rgba_image.rgba.height;
rgba_image.num_pixels = num_pixels = width * height;
if (rgba_image.rgba.alpha != EXTRASAMPLE_UNSPECIFIED)
SET_FLAG(im->flags, F_HAS_ALPHA);
else
UNSET_FLAG(im->flags, F_HAS_ALPHA);
if (!im->format)
im->format = strdup("tiff");
if ((im->loader) || (immediate_load) || (progress))
{
rgba_image.progress = progress;
rgba_image.pper = rgba_image.py = 0;
rgba_image.progress_granularity = progress_granularity;
rast = (uint32 *) _TIFFmalloc(sizeof(uint32) * num_pixels);
im->data = (DATA32 *) malloc(sizeof(DATA32) * num_pixels);
if ((!rast) || (!im->data)) /* Error checking */
{
fprintf(stderr, "imlib2-tiffloader: Out of memory\n");
if (!rast)
_TIFFfree(rast);
if (!im->data)
{
free(im->data);
im->data = NULL;
}
TIFFRGBAImageEnd((TIFFRGBAImage *) &rgba_image);
TIFFClose(tif);
return 0;
}
if (rgba_image.rgba.put.any == NULL)
{
fprintf(stderr, "imlib2-tiffloader: No put function");
_TIFFfree(rast);
free(im->data);
im->data = NULL;
TIFFRGBAImageEnd((TIFFRGBAImage *) &rgba_image);
TIFFClose(tif);
return 0;
}
else
{
if (rgba_image.rgba.isContig)
{
rgba_image.put_contig = rgba_image.rgba.put.contig;
rgba_image.rgba.put.contig = put_contig_and_raster;
}
else
{
rgba_image.put_separate = rgba_image.rgba.put.separate;
rgba_image.rgba.put.separate = put_separate_and_raster;
}
}
if (!TIFFRGBAImageGet((TIFFRGBAImage *) &rgba_image,
rast, width, height))
{
_TIFFfree(rast);
free(im->data);
im->data = NULL;
TIFFRGBAImageEnd((TIFFRGBAImage *) &rgba_image);
TIFFClose(tif);
return 0;
}
_TIFFfree(rast);
}
TIFFRGBAImageEnd((TIFFRGBAImage *) &rgba_image);
return 0;
}
fd = fileno(file);
fd = dup(fd);
fclose(file);
tif = TIFFFdOpen(fd, im->file, "r");
if (!tif)
return 0;
if ((!TIFFRGBAImageOK(tif, "Cannot be processed by libtiff"))
|| (!TIFFRGBAImageBegin((TIFFRGBAImage *) &rgba_image, tif, 0,
"Error reading tiff")))
{
TIFFClose(tif);
return 1;
return 0;
}
rgba_image.image = im;
im->w = width = rgba_image.rgba.width;
im->h = height = rgba_image.rgba.height;
rgba_image.num_pixels = num_pixels = width * height;
if (rgba_image.rgba.alpha != EXTRASAMPLE_UNSPECIFIED)
SET_FLAG(im->flags, F_HAS_ALPHA);
else
UNSET_FLAG(im->flags, F_HAS_ALPHA);
if (!im->format)
im->format = strdup("tiff");
if ((im->loader) || (immediate_load) || (progress))
{
rgba_image.progress = progress;
rgba_image.pper = rgba_image.py = 0;
rgba_image.progress_granularity = progress_granularity;
rast = (uint32 *) _TIFFmalloc(sizeof(uint32) * num_pixels);
im->data = (DATA32 *) malloc(sizeof(DATA32) * num_pixels);
if ((!rast) || (!im->data)) /* Error checking */
{
fprintf(stderr, "imlib2-tiffloader: Out of memory\n");
if (!rast)
_TIFFfree(rast);
if (!im->data)
{
free(im->data);
im->data = NULL;
}
TIFFRGBAImageEnd((TIFFRGBAImage *) &rgba_image);
TIFFClose(tif);
return 0;
}
if (rgba_image.rgba.put.any == NULL)
{
fprintf(stderr, "imlib2-tiffloader: No put function");
_TIFFfree(rast);
free(im->data);
im->data = NULL;
TIFFRGBAImageEnd((TIFFRGBAImage *) &rgba_image);
TIFFClose(tif);
return 0;
}
else
{
if (rgba_image.rgba.isContig)
{
rgba_image.put_contig = rgba_image.rgba.put.contig;
rgba_image.rgba.put.contig = put_contig_and_raster;
}
else
{
rgba_image.put_separate = rgba_image.rgba.put.separate;
rgba_image.rgba.put.separate = put_separate_and_raster;
}
}
if (!TIFFRGBAImageGet((TIFFRGBAImage *) &rgba_image,
rast, width, height))
{
_TIFFfree(rast);
free(im->data);
im->data = NULL;
TIFFRGBAImageEnd((TIFFRGBAImage *) &rgba_image);
TIFFClose(tif);
return 0;
}
_TIFFfree(rast);
}
TIFFRGBAImageEnd((TIFFRGBAImage *) &rgba_image);
TIFFClose(tif);
return 1;
}
/* this seems to work, except the magic number isn't written. I'm guessing */
@ -276,109 +276,109 @@ char
save (ImlibImage *im, ImlibProgressFunction progress,
char progress_granularity)
{
TIFF *tif = NULL;
uint8 *buf = NULL;
DATA32 pixel, *data = im->data;
double alpha_factor;
uint32 x, y;
uint8 r, g, b, a;
int has_alpha = IMAGE_HAS_ALPHA(im);
int i = 0, pl = 0;
char pper = 0;
if (!im->data)
return 0;
tif = TIFFOpen(im->file, "w");
if (!tif)
return 0;
/* None of the TIFFSetFields are checked for errors, but since they */
/* shouldn't fail, this shouldn't be a problem */
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->h);
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, im->w);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
if (has_alpha)
{
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4);
TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, EXTRASAMPLE_ASSOCALPHA);
}
else
{
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
}
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, 0));
buf = (uint8 *) _TIFFmalloc(TIFFScanlineSize(tif));
if (!buf)
{
TIFFClose(tif);
return 0;
}
for (y = 0; y < im->h; y++)
{
i = 0;
for (x = 0; x < im->w; x++)
{
pixel = data[(y * im->w) + x];
r = (pixel >> 16) & 0xff;
g = (pixel >> 8) & 0xff;
b = pixel & 0xff;
if (has_alpha)
{
/* TIFF makes you pre-mutiply the rgb components by alpha */
a = (pixel >> 24) & 0xff;
alpha_factor = ((double) a / 255.0);
r *= alpha_factor;
g *= alpha_factor;
b *= alpha_factor;
}
/* This might be endian dependent */
buf[i++] = r;
buf[i++] = g;
buf[i++] = b;
if (has_alpha)
buf[i++] = a;
}
if (!TIFFWriteScanline(tif, buf, y, 0))
{
_TIFFfree(buf);
TIFFClose(tif);
return 0;
}
if (progress)
{
char per;
int l;
per = (char)((100 * y) / im->h);
if ((per - pper) >= progress_granularity)
{
l = y - pl;
(*progress)(im, per, 0, (y - l), im->w, l);
pper = per;
pl = y;
}
}
}
_TIFFfree(buf);
TIFF *tif = NULL;
uint8 *buf = NULL;
DATA32 pixel, *data = im->data;
double alpha_factor;
uint32 x, y;
uint8 r, g, b, a;
int has_alpha = IMAGE_HAS_ALPHA(im);
int i = 0, pl = 0;
char pper = 0;
if (!im->data)
return 0;
tif = TIFFOpen(im->file, "w");
if (!tif)
return 0;
/* None of the TIFFSetFields are checked for errors, but since they */
/* shouldn't fail, this shouldn't be a problem */
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->h);
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, im->w);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
if (has_alpha)
{
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4);
TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, EXTRASAMPLE_ASSOCALPHA);
}
else
{
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
}
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, 0));
buf = (uint8 *) _TIFFmalloc(TIFFScanlineSize(tif));
if (!buf)
{
TIFFClose(tif);
return 1;
return 0;
}
for (y = 0; y < im->h; y++)
{
i = 0;
for (x = 0; x < im->w; x++)
{
pixel = data[(y * im->w) + x];
r = (pixel >> 16) & 0xff;
g = (pixel >> 8) & 0xff;
b = pixel & 0xff;
if (has_alpha)
{
/* TIFF makes you pre-mutiply the rgb components by alpha */
a = (pixel >> 24) & 0xff;
alpha_factor = ((double) a / 255.0);
r *= alpha_factor;
g *= alpha_factor;
b *= alpha_factor;
}
/* This might be endian dependent */
buf[i++] = r;
buf[i++] = g;
buf[i++] = b;
if (has_alpha)
buf[i++] = a;
}
if (!TIFFWriteScanline(tif, buf, y, 0))
{
_TIFFfree(buf);
TIFFClose(tif);
return 0;
}
if (progress)
{
char per;
int l;
per = (char)((100 * y) / im->h);
if ((per - pper) >= progress_granularity)
{
l = y - pl;
(*progress)(im, per, 0, (y - l), im->w, l);
pper = per;
pl = y;
}
}
}
_TIFFfree(buf);
TIFFClose(tif);
return 1;
}
/* fills the ImlibLoader struct with a strign array of format file */
@ -394,7 +394,7 @@ formats (ImlibLoader *l)
/* this is the only bit you have to change... */
char *list_formats[] =
{ "tiff", "tif" };
/* don't bother changing any of this - it just reads this in and sets */
/* the struct values and makes copies */
{

View File

@ -47,11 +47,11 @@ xpm_parse_color(char *color, int *r, int *g, int *b)
val[i] = 0;
sscanf(val, "%x", b);
if (len == 1)
{
*r = (*r << 4) | *r;
*g = (*g << 4) | *g;
*b = (*b << 4) | *b;
}
{
*r = (*r << 4) | *r;
*g = (*g << 4) | *g;
*b = (*b << 4) | *b;
}
else if (len > 2)
{
*r >>= (len - 2) * 4;
@ -97,38 +97,38 @@ xpm_parse_done(void)
char
load(ImlibImage *im, ImlibProgressFunction progress, char progress_granularity, char immediate_load)
{
DATA32 *ptr, *end;
FILE *f;
int pc, c, i, j, k, w, h, ncolors, cpp, comment, transp, quote,
context, len, done, r, g, b;
char *line, s[256], tok[128], col[256];
XColor xcol;
int lsz = 256;
struct _cmap
{
unsigned char str[6];
unsigned char transp;
short r, g, b;
} *cmap;
short lookup[128 - 32][128 - 32];
float per = 0.0, per_inc;
int last_per = 0, last_y = 0;
done = 0;
transp = -1;
/* if immediate_load is 1, then dont delay image laoding as below, or */
/* already data in this image - dont load it again */
if (im->data)
DATA32 *ptr, *end;
FILE *f;
int pc, c, i, j, k, w, h, ncolors, cpp, comment, transp, quote,
context, len, done, r, g, b;
char *line, s[256], tok[128], col[256];
XColor xcol;
int lsz = 256;
struct _cmap
{
unsigned char str[6];
unsigned char transp;
short r, g, b;
} *cmap;
short lookup[128 - 32][128 - 32];
float per = 0.0, per_inc;
int last_per = 0, last_y = 0;
done = 0;
transp = -1;
/* if immediate_load is 1, then dont delay image laoding as below, or */
/* already data in this image - dont load it again */
if (im->data)
{
xpm_parse_done();
return 0;
}
f = fopen(im->file, "rb");
if (!f)
f = fopen(im->file, "rb");
if (!f)
{
xpm_parse_done();
return 0;
@ -138,394 +138,403 @@ load(ImlibImage *im, ImlibProgressFunction progress, char progress_granularity,
s[9] = 0;
if (strcmp("/* XPM */", s))
{
fclose(f);
xpm_parse_done();
return 0;
}
i = 0;
j = 0;
cmap = NULL;
w = 10;
h = 10;
ptr = NULL;
end = NULL;
c = ' ';
comment = 0;
quote = 0;
context = 0;
line = malloc(lsz);
while (!done)
{
pc = c;
c = fgetc(f);
if (c == EOF)
break;
if (!quote)
{
if ((pc == '/') && (c == '*'))
comment = 1;
else if ((pc == '*') && (c == '/') && (comment))
comment = 0;
}
if (!comment)
{
if ((!quote) && (c == '"'))
{
quote = 1;
i = 0;
}
else if ((quote) && (c == '"'))
{
line[i] = 0;
quote = 0;
if (context == 0)
{
/* Header */
sscanf(line, "%i %i %i %i", &w, &h, &ncolors, &cpp);
if (ncolors > 32766)
i = 0;
j = 0;
cmap = NULL;
w = 10;
h = 10;
ptr = NULL;
end = NULL;
c = ' ';
comment = 0;
quote = 0;
context = 0;
line = malloc(lsz);
while (!done)
{
pc = c;
c = fgetc(f);
if (c == EOF)
break;
if (!quote)
{
if ((pc == '/') && (c == '*'))
comment = 1;
else if ((pc == '*') && (c == '/') && (comment))
comment = 0;
}
if (!comment)
{
if ((!quote) && (c == '"'))
{
quote = 1;
i = 0;
}
else if ((quote) && (c == '"'))
{
line[i] = 0;
quote = 0;
if (context == 0)
{
fprintf(stderr, "IMLIB ERROR: XPM files with colors > 32766 not supported\n");
free(line);
fclose(f);
xpm_parse_done();
return 0;
/* Header */
sscanf(line, "%i %i %i %i", &w, &h, &ncolors, &cpp);
if (ncolors > 32766)
{
fprintf(stderr, "IMLIB ERROR: XPM files with colors > 32766 not supported\n");
free(line);
fclose(f);
xpm_parse_done();
return 0;
}
if (cpp > 5)
{
fprintf(stderr, "IMLIB ERROR: XPM files with characters per pixel > 5 not supported\n");
free(line);
fclose(f);
xpm_parse_done();
return 0;
}
if (w > 32767)
{
fprintf(stderr, "IMLIB ERROR: Image width > 32767 pixels for file\n");
free(line);
fclose(f);
xpm_parse_done();
return 0;
}
if (h > 32767)
{
fprintf(stderr, "IMLIB ERROR: Image height > 32767 pixels for file\n");
free(line);
fclose(f);
xpm_parse_done();
return 0;
}
im->w = w;
im->h = h;
if (!im->format)
im->format = strdup("xpm");
cmap = malloc(sizeof(struct _cmap) * ncolors);
if (!cmap)
{
free(line);
fclose(f);
xpm_parse_done();
return 0;
}
per_inc = 100.0 / (((float) w) * h);
j = 0;
context++;
}
if (cpp > 5)
else if (context == 1)
{
fprintf(stderr, "IMLIB ERROR: XPM files with characters per pixel > 5 not supported\n");
free(line);
fclose(f);
xpm_parse_done();
return 0;
}
if (w > 32767)
{
fprintf(stderr, "IMLIB ERROR: Image width > 32767 pixels for file\n");
free(line);
fclose(f);
xpm_parse_done();
return 0;
}
if (h > 32767)
{
fprintf(stderr, "IMLIB ERROR: Image height > 32767 pixels for file\n");
free(line);
fclose(f);
xpm_parse_done();
return 0;
}
cmap = malloc(sizeof(struct _cmap) * ncolors);
if (!cmap)
{
free(line);
fclose(f);
xpm_parse_done();
return 0;
}
im->w = w;
im->h = h;
if (!im->format)
im->format = strdup("xpm");
per_inc = 100.0 / (((float) w) * h);
if (im->loader || immediate_load || progress)
{
im->data = (DATA32 *) malloc(sizeof(DATA32) * w * h);
if (!im->data)
{
free(cmap);
free(line);
fclose(f);
xpm_parse_done();
return 0;
}
ptr = im->data;
end = ptr + (sizeof(DATA32) * w * h);
}
j = 0;
context++;
}
else if (context == 1)
{
/* Color Table */
if (j < ncolors)
{
int slen;
int hascolor, iscolor;
iscolor = 0;
hascolor = 0;
tok[0] = 0;
col[0] = 0;
s[0] = 0;
len = strlen(line);
strncpy(cmap[j].str, line, cpp);
cmap[j].str[cpp] = 0;
cmap[j].r = -1;
cmap[j].transp = 0;
for (k = cpp; k < len; k++)
{
if (line[k] != ' ')
{
s[0] = 0;
sscanf(&line[k], "%65535s", s);
slen = strlen(s);
k += slen;
if (!strcmp(s, "c"))
iscolor = 1;
if ((!strcmp(s, "m")) || (!strcmp(s, "s")) ||
(!strcmp(s, "g4")) || (!strcmp(s, "g")) ||
(!strcmp(s, "c")) || (k >= len))
{
if (k >= len)
{
if (col[0])
strcat(col, " ");
if (strlen(col) + strlen(s) < sizeof(col))
strcat(col, s);
}
if (col[0])
{
if (!strcasecmp(col, "none"))
/* Color Table */
if (j < ncolors)
{
int slen;
int hascolor, iscolor;
iscolor = 0;
hascolor = 0;
tok[0] = 0;
col[0] = 0;
s[0] = 0;
len = strlen(line);
strncpy(cmap[j].str, line, cpp);
cmap[j].str[cpp] = 0;
cmap[j].r = -1;
cmap[j].transp = 0;
for (k = cpp; k < len; k++)
{
if (line[k] != ' ')
{
s[0] = 0;
sscanf(&line[k], "%65535s", s);
slen = strlen(s);
k += slen;
if (!strcmp(s, "c"))
iscolor = 1;
if ((!strcmp(s, "m")) || (!strcmp(s, "s")) ||
(!strcmp(s, "g4")) || (!strcmp(s, "g")) ||
(!strcmp(s, "c")) || (k >= len))
{
transp = 1;
cmap[j].transp = 1;
if (k >= len)
{
if (col[0])
strcat(col, " ");
if (strlen(col) + strlen(s) < sizeof(col))
strcat(col, s);
}
if (col[0])
{
if (!strcasecmp(col, "none"))
{
transp = 1;
cmap[j].transp = 1;
}
else
{
if ((((cmap[j].r < 0) ||
(!strcmp(tok, "c"))) &&
(!hascolor)))
{
r = 0; g = 0; b = 0;
xpm_parse_color(col, &r, &g, &b);
cmap[j].r = r;
cmap[j].g = g;
cmap[j].b = b;
if (iscolor)
hascolor = 1;
}
}
}
strcpy(tok, s);
col[0] = 0;
}
else
{
if ((((cmap[j].r < 0) ||
(!strcmp(tok, "c"))) &&
(!hascolor)))
{
r = 0; g = 0; b = 0;
xpm_parse_color(col, &r, &g, &b);
cmap[j].r = r;
cmap[j].g = g;
cmap[j].b = b;
if (iscolor)
hascolor = 1;
}
if (col[0])
strcat(col, " ");
strcat(col, s);
}
}
strcpy(tok, s);
col[0] = 0;
}
else
{
if (col[0])
strcat(col, " ");
strcat(col, s);
}
}
}
}
j++;
if (j >= ncolors)
{
if (cpp == 1)
for (i = 0; i < ncolors; i++)
lookup[(int)cmap[i].str[0] - 32][0] = i;
if (cpp == 2)
for (i = 0; i < ncolors; i++)
lookup[(int)cmap[i].str[0] - 32][(int)cmap[i].str[1] - 32] = i;
context++;
}
}
else
{
/* Image Data */
i = 0;
if (cpp == 0)
{
/* Chars per pixel = 0? well u never know */
}
if (cpp == 1)
{
if (transp)
{
for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++)
{
col[0] = line[i];
if (cmap[lookup[(int)col[0] - 32][0]].transp)
{
r = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].r;
g = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].g;
b = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].b;
*ptr++ = 0x00ffffff & ((r << 16) | (g << 8) | b);
}
else
{
r = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].r;
g = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].g;
b = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].b;
*ptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
}
}
}
else
{
for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++)
{
col[0] = line[i];
r = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].r;
g = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].g;
b = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].b;
*ptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
}
}
}
else if (cpp == 2)
{
if (transp)
{
for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++)
{
col[0] = line[i++];
col[1] = line[i];
if (cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].transp)
{
r = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].r;
g = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].g;
b = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].b;
*ptr++ = 0x00ffffff & ((r << 16) | (g << 8) | b);
}
else
{
r = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].r;
g = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].g;
b = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].b;
*ptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
}
}
}
else
{
for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++)
{
col[0] = line[i++];
col[1] = line[i];
r = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].r;
g = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].g;
b = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].b;
*ptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
}
}
}
}
}
j++;
if (j >= ncolors)
{
if (cpp == 1)
for (i = 0; i < ncolors; i++)
lookup[(int)cmap[i].str[0] - 32][0] = i;
if (cpp == 2)
for (i = 0; i < ncolors; i++)
lookup[(int)cmap[i].str[0] - 32][(int)cmap[i].str[1] - 32] = i;
context++;
}
if (transp >= 0) {
SET_FLAG(im->flags, F_HAS_ALPHA);
} else {
UNSET_FLAG(im->flags, F_HAS_ALPHA);
}
if (im->loader || immediate_load || progress)
{
im->data = (DATA32 *) malloc(sizeof(DATA32) * im->w * im->h);
if (!im->data)
{
free(cmap);
free(line);
fclose(f);
xpm_parse_done();
return 0;
}
ptr = im->data;
end = ptr + (sizeof(DATA32) * w * h);
}
else
{
free(cmap);
free(line);
fclose(f);
xpm_parse_done();
return 1;
}
}
else
{
if (transp)
{
for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++)
{
for (j = 0; j < cpp; j++, i++)
{
col[j] = line[i];
}
col[j] = 0;
i--;
for (j = 0; j < ncolors; j++)
{
if (!strcmp(col, cmap[j].str))
{
if (cmap[j].transp)
/* Image Data */
i = 0;
if (cpp == 0)
{
/* Chars per pixel = 0? well u never know */
}
if (cpp == 1)
{
if (transp)
{
for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++)
{
col[0] = line[i];
if (cmap[lookup[(int)col[0] - 32][0]].transp)
{
r = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].r;
g = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].g;
b = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].b;
*ptr++ = 0x00ffffff & ((r << 16) | (g << 8) | b);
r = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].r;
g = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].g;
b = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].b;
*ptr++ = 0x00ffffff & ((r << 16) | (g << 8) | b);
}
else
{
r = (unsigned char)cmap[j].r;
g = (unsigned char)cmap[j].g;
b = (unsigned char)cmap[j].b;
*ptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
r = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].r;
g = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].g;
b = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].b;
*ptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
}
j = ncolors;
}
}
}
}
else
{
for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++)
{
for (j = 0; j < cpp; j++, i++)
{
col[j] = line[i];
}
col[j] = 0;
i--;
for (j = 0; j < ncolors; j++)
{
if (!strcmp(col, cmap[j].str))
{
r = (unsigned char)cmap[j].r;
g = (unsigned char)cmap[j].g;
b = (unsigned char)cmap[j].b;
}
}
else
{
for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++)
{
col[0] = line[i];
r = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].r;
g = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].g;
b = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].b;
*ptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
j = ncolors;
}
}
}
}
}
}
}
else if (cpp == 2)
{
if (transp)
{
for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++)
{
col[0] = line[i++];
col[1] = line[i];
if (cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].transp)
{
r = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].r;
g = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].g;
b = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].b;
*ptr++ = 0x00ffffff & ((r << 16) | (g << 8) | b);
}
else
{
r = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].r;
g = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].g;
b = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].b;
*ptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
}
}
}
else
{
for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++)
{
col[0] = line[i++];
col[1] = line[i];
r = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].r;
g = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].g;
b = (unsigned char)cmap[lookup[(int)col[0] - 32][(int)col[1] - 32]].b;
*ptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
}
}
}
else
{
if (transp)
{
for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++)
{
for (j = 0; j < cpp; j++, i++)
{
col[j] = line[i];
}
col[j] = 0;
i--;
for (j = 0; j < ncolors; j++)
{
if (!strcmp(col, cmap[j].str))
{
if (cmap[j].transp)
{
r = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].r;
g = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].g;
b = (unsigned char)cmap[lookup[(int)col[0] - 32][0]].b;
*ptr++ = 0x00ffffff & ((r << 16) | (g << 8) | b);
}
else
{
r = (unsigned char)cmap[j].r;
g = (unsigned char)cmap[j].g;
b = (unsigned char)cmap[j].b;
*ptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
}
j = ncolors;
}
}
}
}
else
{
for (i = 0; ((i < 65536) && (ptr < end) && (line[i])); i++)
{
for (j = 0; j < cpp; j++, i++)
{
col[j] = line[i];
}
col[j] = 0;
i--;
for (j = 0; j < ncolors; j++)
{
if (!strcmp(col, cmap[j].str))
{
r = (unsigned char)cmap[j].r;
g = (unsigned char)cmap[j].g;
b = (unsigned char)cmap[j].b;
*ptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
j = ncolors;
}
}
}
}
}
per += per_inc;
if (progress && (((int) per) != last_per) && (((int) per) % progress_granularity == 0))
{
last_per = (int) per;
if (!(progress(im, (int) per, 0, last_y, w, i)))
{
fclose(f);
free(cmap);
free(line);
xpm_parse_done();
return 2;
}
last_y = i;
}
}
per += per_inc;
if (progress && (((int) per) != last_per) && (((int) per) % progress_granularity == 0))
{
last_per = (int) per;
if (!(progress(im, (int) per, 0, last_y, w, i)))
{
fclose(f);
free(cmap);
free(line);
xpm_parse_done();
return 2;
}
last_y = i;
}
}
}
}
/* Scan in line from XPM file */
if ((!comment) && (quote) && (c != '"'))
{
if (c < 32)
c = 32;
else if (c > 127)
c = 127;
line[i++] = c;
}
if (i >= lsz)
{
lsz += 256;
line = realloc(line, lsz);
}
if ((ptr) && ((ptr - im->data) >= w * h * sizeof(DATA32)))
done = 1;
}
if (transp >= 0) {
SET_FLAG(im->flags, F_HAS_ALPHA);
} else {
UNSET_FLAG(im->flags, F_HAS_ALPHA);
}
if (progress)
{
progress(im, 100, 0, last_y, w, h);
}
free(cmap);
free(line);
}
}
/* Scan in line from XPM file */
if ((!comment) && (quote) && (c != '"'))
{
if (c < 32)
c = 32;
else if (c > 127)
c = 127;
line[i++] = c;
}
if (i >= lsz)
{
lsz += 256;
line = realloc(line, lsz);
}
if ((ptr) && ((ptr - im->data) >= w * h * sizeof(DATA32)))
done = 1;
}
if (progress)
{
progress(im, 100, 0, last_y, w, h);
}
free(cmap);
free(line);
xpm_parse_done();
return 1;
return 1;
}
char
@ -550,7 +559,7 @@ formats (ImlibLoader *l)
/* this is the only bit you have to change... */
char *list_formats[] =
{ "xpm" };
/* don't bother changing any of this - it just reads this in and sets */
/* the struct values and makes copies */
{