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];
unsigned char b[2];
if (fread(b, sizeof(unsigned char), 2, file) != 2)
return 0;
if (fread(b, sizeof(unsigned char), 2, file) != 2)
return 0;
*ret = (b[1] << 8) | b[0];
return 1;
*ret = (b[1] << 8) | b[0];
return 1;
}
int ReadleLong(FILE *file, unsigned long *ret)
{
unsigned char b[4];
unsigned char b[4];
if (fread(b, sizeof(unsigned char), 4, file) != 4)
return 0;
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;
*ret = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
return 1;
}
char
@ -86,92 +86,92 @@ load (ImlibImage *im, ImlibProgressFunction progress,
{
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;
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);
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;
@ -187,14 +187,14 @@ 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);
@ -206,368 +206,368 @@ load (ImlibImage *im, ImlibProgressFunction progress,
ptr = im->data + ((h - 1) * w);
if (bitcount == 4) {
if (comp == BI_RLE4) {
x = 0;
y = 0;
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;
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;
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;
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';
*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 ((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;
}
if (x >= w) {
buffer_ptr += (l - j) / 2;
break;
}
*ptr++ = 0xff000000 |
(rgbQuads[k].rgbRed << 16) |
(rgbQuads[k].rgbGreen << 8) |
rgbQuads[k].rgbBlue;
x++;
*ptr++ = 0xff000000 |
(rgbQuads[k].rgbRed << 16) |
(rgbQuads[k].rgbGreen << 8) |
rgbQuads[k].rgbBlue;
x++;
if (ptr > data_end)
ptr = data_end;
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;
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;
}
}
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;
}
}
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;
}
}
}
}
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;
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;
*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++);
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;
}
if (x >= w) {
buffer_ptr += l - j;
break;
}
*ptr++ = 0xff000000 |
(rgbQuads[byte].rgbRed << 16) |
(rgbQuads[byte].rgbGreen << 8) |
rgbQuads[byte].rgbBlue;
x++;
*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;
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))
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;
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;
}
}
}
}
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;
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))
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;
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))
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;
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))
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

View File

