/* * vsp.c -- vsp file expander * (C)Copyright 1998, 99 by Hiroshi Takekawa * This file is part of Enfle. * * Last Modified: Sun Sep 26 16:57:29 1999. * $Id: vsp.c,v 1.3 1999/09/26 08:55:59 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 "config.h" #include "vsp.h" #include #include #if STDC_HEADERS # include #else # ifndef HAVE_MEMCPY # define memcpy(d, s, n) bcopy ((s), (d), (n)) # define memmove(d, s, n) bcopy ((s), (d), (n)) # endif #endif static VSP_info * vsp_loadheader(unsigned char *d) { VSP_info *v = malloc(sizeof(VSP_info)); if (v == NULL) return NULL; v->x = (d[1] << 8) + d[0]; v->y = (d[3] << 8) + d[2]; v->width = ((d[5] << 8) + d[4] - v->x) << 3; v->height = (d[7] << 8) + d[6] - v->y; v->pb = d[9]; v->p_offset = 0x0a; v->d_offset = 0x3a; if (v->x < 0 || v->x > 80 || v->y < 0 || v->y > 400 || v->width <= 0 || v->width > 640 || v->height <= 0 || v->height > 400) { free(v); return NULL; } return v; } static unsigned char * vsp_decode(unsigned char *d, int w, int h) { int c, i, l, x, y, pl; unsigned char b, b1, b2, b3, mask = 0; unsigned char bcb[4][480], bpb[4][480], *bc[4], *bp[4], *p, *loc; if ((p = malloc(w * h)) == NULL) return NULL; bp[0] = bpb[0]; bp[1] = bpb[1]; bp[2] = bpb[2]; bp[3] = bpb[3]; bc[0] = bcb[0]; bc[1] = bcb[1]; bc[2] = bcb[2]; bc[3] = bcb[3]; for (x = 0; x < (w >> 3); x++) { for (pl = 0; pl < 4; pl++) for (y = 0; y < h;) { c = *d++; if (c > 7) { *(bc[pl] + y) = c; y++; } else if (c == 0) { l = (*d++) + 1; memcpy(bc[pl] + y, bp[pl] + y, l); y += l; } else if (c == 1) { l = (*d++) + 1; b = *d++; memset(bc[pl] + y, b, l); y += l; } else if (c == 2) { l = (*d++) + 1; b = *d++; b1 = *d++; for (i = 0; i < l; i++) { *(bc[pl] + y) = b; y++; *(bc[pl] + y) = b1; y++; } } else if (c == 3) { l = (*d++) + 1; for (i = 0; i < l; i++) { *(bc[pl] + y) = (*(bc[0] + y) ^ mask); y++; } mask = 0; } else if (c == 4) { l = (*d++) + 1; for (i = 0; i < l; i++) { *(bc[pl] + y) = (*(bc[1] + y) ^ mask); y++; } mask = 0; } else if (c == 5) { l = (*d++) + 1; for (i = 0; i < l; i++) { *(bc[pl] + y) = (*(bc[2] + y) ^ mask); y++; } mask = 0; } else if (c == 6) mask = 0xff; else if (c == 7) { *(bc[pl] + y) = *d++; y++; } } /* expand planes to packed pixel */ for (y = 0; y < h; y++) { loc = p + y * w + (x << 3); b = bc[0][y]; b1 = bc[1][y]; b2 = bc[2][y]; b3 = bc[3][y]; *(loc + 0) = ((b >> 7) & 1) | ((b1 >> 6) & 2) | ((b2 >> 5) & 4) | ((b3 >> 4) & 8); *(loc + 1) = ((b >> 6) & 1) | ((b1 >> 5) & 2) | ((b2 >> 4) & 4) | ((b3 >> 3) & 8); *(loc + 2) = ((b >> 5) & 1) | ((b1 >> 4) & 2) | ((b2 >> 3) & 4) | ((b3 >> 2) & 8); *(loc + 3) = ((b >> 4) & 1) | ((b1 >> 3) & 2) | ((b2 >> 2) & 4) | ((b3 >> 1) & 8); *(loc + 4) = ((b >> 3) & 1) | ((b1 >> 2) & 2) | ((b2 >> 1) & 4) | ((b3 ) & 8); *(loc + 5) = ((b >> 2) & 1) | ((b1 >> 1) & 2) | ((b2 ) & 4) | ((b3 << 1) & 8); *(loc + 6) = ((b >> 1) & 1) | ((b1 ) & 2) | ((b2 << 1) & 4) | ((b3 << 2) & 8); *(loc + 7) = ((b ) & 1) | ((b1 << 1) & 2) | ((b2 << 2) & 4) | ((b3 << 3) & 8); } /* copy */ bp[0] = bc[0]; bp[1] = bc[1]; bp[2] = bc[2]; bp[3] = bc[3]; } return p; } VSP_info * VSP_load(unsigned char *data) { VSP_info *vspinfo; int i; if (data == NULL) return NULL; if ((vspinfo = vsp_loadheader(data)) == NULL) return NULL; #ifdef DEBUG fprintf(stderr, "width = %d, height = %d\n", vspinfo->width, vspinfo->height); #endif for (i = 0; i < 16; i++) { vspinfo->palette[i][0] = *(data + vspinfo->p_offset + i * 3 + 1) << 4; vspinfo->palette[i][1] = *(data + vspinfo->p_offset + i * 3 + 2) << 4; vspinfo->palette[i][2] = *(data + vspinfo->p_offset + i * 3 + 0) << 4; } vspinfo->image = vsp_decode(data + vspinfo->d_offset, vspinfo->width, vspinfo->height); return vspinfo; }