/* * grp.c -- grp file handler * (C)Copyright 1999 by Hiroshi Takekawa * This file is part of Enfle. * * Last Modified: Fri Dec 24 00:15:21 1999. * $Id: grp.c,v 1.12 1999/12/23 15:15:31 sian Exp $ * * Enfle is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Enfle is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "plugin.h" #include "utils.h" #include "grp.h" int #ifdef PIC get_plugininfo(PluginInfo *p) #else loader_grp_get_plugininfo(PluginInfo *p) #endif { p->version = 1; p->type = _Loader; p->pluginname = "GRP Format Loader Plugin version 0.1.1.1"; p->pluginshortname = FORMAT_NAME; p->author = "Hiroshi Takekawa"; p->dlhandle = NULL; /* set by plugin_load */ p->functions.loader.load_image = grp_load_image; return 1; } static int grp_read_type0(Info *info, Image *p) { Archive *ar = info->ar; unsigned char *data; int size, o; #ifdef DEBUG fprintf(stderr, "grp_read_type0() called\n"); #endif size = ar->size - (2 + 4 * 256 + 4); if (size < 0) return 0; if ((data = malloc(size)) == NULL) return 0; if ((o = archive_read(ar, data, size)) != size) { fprintf(stderr, "grp_read_type0: archive_read() failed: %d bytes read\n", o); free(data); return 0; } p->width = get_little_word(data); p->height = get_little_word(data + 2); o = 4; if (size < p->width * p->height || size >= p->width * p->height + 8) { p->width = get_little_word(data + 4); p->height = get_little_word(data + 6); if (!p->width || !p->height || p->width * p->height + 8 != size) { free(data); return 0; } o = 8; } p->type = _INDEX; p->ncolors = 256; p->bytes_per_line = image_calculate_bytes_per_line(p->width, p->type); p->image_size = p->bytes_per_line * p->height; if ((p->image = malloc(p->image_size)) == NULL) { free(data); return 0; } memcpy(p->image, data + o, p->image_size); free(data); return 1; } static int grp_read_type1(Info *info, Image *p) { Archive *ar = info->ar; unsigned char buf[8], *data; int i, j, b = 0, c = 0, l, o, w, compressed_size, extracted_size, rp; if (archive_read(ar, buf, 8) != 8) return 0; compressed_size = get_little_dword(buf); if (ar->size < compressed_size) return 0; extracted_size = get_little_dword(buf + 4); if (extracted_size > (1 << 24) || extracted_size < 0) return 0; rp = archive_tell(ar); if ((data = malloc(extracted_size)) == NULL) return 0; /* extraction */ for (i = 0, j = 0; i < extracted_size && j < compressed_size;) { if (--c < 0) { b = archive_getc(ar); j++; c = 7; } if (b & 1) { data[i++] = archive_getc(ar); j++; } else { w = read_little_word(ar); j += 2; o = w >> 4; if ((l = (w & 0xf) + 3) == 18) { l += archive_getc(ar); j++; } o += ((i >> 11) << 11); if (i - 2 < o) o -= 0x800; for (; l > 0; l--) { /* data[i++] = (o < 0) ? 0 : data[o]; o++; */ data[i++] = data[o++]; } } b >>= 1; } /* verify */ if (i != extracted_size) { fprintf(stderr, "grp_read_type1: extraceted size: %d != %d\n", extracted_size, i); free(data); return 0; } p->width = get_little_word(data); p->height = get_little_word(data + 2); if (p->width * p->height + 4 == extracted_size) o = 4; else { p->width = get_little_word(data + 4); p->height = get_little_word(data + 6); if (!p->width || !p->height || p->width * p->height + 8 != extracted_size) { free(data); return 0; } o = 8; } p->type = _INDEX; p->ncolors = 256; p->bytes_per_line = image_calculate_bytes_per_line(p->width, p->type); p->image_size = p->bytes_per_line * p->height; if ((p->image = malloc(p->image_size)) == NULL) { free(data); return 0; } memcpy(p->image, data + o, p->image_size); free(data); return 1; } static int grp_decode_image(Info *info, Image *p) { Archive *ar = info->ar; int i, c, nc; unsigned char buf[2 + 4 * 256 + 4]; #ifdef DEBUG fprintf(stderr, "grp_decode_image() called\n"); #endif if (archive_read(ar, buf, 2 + 4 * 256 + 4) != 2 + 4 * 256 + 4) return 0; if ((nc = get_little_word(buf)) > 256) return 0; /* palette */ for (i = 0; i < nc; i++) { c = buf[2 + 4 * i]; p->colormap[c][2] = buf[2 + 4 * i + 1]; p->colormap[c][1] = buf[2 + 4 * i + 2]; p->colormap[c][0] = buf[2 + 4 * i + 3]; } if (!(buf[2 + 4 * 256] ? grp_read_type1(info, p) : grp_read_type0(info, p))) return 0; info->format = FORMAT_NAME; return 1; } int grp_load_image(Info *info, Image *p) { if (!grp_decode_image(info, p)) return info->format == NULL ? PROC_NOT : PROC_ERROR; info->npics = 1; /* set handler */ info->handler.destroy = NULL; info->handler.alarmset = NULL; info->handler.alarm = NULL; info->handler.alarmoff = NULL; return PROC_OK; }