@ -11,7 +11,7 @@
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
# include <config.h>
#endif
#include "common.h"
@ -50,26 +50,26 @@ static DATA32* flip(DATA32* in, int w, int h);
#define TGA_SIGNATURE "TRUEVISION-XFILE"
typedef struct {
unsigned char idLength;
unsigned char colorMapType;
unsigned char imageType;
unsigned char colorMapIndexLo, colorMapIndexHi;
unsigned char colorMapLengthLo, colorMapLengthHi;
unsigned char colorMapSize;
unsigned char xOriginLo, xOriginHi;
unsigned char yOriginLo, yOriginHi;
unsigned char widthLo, widthHi;
unsigned char heightLo, heightHi;
unsigned char bpp;
unsigned char descriptor;
unsigned char idLength;
unsigned char colorMapType;
unsigned char imageType;
unsigned char colorMapIndexLo, colorMapIndexHi;
unsigned char colorMapLengthLo, colorMapLengthHi;
unsigned char colorMapSize;
unsigned char xOriginLo, xOriginHi;
unsigned char yOriginLo, yOriginHi;
unsigned char widthLo, widthHi;
unsigned char heightLo, heightHi;
unsigned char bpp;
unsigned char descriptor;
} tga_header;
typedef struct {
unsigned int extensionAreaOffset;
unsigned int developerDirectoryOffset;
char signature[16];
char dot;
char null;
unsigned int extensionAreaOffset;
unsigned int developerDirectoryOffset;
char signature[16];
char dot;
char null;
} tga_footer;
@ -82,84 +82,84 @@ char
save (ImlibImage *im, ImlibProgressFunction progress,
char progress_granularity)
{
FILE *f;
DATA32 *dataptr;
unsigned char *buf, *bufptr;
int y, pl = 0;
char pper = 0;
FILE *f;
DATA32 *dataptr;
unsigned char *buf, *bufptr;
int y, pl = 0;
char pper = 0;
tga_header header;
tga_header header;
if(!im->data)
return 0;
if(!im->data)
return 0;
f = fopen(im->file, "wb");
if(!f)
return 0;
f = fopen(im->file, "wb");
if(!f)
return 0;
/* assemble the TGA header information */
/* assemble the TGA header information */
/* most entries are zero... */
memset(&header, 0x0, sizeof(header));
/* most entries are zero... */
memset(&header, 0x0, sizeof(header));
/* uncompressed RGB Targa identifier */
header.imageType = TGA_TYPE_COLOR;
/* uncompressed RGB Targa identifier */
header.imageType = TGA_TYPE_COLOR;
/* image width, low byte */
header.widthLo = im->w & 0xFF;
/* image width, high byte */
header.widthHi = im->w >> 8;
/* image width, low byte */
header.widthLo = im->w & 0xFF;
/* image width, high byte */
header.widthHi = im->w >> 8;
/* image height, low byte */
header.heightLo = im->h & 0xFF;
/* image height, high byte */
header.heightHi = im->h >> 8;
/* image height, low byte */
header.heightLo = im->h & 0xFF;
/* image height, high byte */
header.heightHi = im->h >> 8;
/* total number of bits per pixel */
header.bpp = (im->flags & F_HAS_ALPHA) ? 32 : 24;
/* number of extra (alpha) bits per pixel */
header.descriptor = (im->flags & F_HAS_ALPHA) ? 8 : 0;
/* total number of bits per pixel */
header.bpp = (im->flags & F_HAS_ALPHA) ? 32 : 24;
/* number of extra (alpha) bits per pixel */
header.descriptor = (im->flags & F_HAS_ALPHA) ? 8 : 0;
/* top-to-bottom storage */
header.descriptor |= TGA_DESC_VERTICAL;
/* top-to-bottom storage */
header.descriptor |= TGA_DESC_VERTICAL;
/* allocate a buffer to receive the BGRA-swapped pixel values */
buf = malloc(im->w * im->h * ((im->flags & F_HAS_ALPHA) ? 4 : 3) );
if(!buf) {
fclose(f);
return 0;
}
/* allocate a buffer to receive the BGRA-swapped pixel values */
buf = malloc(im->w * im->h * ((im->flags & F_HAS_ALPHA) ? 4 : 3) );
if(!buf) {
fclose(f);
return 0;
}
/* now we have to read from im->data into buf, swapping RGBA to BGRA */
dataptr = im->data; bufptr = buf;
/* now we have to read from im->data into buf, swapping RGBA to BGRA */
dataptr = im->data; bufptr = buf;
/* for each row */
for(y = 0; y < im->h; y++)
{
int x;
unsigned char r, g, b, a;
/* for each row */
for(y = 0; y < im->h; y++)
{
int x;
unsigned char r, g, b, a;
/* for each pixel in the row */
for(x = 0; x < im->w; x++) {
if(im->flags & F_HAS_ALPHA) {
READ_RGBA(dataptr, r, g, b, a);
*bufptr++ = b;
*bufptr++ = g;
*bufptr++ = r;
*bufptr++ = a;
} else {
READ_RGB(dataptr, r, g, b);
*bufptr++ = b;
*bufptr++ = g;
*bufptr++ = r;
}
dataptr++;
} /* end for (each pixel in row) */
/* for each pixel in the row */
for(x = 0; x < im->w; x++) {
if(im->flags & F_HAS_ALPHA) {
READ_RGBA(dataptr, r, g, b, a);
*bufptr++ = b;
*bufptr++ = g;
*bufptr++ = r;
*bufptr++ = a;
} else {
READ_RGB(dataptr, r, g, b);
*bufptr++ = b;
*bufptr++ = g;
*bufptr++ = r;
}
dataptr++;
} /* end for (each pixel in row) */
/* report progress every row */
if (progress)
/* report progress every row */
if (progress)
{
char per;
int l;
@ -170,28 +170,28 @@ save (ImlibImage *im, ImlibProgressFunction progress,
{
l = y - pl;
if(!progress(im, per, 0, (y - l), im->w, l))
{
if(buf)
free(buf);
fclose(f);
return 2;
}
{
if(buf)
free(buf);
fclose(f);
return 2;
}
pper = per;
pl = y;
}
}
}
}
/* write the header */
fwrite(&header, sizeof(header), 1, f);
/* write the header */
fwrite(&header, sizeof(header), 1, f);
/* write the image data */
fwrite(buf, 1, im->w * im->h * ((im->flags & F_HAS_ALPHA) ? 4 : 3), f);
/* write the image data */
fwrite(buf, 1, im->w * im->h * ((im->flags & F_HAS_ALPHA) ? 4 : 3), f);
if(buf)
free(buf);
fclose(f);
return 1;
if(buf)
free(buf);
fclose(f);
return 1;
}
/* Load up a TGA file
@ -208,163 +208,171 @@ char
load (ImlibImage *im, ImlibProgressFunction progress,
char progress_granularity, char immediate_load)
{
FILE *fp;
int bpp, vinverted = 0;
int rle = 0, footer_present = 0;
FILE *fp;
int bpp, vinverted = 0;
int rle = 0, footer_present = 0;
tga_header header;
tga_footer footer;
tga_header header;
tga_footer footer;
if(im->data)
return 0;
if(im->data)
return 0;
fp = fopen(im->file, "rb");
if(!fp)
return 0;
fp = fopen(im->file, "rb");
if(!fp)
return 0;
/* read the footer first */
fseek (fp, 0L - (sizeof (tga_footer)), SEEK_END);
if (fread (&footer, sizeof (tga_footer), 1, fp) != 1)
/* read the footer first */
fseek (fp, 0L - (sizeof (tga_footer)), SEEK_END);
if (fread (&footer, sizeof (tga_footer), 1, fp) != 1)
{
fclose(fp);
return 0;
}
/* check the footer to see if we have a v2.0 TGA file */
if (memcmp(footer.signature, TGA_SIGNATURE, sizeof (footer.signature)) == 0)
footer_present = 1;
/* now read the header */
if (fseek (fp, 0, SEEK_SET) || fread (&header, sizeof (header), 1, fp) != 1)
{
fclose(fp);
return 0;
}
/* skip over alphanumeric ID field */
if (header.idLength && fseek (fp, header.idLength, SEEK_CUR))
{
fclose(fp);
return 0;
}
/* now parse the header */
/* this flag indicated bottom-up pixel storage */
vinverted = header.descriptor ^ TGA_DESC_VERTICAL;
switch (header.imageType)
{
case TGA_TYPE_COLOR_RLE:
case TGA_TYPE_GRAY_RLE:
rle = 1;
break;
case TGA_TYPE_COLOR:
case TGA_TYPE_GRAY:
rle = 0;
break;
default:
fclose(fp);
return 0;
}
/* bits per pixel */
bpp = header.bpp;
if( ! ((bpp == 32) || (bpp == 24) || (bpp == 8)) )
{
fclose(fp);
return 0;
}
/* endian-safe loading of 16-bit sizes */
im->w = (header.widthHi << 8) | header.widthLo;
im->h = (header.heightHi << 8) | header.heightLo;
if ((im->w > 32767) || (im->w < 1) || (im->h > 32767) || (im->h < 1))
{
im->w = 0;
fclose(fp);
return 0;
}
if(!im->format)
{
if (bpp == 32)
SET_FLAG(im->flags, F_HAS_ALPHA);
else
UNSET_FLAG(im->flags, F_HAS_ALPHA);
im->format = strdup("tga");
}
/* if we need to actually read the pixel data... */
if (((!im->data) && (im->loader)) || (immediate_load) || (progress))
{
unsigned long datasize;
struct stat ss;
unsigned char *buf, *bufptr;
DATA32 *dataptr;
int y, pl = 0;
char pper = 0;
/* allocate the destination buffer */
im->data = malloc(im->w * im->h * sizeof(DATA32));
if(!im->data)
{
fclose(fp);
return 0;
im->w = 0;
fclose(fp);
return 0;
}
/* check the footer to see if we have a v2.0 TGA file */
if (memcmp(footer.signature, TGA_SIGNATURE, sizeof (footer.signature)) == 0)
footer_present = 1;
/* first we read the file data into a buffer for parsing */
/* then we decode from RAM */
/* now read the header */
if (fseek (fp, 0, SEEK_SET) || fread (&header, sizeof (header), 1, fp) != 1)
/* find out how much data must be read from the file */
/* (this is NOT simply width*height*4, due to compression) */
stat(im->file, &ss);
datasize = ss.st_size - sizeof(tga_header) - header.idLength -
(footer_present ? sizeof(tga_footer) : 0);
buf = malloc(datasize);
if(!buf)
{
fclose(fp);
return 0;
im->w = 0;
fclose(fp);
return 0;
}
/* skip over alphanumeric ID field */
if (header.idLength && fseek (fp, header.idLength, SEEK_CUR))
/* read in the pixel data */
if( fread(buf, 1, datasize, fp) != datasize)
{
fclose(fp);
return 0;
fclose(fp);
return 0;
}
/* now parse the header */
/* buffer is ready for parsing */
/* this flag indicated bottom-up pixel storage */
vinverted = header.descriptor ^ TGA_DESC_VERTICAL;
/* bufptr is the next byte to be read from the buffer */
bufptr = buf;
/* endian-safe loading of 16-bit sizes */
im->w = (header.widthHi << 8) | header.widthLo;
im->h = (header.heightHi << 8) | header.heightLo;
/* dataptr is the next 32-bit pixel to be filled in */
dataptr = im->data;
switch (header.imageType)
/* decode uncompressed BGRA data */
if(!rle)
{
case TGA_TYPE_COLOR_RLE:
case TGA_TYPE_GRAY_RLE:
rle = 1;
break;
for(y = 0; y < im->h; y++) /* for each row */
{
int x;
case TGA_TYPE_COLOR:
case TGA_TYPE_GRAY:
rle = 0;
break;
default:
fclose(fp);
return 0;
}
/* bits per pixel */
bpp = header.bpp;
if( ! ((bpp == 32) || (bpp == 24) || (bpp == 8)) )
{
fclose(fp);
return 0;
}
/* point dataptr at the beginning of the row */
if(vinverted)
/* some TGA's are stored upside-down! */
dataptr = im->data + (im->h - (y+1)) * im->w;
else
dataptr = im->data + y * im->w;
if(!im->format)
{
if (bpp == 32)
SET_FLAG(im->flags, F_HAS_ALPHA);
else
UNSET_FLAG(im->flags, F_HAS_ALPHA);
im->format = strdup("tga");
}
/* if we need to actually read the pixel data... */
if (((!im->data) && (im->loader)) || (immediate_load) || (progress))
{
unsigned long datasize;
struct stat ss;
unsigned char *buf, *bufptr;
DATA32 *dataptr;
int y, pl = 0;
char pper = 0;
/* allocate the destination buffer */
im->data = malloc(im->w * im->h * sizeof(DATA32));
if(!im->data)
{
fclose(fp);
return 0;
}
/* first we read the file data into a buffer for parsing */
/* then we decode from RAM */
/* find out how much data must be read from the file */
/* (this is NOT simply width*height*4, due to compression) */
stat(im->file, &ss);
datasize = ss.st_size - sizeof(tga_header) - header.idLength -
(footer_present ? sizeof(tga_footer) : 0);
buf = malloc(datasize);
if(!buf)
{
fclose(fp);
return 0;
}
/* read in the pixel data */
if( fread(buf, 1, datasize, fp) != datasize)
{
fclose(fp);
return 0;
}
/* buffer is ready for parsing */
/* bufptr is the next byte to be read from the buffer */
bufptr = buf;
/* dataptr is the next 32-bit pixel to be filled in */
dataptr = im->data;
/* decode uncompressed BGRA data */
if(!rle)
{
for(y = 0; y < im->h; y++) /* for each row */
{
int x;
/* point dataptr at the beginning of the row */
if(vinverted)
/* some TGA's are stored upside-down! */
dataptr = im->data + (im->h - (y+1)) * im->w;
else
dataptr = im->data + y * im->w;
for(x = 0; x < im->w; x++) /* for each pixel in the row */
{
switch(bpp) {
for(x = 0; x < im->w; x++) /* for each pixel in the row */
{
switch(bpp) {
/* 32-bit BGRA pixels */
case 32:
case 32:
WRITE_RGBA(dataptr,
*(bufptr + 2), /* R */
*(bufptr + 1), /* G */
@ -376,7 +384,7 @@ load (ImlibImage *im, ImlibProgressFunction progress,
break;
/* 24-bit BGR pixels */
case 24:
case 24:
WRITE_RGBA(dataptr,
*(bufptr + 2), /* R */
*(bufptr + 1), /* G */
@ -388,7 +396,7 @@ load (ImlibImage *im, ImlibProgressFunction progress,
break;
/* 8-bit grayscale */
case 8:
case 8:
WRITE_RGBA(dataptr,
*bufptr, /* grayscale */
*bufptr,
@ -398,186 +406,186 @@ load (ImlibImage *im, ImlibProgressFunction progress,
dataptr++;
bufptr += 1;
break;
}
}
} /* end for (each pixel) */
} /* end for (each pixel) */
/* report progress every row */
if(progress)
{
char per;
int l;
/* report progress every row */
if(progress)
{
char per;
int l;
per = (char)((100*y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
per = (char)((100*y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, (y - l), im->w, l))
{
free(buf);
fclose(fp);
return 2;
free(buf);
fclose(fp);
return 2;
}
pper = per;
pl = y;
}
}
}
}
} /* end for (each row) */
} /* end for (each row) */
} /* end if (RLE) */
} /* end if (RLE) */
/* decode RLE compressed data */
else
{
unsigned char curbyte, red, green, blue, alpha;
DATA32 *final_pixel = dataptr + im->w * im->h;
unsigned char curbyte, red, green, blue, alpha;
DATA32 *final_pixel = dataptr + im->w * im->h;
/* loop until we've got all the pixels */
while(dataptr < final_pixel)
{
int count;
/* loop until we've got all the pixels */
while(dataptr < final_pixel)
{
int count;
curbyte = *bufptr++;
count = (curbyte & 0x7F) + 1;
curbyte = *bufptr++;
count = (curbyte & 0x7F) + 1;
if(curbyte & 0x80) /* RLE packet */
{
int i;
if(curbyte & 0x80) /* RLE packet */
{
int i;
switch(bpp) {
case 32:
blue = *bufptr++; green = *bufptr++; red = *bufptr++;
alpha = *bufptr++;
for(i = 0; i < count; i++) {
WRITE_RGBA(dataptr, red, green, blue, alpha);
dataptr++;
}
break;
case 24:
blue = *bufptr++; green = *bufptr++; red = *bufptr++;
for(i = 0; i < count; i++) {
WRITE_RGBA(dataptr, red, green, blue, (char) 0xff);
dataptr++;
}
break;
case 8:
alpha = *bufptr++;
for(i = 0; i < count; i++) {
WRITE_RGBA(dataptr, alpha, alpha, alpha, (char) 0xff);
dataptr++;
}
break;
}
} /* end if (RLE packet) */
else /* raw packet */
{
int i;
for(i = 0; i < count; i++)
{
switch(bpp) {
/* 32-bit BGRA pixels */
case 32:
WRITE_RGBA(dataptr,
*(bufptr + 2), /* R */
*(bufptr + 1), /* G */
*(bufptr + 0), /* B */
*(bufptr + 3) /* A */
);
dataptr++;
bufptr += 4;
break;
/* 24-bit BGR pixels */
case 24:
WRITE_RGBA(dataptr,
*(bufptr + 2), /* R */
*(bufptr + 1), /* G */
*(bufptr + 0), /* B */
(char) 0xff /* A */
);
dataptr++;
bufptr += 3;
break;
/* 8-bit grayscale */
case 8:
WRITE_RGBA(dataptr,
*bufptr, /* pseudo-grayscale */
*bufptr,
*bufptr,
(char) 0xff
);
dataptr++;
bufptr += 1;
break;
}
}
} /* end if (raw packet) */
/* report progress every packet */
if(progress)
{
char per;
int l;
/* compute an approximate y value */
/* can't be exact since packets don't necessarily */
/* end at the end of a row */
y = (dataptr - im->data) / im->w;
per = (char)((100*y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, (y - l), im->w, l))
{
free(buf);
fclose(fp);
return 2;
switch(bpp) {
case 32:
blue = *bufptr++; green = *bufptr++; red = *bufptr++;
alpha = *bufptr++;
for(i = 0; i < count; i++) {
WRITE_RGBA(dataptr, red, green, blue, alpha);
dataptr++;
}
pper = per;
pl = y;
}
} /* end progress report */
break;
} /* end for (each packet) */
case 24:
blue = *bufptr++; green = *bufptr++; red = *bufptr++;
for(i = 0; i < count; i++) {
WRITE_RGBA(dataptr, red, green, blue, (char) 0xff);
dataptr++;
}
break;
/* must now flip a bottom-up image */
case 8:
alpha = *bufptr++;
for(i = 0; i < count; i++) {
WRITE_RGBA(dataptr, alpha, alpha, alpha, (char) 0xff);
dataptr++;
}
break;
}
/* This is the best of several ugly implementations
* I considered. It's not very good since the image
* will be upside-down throughout the loading process.
* This could be done in-line with the de-RLE code
* above, but that would be messy to code. There's
* probably a better way... */
} /* end if (RLE packet) */
if(vinverted) {
im->data = flip(im->data, im->w, im->h);
if(!im->data) {
fclose(fp);
free(buf);
return 0;
}
}
else /* raw packet */
{
int i;
for(i = 0; i < count; i++)
{
switch(bpp) {
/* 32-bit BGRA pixels */
case 32:
WRITE_RGBA(dataptr,
*(bufptr + 2), /* R */
*(bufptr + 1), /* G */
*(bufptr + 0), /* B */
*(bufptr + 3) /* A */
);
dataptr++;
bufptr += 4;
break;
/* 24-bit BGR pixels */
case 24:
WRITE_RGBA(dataptr,
*(bufptr + 2), /* R */
*(bufptr + 1), /* G */
*(bufptr + 0), /* B */
(char) 0xff /* A */
);
dataptr++;
bufptr += 3;
break;
/* 8-bit grayscale */
case 8:
WRITE_RGBA(dataptr,
*bufptr, /* pseudo-grayscale */
*bufptr,
*bufptr,
(char) 0xff
);
dataptr++;
bufptr += 1;
break;
}
}
} /* end if (raw packet) */
/* report progress every packet */
if(progress)
{
char per;
int l;
/* compute an approximate y value */
/* can't be exact since packets don't necessarily */
/* end at the end of a row */
y = (dataptr - im->data) / im->w;
per = (char)((100*y) / im->h);
if (((per - pper) >= progress_granularity) ||
(y == (im->h - 1)))
{
l = y - pl;
if(!progress(im, per, 0, (y - l), im->w, l))
{
free(buf);
fclose(fp);
return 2;
}
pper = per;
pl = y;
}
} /* end progress report */
} /* end for (each packet) */
/* must now flip a bottom-up image */
/* This is the best of several ugly implementations
* I considered. It's not very good since the image
* will be upside-down throughout the loading process.
* This could be done in-line with the de-RLE code
* above, but that would be messy to code. There's
* probably a better way... */
if(vinverted) {
im->data = flip(im->data, im->w, im->h);
if(!im->data) {
fclose(fp);
free(buf);
return 0;
}
}
} /* end if (image is RLE) */
free(buf);
free(buf);
} /* end if (loading pixel data) */
fclose(fp);
return 1;
fclose(fp);
return 1;
}
void
@ -606,22 +614,22 @@ formats (ImlibLoader *l)
static DATA32*
flip(DATA32* in, int w, int h)
{
int adv, adv2, i;
DATA32* out;
int adv, adv2, i;
DATA32* out;
out = malloc(w * h * sizeof(DATA32));
if(!out)
return NULL;
out = malloc(w * h * sizeof(DATA32));
if(!out)
return NULL;
adv = 0; adv2 = w * h;
adv = 0; adv2 = w * h;
for(i = 0; i < h; i++) {
adv2 -= w;
memmove(out + adv, in + adv2, w * sizeof(DATA32));
adv += w;
}
for(i = 0; i < h; i++) {
adv2 -= w;
memmove(out + adv, in + adv2, w * sizeof(DATA32));
adv += w;
}
free(in);
return out;
free(in);
return out;
}

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;
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;
image_width = img->image->w;
image_height = img->image->h;
dy = h > y ? -1 : y - 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! */
/* 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 (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);
}
}
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 (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 (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 (((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;
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;
if (im->data)
return 0;
file = fopen(im->file, "rb");
file = fopen(im->file, "rb");
if (!file)
return 0;
if (!file)
return 0;
fread(&magic_number, sizeof(uint16), 1, file);
rewind(file);
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);
if ((magic_number != TIFF_BIGENDIAN) /* Checks if actually tiff file */
&& (magic_number != TIFF_LITTLEENDIAN))
{
fclose(file);
return 0;
}
tif = TIFFFdOpen(fd, im->file, "r");
fd = fileno(file);
fd = dup(fd);
fclose(file);
if (!tif)
return 0;
tif = TIFFFdOpen(fd, im->file, "r");
if ((!TIFFRGBAImageOK(tif, "Cannot be processed by libtiff"))
|| (!TIFFRGBAImageBegin((TIFFRGBAImage *) &rgba_image, tif, 0,
"Error reading tiff")))
{
TIFFClose(tif);
return 0;
}
if (!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);
if ((!TIFFRGBAImageOK(tif, "Cannot be processed by libtiff"))
|| (!TIFFRGBAImageBegin((TIFFRGBAImage *) &rgba_image, tif, 0,
"Error reading tiff")))
{
TIFFClose(tif);
return 0;
}
return 1;
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;
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;
if (!im->data)
return 0;
tif = TIFFOpen(im->file, "w");
tif = TIFFOpen(im->file, "w");
if (!tif)
return 0;
if (!tif)
return 0;
/* None of the TIFFSetFields are checked for errors, but since they */
/* shouldn't fail, this shouldn't be a problem */
/* 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));
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));
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);
if (!buf)
{
TIFFClose(tif);
return 0;
}
return 1;
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 */

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;
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;
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;
short lookup[128 - 32][128 - 32];
float per = 0.0, per_inc;
int last_per = 0, last_y = 0;
done = 0;
transp = -1;
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 immediate_load is 1, then dont delay image laoding as below, or */
/* already data in this image - dont load it again */
if (im->data)
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;
}
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;
}
cmap = malloc(sizeof(struct _cmap) * ncolors);
/* 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");
if (!cmap)
{
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;
}
per_inc = 100.0 / (((float) w) * h);
j = 0;
context++;
}
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)
else if (context == 1)
{
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;
/* 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"))
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;
}
}
}
/* 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);
}
if (progress)
{
progress(im, 100, 0, last_y, w, h);
}
free(cmap);
free(line);
free(cmap);
free(line);
xpm_parse_done();
return 1;
return 1;
}
char