2 "$Id: image.c 9201 2008-06-01 17:32:45Z anmaster $";
46 #define ROTATE_RIGHT(c) if ((c) & 01) (c) = ((c) >>1) + 0x80000000; else (c) >>= 1;
78 if ((cp=strchr(filename,
'@'))!=NULL) {
80 int offset, length, last=-1;
82 offset = atoi(cp + 1);
85 LOG(
LOG_ERROR,
"common::load_image",
"Corrupt filename - has '@' but no ':' ?(%s)", filename);
88 length = atoi(lp + 1);
92 if (last==-1 &&
fd_cache[i].fd == -1) last = i;
95 if (i == MAX_FACE_SETS) {
97 LOG(
LOG_WARNING,
"common::load_image",
"fd_cache filled up? unable to load matching cache entry");
102 if ((
fd_cache[last].fd = open(filename, O_RDONLY | O_BINARY))==-1) {
104 if ((
fd_cache[last].fd = open(filename, O_RDONLY))==-1) {
106 LOG(
LOG_WARNING,
"common::load_image",
"unable to load listed cache file %s",filename);
113 lseek(
fd_cache[i].fd, offset, SEEK_SET);
115 *len = read(
fd_cache[i].fd, data, length);
117 *len = read(
fd_cache[i].fd, data, 65535);
124 if ((fd=open(filename, O_RDONLY | O_BINARY))==-1)
return -1;
125 length = lseek(fd, 0, SEEK_END);
126 lseek(fd, 0, SEEK_SET);
127 *len=read(fd, data, length);
129 if ((fd=open(filename, O_RDONLY))==-1)
return -1;
130 *len=read(fd, data, 65535);
142 for (i=0; i<*len; i++) {
165 #define IMAGE_HASH 8192
192 for (p = str; *p!=
'\0' && *p !=
'.'; p++) {
200 return hash % tablesize;
213 if (
image_cache[newhash].image_name == NULL)
return -1;
214 if (!strcmp(
image_cache[newhash].image_name, str))
return newhash;
217 }
while (newhash != hash);
222 LOG(
LOG_WARNING,
"common::image_find_hash",
"Hash table is full, increase IMAGE_CACHE size");
232 if (hash_entry == -1) {
233 LOG(
LOG_ERROR,
"common::image_remove_hash",
"Unable to find cache entry for %s, %s", imagename, ce->
filename);
245 LOG(
LOG_ERROR,
"common::image_rmove_hash",
"Unable to find cache entry for %s, %s", imagename, ce->
filename);
266 if (hash_entry == -1)
return NULL;
270 if (entry->
checksum == checksum)
break;
285 strcmp(
image_cache[newhash].image_name, imagename)) {
289 if (newhash == hash) {
290 LOG(
LOG_WARNING,
"common::image_find_hash",
"Hash table is full, increase IMAGE_CACHE size");
304 new_entry->
filename = strdup(filename);
323 if (line[0] ==
'#')
return;
325 if (sscanf(line,
"%s %u %s", imagename, &checksum, filename)==3) {
328 LOG(
LOG_WARNING,
"common::image_process_line",
"Did not parse line %s properly?", line);
342 facetoname[i] = NULL;
348 snprintf(bmaps,
sizeof(bmaps),
"%s/bmaps.client",CF_DATADIR);
349 if ((fp=fopen(bmaps,
"r"))!=NULL) {
350 while (fgets(inbuf,
MAX_BUF-1, fp)!=NULL) {
355 snprintf(inbuf,
sizeof(inbuf),
"Unable to open %s. You may wish to download and install the image file to improve performance.\n", bmaps);
359 snprintf(bmaps,
sizeof(bmaps),
"%s/.crossfire/image-cache/bmaps.client", getenv(
"HOME"));
360 if ((fp=fopen(bmaps,
"r"))!=NULL) {
361 while (fgets(inbuf,
MAX_BUF-1, fp)!=NULL) {
404 uint8 data[65536], *png_tmp;
410 fprintf(stderr,
"finish_face_cmd, pnum=%d, checksum=%d, face=%s\n",
411 pnum, checksum, face);
418 snprintf(filename,
sizeof(filename),
"%s/.crossfire/gfx/%s.png", getenv(
"HOME"), face);
419 if (
load_image(filename, data, &len, &newsum)==-1) {
431 snprintf(filename,
sizeof(filename),
"%s/%s",
434 snprintf(filename,
sizeof(filename),
"%s/.crossfire/image-cache/%s",
436 if (
load_image(filename, data, &len, &newsum)==-1) {
437 LOG(
LOG_WARNING,
"common::finish_face_cmd",
"file %s listed in cache file, but unable to load", filename);
445 if (!(png_tmp =
png_to_data(data, len, &nx, &ny))) {
447 LOG(
LOG_WARNING,
"common::finish_face_cmd",
"Got error on png_to_data, image=%s",face);
449 if (!ce->
ispublic) unlink(filename);
460 LOG(
LOG_WARNING,
"common::finish_face_cmd",
"Got error on create_and_rescale_image_from_data, file=%s",filename);
502 LOG(
LOG_WARNING,
"common::Face2Cmd",
"Received a 'face' command when we are not caching");
508 face = (
char*)data+7;
522 if (len<9 || (len-9)!=plen) {
523 LOG(
LOG_WARNING,
"common::Image2Cmd",
"Lengths don't compare (%d,%d)",
544 if (facetoname[face]==NULL) {
545 LOG(
LOG_WARNING,
"common::display_newpng",
"Caching images, but name for %ld not set", face);
548 snprintf(filename,
sizeof(filename),
"%s/.crossfire/image-cache",getenv(
"HOME"));
549 if (access(filename, R_OK | W_OK | X_OK)== -1)
553 mkdir(filename, 0755);
556 snprintf(filename,
sizeof(filename),
"%s/.crossfire/image-cache/%c%c", getenv(
"HOME"),
557 facetoname[face][0], facetoname[face][1]);
558 if (access(filename, R_OK | W_OK | X_OK)== -1)
562 mkdir(filename,0755);
574 snprintf(basename,
sizeof(basename),
"%s.%s", facetoname[face], face_info.
facesets[setnum].
prefix);
576 strcpy(basename, facetoname[face]);
584 snprintf(filename,
sizeof(filename),
"%s/.crossfire/image-cache/%c%c/%s.%d",
585 getenv(
"HOME"), facetoname[face][0],
586 facetoname[face][1], basename, setnum);
587 }
while (access(filename, F_OK)==-0);
590 if ((tmpfile = fopen(filename,
"wb"))==NULL) {
592 if ((tmpfile = fopen(filename,
"w"))==NULL) {
594 LOG(
LOG_WARNING,
"common::display_newpng",
"Can not open %s for writing", filename);
599 fwrite(buf, buflen, 1, tmpfile);
602 for (i=0; (int)i<buflen; i++) {
607 snprintf(filename,
sizeof(filename),
"%c%c/%s.%d", facetoname[face][0], facetoname[face][1],
617 snprintf(filename,
sizeof(filename),
"%s/.crossfire/image-cache/bmaps.client", getenv(
"HOME"));
618 if ((tmpfile=fopen(filename,
"a"))==NULL) {
619 LOG(
LOG_WARNING,
"common::display_newpng",
"Can not open %s for appending", filename);
622 fprintf(tmpfile,
"%s %u %c%c/%s.%d\n",
623 facetoname[face], csum, facetoname[face][0],
624 facetoname[face][1], basename, setnum);
630 pngtmp =
png_to_data(buf, buflen, &width, &height);
632 LOG(
LOG_WARNING,
"common::display_newpng",
"create_and_rescale_image_from_data failed for face %ld", face);
636 free(facetoname[face]);
637 facetoname[face]=NULL;
655 char *cp, *lp, *cps[7], buf[
MAX_BUF];
656 int onset=0, badline=0,i;
661 cp = strchr(lp,
'\n');
662 if (!cp || (cp - lp) > len)
return;
666 cp = strchr(lp,
'\n');
667 if (!cp || (cp - lp) > len)
return;
671 cp = strchr(lp,
'\n');
672 while (cp && (cp - lp) <= len) {
678 if (!(cps[0] = strtok(lp,
":"))) badline=1;
679 for (i=1; i<7; i++) {
680 if (!(cps[i] = strtok(NULL,
":"))) badline=1;
683 LOG(
LOG_WARNING,
"common::get_image_info",
"bad data, ignoring line:/%s/", lp);
685 onset = atoi(cps[0]);
687 LOG(
LOG_WARNING,
"common::get_image_info",
"setnum is too high: %d > %d",
698 cp = strchr(lp,
'\n');
712 if (onset < MAX_FACE_SETS) {
716 snprintf(buf,
sizeof(buf),
"Unable to find match for faceset %s on the server", face_info.
want_faceset);
739 int start, stop, imagenum, slen, faceset;
743 cp = strchr((
char*)data,
' ');
744 if (!cp || (cp - data) > len)
return;
745 start = atoi((
char*)data);
747 while (isspace(*cp)) cp++;
749 cp = strchr(lp,
' ');
750 if (!cp || (cp - data) > len)
return;
761 while (*cp==
' ') cp++;
762 while ((cp - data) < len) {
777 LOG(
LOG_WARNING,
"common::get_image_sums",
"Received an image beyond our range? %d > %d", imagenum, stop);
char facecachedir[MAX_BUF]
short GetShort_String(const unsigned char *data)
static sint32 image_find_hash(char *str)
static int load_image(char *filename, uint8 *data, int *len, uint32 *csum)
struct Image_Cache image_cache[IMAGE_HASH]
sint16 want_config[CONFIG_NUMS]
struct Cache_Entry * cache_entry
void Image2Cmd(uint8 *data, int len)
int create_and_rescale_image_from_data(Cache_Entry *ce, int pixmap_num, uint8 *rgba_data, int width, int height)
void Face2Cmd(uint8 *data, int len)
void LOG(LogLevel level, const char *origin, const char *format,...)
uint8 * png_to_data(uint8 *data, int len, uint32 *width, uint32 *height)
static uint32 image_hash_name(char *str, int tablesize)
int cs_print_string(int fd, const char *str,...)
sint16 use_config[CONFIG_NUMS]
struct Cache_Entry * next
struct FD_Cache fd_cache[MAX_FACE_SETS]
static Cache_Entry * image_add_hash(char *imagename, char *filename, uint32 checksum, uint32 ispublic)
static Cache_Entry * image_find_cache_entry(char *imagename, uint32 checksum, int has_sum)
void reset_image_cache_data(void)
void get_image_sums(char *data, int len)
static void image_remove_hash(char *imagename, Cache_Entry *ce)
void display_newpng(int face, uint8 *buf, int buflen, int setnum)
static void image_process_line(char *line, uint32 ispublic)
char * strdup_local(const char *str)
void requestface(int pnum, char *facename)
void init_common_cache_data(void)
void draw_info(const char *str, int color)
const char *const rcsid_common_image_c
void finish_face_cmd(int pnum, uint32 checksum, int has_sum, char *face, int faceset)
Face_Information face_info
int associate_cache_entry(Cache_Entry *ce, int pixnum)
int GetInt_String(const unsigned char *data)
static char * facetoname[MAXPIXMAPNUM]
void get_image_info(uint8 *data, int len)