Keith Packard wrote:
> I haven't seen anyone attempt a complete set, both because it's a lot of
> work and because there aren't great tools yet available to help in this
> task.
I wrote this very quick hack to allow me to change the red cursors to green
ones, by swapping the red and green bytes of every single point in the
image. Combined with a bash one-liner, it can read all of the files in the
redglass/ directory and put them in a new one called eg. greenglass/. It
should be possible to change the argb_filter function to perform other,
similar changes. Let me know if you find it useful.
Glyn
--
Drag queens have the navy tossing in their beds
Mary ate her little lamb and punk rock isn't dead
/* Xcur byteswapper v0.0.1
*
* No warranty whatsoever, do whatever you want with this file.
*
* The _intention_ is that the program will read an Xcur file from stdin,
* apply argb_filter to each pixel, and write the resulting Xcur to stdout
*
* Probably has endian issues.
*
* Glyn Kennington, 2003
*/
#include <stdio.h>
#include <stdint.h>
/* I have no need for the other members */
struct toc_entry
{
uint32_t type;
uint32_t position;
} ;
uint32_t temp;
/* takes the original ARGB pixel value, and returns a new one */
uint32_t argb_filter(uint32_t orig)
{
temp = (orig&0xFF0000FF ) | (orig&0xFF00)<<8 | (orig&0xFF0000)>>8 ;
return temp;
}
int main(int argc, char * argv[])
{
uint32_t word, pos;
uint32_t filehdr_len;
uint32_t toc_count, toc_len;
struct toc_entry *toc;
int i;
pos = 0;
fread(&word,4,1,stdin); pos +=4;
fwrite(&word,4,1,stdout);
if (word != 0x72756358) /* "Xcur" */
{
fprintf(stderr,"Not an Xcur file!\n");
return -1;
}
fread(&filehdr_len,4,1,stdin); pos +=4;
fwrite(&filehdr_len,4,1,stdout);
if (filehdr_len != 16)
{
fprintf(stderr,"had expected 16-byte header, but got %i\n", filehdr_len);
}
fread(&word,4,1,stdin); pos +=4; /* version no. */
fwrite(&word,4,1,stdout);
fread(&toc_count,4,1,stdin); pos+=4;
fwrite(&toc_count,4,1,stdout);
if (pos!=filehdr_len)
{
fprintf(stderr,"copying %i bytes, till of file header\n", filehdr_len-pos);
for ( ; pos < filehdr_len ; pos +=4 )
{
fread(&word,4,1,stdin);
fwrite(&word,4,1,stdout);
}
}
toc = (struct toc_entry *)calloc(toc_count, sizeof(struct toc_entry));
for (i = 0 ; i < toc_count ; i ++ )
{
fread(&(toc[i].type), 4, 1, stdin); pos+=4;
fwrite(&(toc[i].type), 4, 1, stdout);
fread(&word,4,1,stdin); pos+=4; /* subtype */
fwrite(&word,4,1,stdout);
fread(&(toc[i].position), 4, 1, stdin); pos+=4;
fwrite(&(toc[i].position), 4, 1, stdout);
}
for (i = 0 ; i < toc_count ; i ++ )
{
uint32_t hdr_len;
fread(&hdr_len,4,1,stdin); pos += 4;
fwrite(&hdr_len,4,1,stdout);
for ( ; pos < toc[i].position + hdr_len ; pos +=4 )
{ /* copy the rest of the headers without using them */
fread(&word,4,1,stdin);
fwrite(&word,4,1,stdout);
}
if ( toc[i].type == 0xFFFD0001)
{ /* comment, so copy and skip */
uint8_t c; /* copy one byte at a time */
if (i == toc_count-1)
{ /* last chunk, just go to EOF */
while (!feof(stdin))
{
if (!fread(&c,1,1,stdin))
break; /* this will detect EOF, the while() won't */
pos+=1;
fwrite(&c,1,1,stdout);
}
} /* if (last chunk) */
else
{ /* just read to next hdr */
for ( ; pos < toc[i+1].position ; pos ++ )
{
fread(&c,1,1,stdin);
fwrite(&c,1,1,stdout);
}
} /* if (chunks remaining) */
} /* if (comment) */
else
{ /* image (I hope), so apply filter when copying */
if (i == toc_count-1)
{
while (!feof(stdin))
{
if (fread(&word,4,1,stdin)<1)
break;
pos+=4;
word = argb_filter(word);
fwrite(&word,4,1,stdout);
}
} /* if (last chunk) */
else
{ /* just read to next hdr */
for ( ; pos < toc[i+1].position ; pos+=4 )
{
fread(&word,4,1,stdin);
word = argb_filter(word);
fwrite(&word,4,1,stdout);
}
} /* if (chunks remaining) */
} /* if (image) */
} /* for (table)*/
return 0;
}