/* * Photo Image Print System * Copyright (C) 2000-2004 EPSON KOWA Corporation. * Copyright (C) SEIKO EPSON CORPORATION 2000-2004. * * This program 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. * * This program 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., 675 Mass Ave, Cambridge, MA 02139, USA. * * As a special exception, EPSON KOWA Corporation gives permission to * link the code of this program with libraries which are covered by * the EPSON KOWA PUBLIC LICENCE and distribute their linked * combinations. You must obey the GNU General Public License in all * respects for all of the code used other than the libraries which * are covered by EPSON KOWA PUBLIC LICENCE. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "pips.h" #include "pipsError.h" #define BUFMAX 0xff #define LBUFMAX 0xffff #define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4) typedef struct BITMAPFILEHEADER{ //USHORT bfType; // must be "BM" ULONG bfSize; // file size(byte) USHORT bfReserved1; // reserved USHORT bfReserved2; // reserved ULONG bfOffBits; // offset to image } BFH; typedef struct BITMAPINFOHEADER{ ULONG biSize; // 当構造体のサイズ(バイト) ULONG biWidth; // イメージの幅 ULONG biHeight; // イメージの高さ USHORT biPlanes; // must be 1 USHORT biBitCount; // 色数 ULONG biCompression; // 圧縮タイプ ULONG biSizeImage; // イメージのサイズ ULONG biXPelsPerMeter; // 水平解像度 ULONG biYPelsPerMeter; // 垂直解像度 ULONG biClrUsed; // →カラーテーブルを参照 ULONG biClrImportant; // →カラーテーブルを参照 } BIH; typedef struct RGBQUAD{ UCHAR rgbBlue; // あお UCHAR rgbGreen; // みどり UCHAR rgbRed; // あか UCHAR rgbReserved; // must be 0 } RGBQ; static ULONG tunLong(ULONG); static USHORT tunShort(USHORT); static void tunByte(BFH *, BIH *); static int escStream(char*, FILE*, FILE*); //-------------------------------------------------- // tunLong //-------------------------------------------------- static ULONG tunLong(ULONG from) { int i; ULONG to = 0; for(i = 0; i < 4; i++){ to += from & 0x000000ff; if(i < 3){ from = from >> 8; to = to << 8; } } return to; } //-------------------------------------------------- // tunShort //-------------------------------------------------- static USHORT tunShort(USHORT from) { int i; USHORT to = 0; for(i = 0; i < 2; i++){ to += from & 0x00ff; if(i < 1){ from = from >> 8; to = to << 8; } } return to; } //-------------------------------------------------- // tunByte //-------------------------------------------------- static void tunByte(BFH *bfh, BIH *bih) { bfh->bfSize = tunLong(bfh->bfSize); bfh->bfReserved1 = tunShort(bfh->bfReserved1); bfh->bfReserved2 = tunShort(bfh->bfReserved2); bfh->bfOffBits = tunLong(bfh->bfOffBits); bih->biSize = tunLong(bih->biSize); bih->biWidth = tunLong(bih->biWidth); bih->biHeight = tunLong(bih->biHeight); bih->biPlanes = tunShort(bih->biPlanes); bih->biBitCount = tunShort(bih->biBitCount); bih->biCompression = tunLong(bih->biCompression); bih->biSizeImage = tunLong(bih->biSizeImage); bih->biXPelsPerMeter = tunLong(bih->biXPelsPerMeter); bih->biYPelsPerMeter = tunLong(bih->biYPelsPerMeter); bih->biClrUsed = tunLong(bih->biClrUsed); bih->biClrImportant = tunLong(bih->biClrImportant); } //################################################## // fileLoad //################################################## int fileLoad(FILE *infp, FILE *outfp, POINT *size, UCHAR **bmData) { BFH bfh; BIH bih; UCHAR *bgr_data = NULL; char *buffer = NULL; int offset; int error = 0; size_t bmsize = 0; USHORT bfType; if ( !infp ) { error = -1; goto bail; } buffer = malloc( LBUFMAX ); if ( !buffer ) { error = MEMORY_ERROR; goto bail; } #if DEBUG fprintf( stderr, "begin load\n"); #endif memset(buffer, 0, LBUFMAX); error = escStream(buffer, infp, outfp ); switch(error) { case -1: error = -1; goto bail; case 0: error = INPUT_ESCP_WARNING; goto bail; default: if ( error < sizeof(USHORT) + sizeof(bfh) + sizeof(bih)) { error = GRAPHICS_FORMAT_ERROR; goto bail; } error = 0; break; } memcpy( &bfType, buffer, sizeof(USHORT) ); offset = sizeof(USHORT); memcpy( &bfh, buffer + offset, sizeof(bfh) ); offset += sizeof(bfh); memcpy( &bih, buffer + offset, sizeof(bih)); offset += sizeof(bih); if(bfType == 0x424d) { tunByte(&bfh, &bih); } else if(bfType != 0x4d42) { error = GRAPHICS_FORMAT_ERROR; goto bail; } if(bih.biBitCount != 24){ error = GRAPHICS_FORMAT_ERROR; goto bail; } bmsize = WIDTHBYTES(bih.biWidth * 24) * bih.biHeight; bgr_data = (UCHAR *) malloc(bmsize); if ( !bgr_data ) { error = MEMORY_ERROR; goto bail; } if (LBUFMAX - bfh.bfOffBits > 0) { if( bmsize > LBUFMAX - bfh.bfOffBits ) { ULONG left = LBUFMAX - bfh.bfOffBits; memcpy( bgr_data, buffer + bfh.bfOffBits, left); if( fread(bgr_data + left, bmsize - left, 1, infp) != 1 ) { error = GRAPHICS_LOAD_ERROR; goto bail; } } else memcpy( bgr_data, buffer + bfh.bfOffBits, bmsize); } else { ULONG data_ofs = 0; data_ofs = (ULONG)fabs (LBUFMAX - bfh.bfOffBits); if (data_ofs) fseek (infp, data_ofs, SEEK_CUR); if( fread(bgr_data, bmsize, 1, infp) != 1 ) { error = GRAPHICS_LOAD_ERROR; goto bail; } } bail: if ( size ) { size->x = bih.biWidth; size->y = bih.biHeight; } if ( bmData ) *bmData = bgr_data; if ( buffer ) { free( buffer ); } if (!error) { long gofs; gofs = bfh.bfSize - bmsize - bfh.bfOffBits; if (gofs) fseek (infp, gofs, SEEK_CUR); } #if DEBUG fprintf( stderr, "end load\n" ); #endif return error; } //-------------------------------------------------- // escStream //-------------------------------------------------- static int escStream (char *buf, FILE *infp, FILE *outfp) { char escp_head[] = "REMOTE1"; int nbuf, i; if ( !buf ) return 0; if ( feof ( infp ) ) return 0; nbuf = fread (buf, sizeof (char), LBUFMAX, infp); if (nbuf == 0) return -1; else if ( nbuf < strlen (escp_head)) return 0; for (i = 0; i < nbuf - strlen (escp_head); i++) { if (!strncmp (buf + i, escp_head, strlen (escp_head))) { fwrite (buf, sizeof(char), nbuf, outfp); while ((nbuf = fread(buf, sizeof (char), LBUFMAX, infp)) != 0) { fwrite (buf, sizeof (char), nbuf, outfp); fflush ( outfp ); } if (nbuf) fwrite(buf, sizeof (char), nbuf, outfp ); return 0; } } return nbuf; }