/*************************************************************************** * Copyright (C) 2009 by SEMIKO * * mail@semico.ru * * * * 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #include #include #include /* Коды выхода BSD from @(#)sysexits.h 8.1 (Berkeley) 6/2/93 */ /* Copyright (c) 1987, 1993 */ /* The Regents of the University of California. All rights reserved. */ #define EX_USAGE 64 /* command line usage error */ #define EX_DATAERR 65 /* data format error */ #define EX_NOINPUT 66 /* cannot open input */ #define EX_NOUSER 67 /* addressee unknown */ #define EX_NOHOST 68 /* host name unknown */ #define EX_UNAVAILABLE 69 /* service unavailable */ #define EX_SOFTWARE 70 /* internal software error */ #define EX_OSERR 71 /* system error (e.g., can't fork) */ #define EX_OSFILE 72 /* critical OS file missing */ #define EX_CANTCREAT 73 /* can't create (user) output file */ #define EX_IOERR 74 /* input/output error */ #define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ #define EX_PROTOCOL 76 /* remote error in protocol */ #define EX_NOPERM 77 /* permission denied */ #define EX_CONFIG 78 /* configuration error */ /* end sysexits.h */ char version[]="Version 0.11"; /* v0.11 - 02.01.10 - изменён формат вывода чисел в MKL-файле; - добавлен ключ -f (-f0 - десятичный формат в MKL, -f1 - шестнадцатиричный, -f2 - десятичный от 0 до 9) */ int dos=0; /* 0-GNU/Linux 1-DOS 2-Win32 */ char fname[5][256]; /* 0-BMP без расширения 1-BMP исходный 2-MKL 3-TXT 4-MKI */ int fname_vsego; /* всего файлов в строке аргументов */ int kluch_e=0; /* ключ -e - отображение рисунка (при X<80) на терминале (stdout) */ int kluch_f=2; /* ключ -f - формат вывода в MKL (v0.11) */ FILE *fp1,*fp2,*fp3,*fp4; /* потоки 1-BMP 2-MKL 3-TXT 4-MKI */ char mes0[8]; /* ВК ПС для DOS или ВК для Linux */ char str[512]; char str1[256]; char strerr[256]; /* сообщение об ошибке */ char pict[128][64]; /* массив точек - 8 килобайт в памяти найдётся, а битовые поля плохо переносимы */ /* функции */ int bmpgetc(long); void k2str1(int); /* v0.11 */ int bmp2mkl(void); /*-----*/ int bmpgetc(long n) { /* считывает байт из указанной позиции BMP-файла */ int i; int re=EOF; i=fseek(fp1,n,0); /* от начала файла - SEEK_SET==0 */ if (i!=0) goto end; re=fgetc(fp1); end: return(re); } void k2str1(int k) { /* преобразование числа в строку str1 с учётом kluch_f */ if ((kluch_f<0)||(kluch_f>2)) kluch_f=2; if (kluch_f==0) sprintf(str1,"%d",k); /* десятичное число */ if (kluch_f==1) { /* шестнадцатиричное число - всегда */ if ((k>0x99)||((k>9)&&(k<16))) sprintf(str1,"0%Xh",k); else sprintf(str1,"%Xh",k); } if (kluch_f==2) { /* шестнадцатиричное число только больше 10 */ if ((k>=0)&&(k<=9)) sprintf(str1,"%d",k); if ((k>9)&&(k<=0x99)) sprintf(str1,"%Xh",k); if ((k>0x99)||((k>9)&&(k<16))) sprintf(str1,"0%Xh",k); } return; } int bmp2mkl(void) { int x,y,y1,xbmp,ybmp,i,j,k; long l; long loffbits=0; /* начало изображения в BMP */ long loffpal=0; /* начало палитры в BMP */ long loffbmpy; /* смещение строки в BMP */ long lbmpx; /* длина строки в BMP */ int napr=0; /* 0 - BMP записан снизу-вверх, 1 - сверху-вниз */ int bitcount; /* 0 - JPEG или PNG, 1 - моно, 4 - 16 цветов, 8 - 256 цветов */ char c; /* цвет точки: 0-сброшен, 1-установлен (чёрный) */ int cbmp; /* чёрный (наиболее тёмный) цвет в палитре BMP файла */ long cbmpy, cbmpymin; /* серый для поиска наиболее тёмного */ int cr=30, cg=59, cb=11; /* константы цветов для преобразования в серый */ int re=0; /* потоки fp1 и fp2 должны быть открыты */ if ((fp1==NULL)||(fp2==NULL)) {re=1; goto end;} /* проверить параметры BMP-файла */ if ((bmpgetc(0)!=0x42)||(bmpgetc(1)!=0x4D)) {re=1; goto end;} /* не BMP */ loffbits=bmpgetc(10)+256*bmpgetc(11); /* biOffBits - смещение начала изображения в файле */ loffpal=14+bmpgetc(14)+256*bmpgetc(15); /* 14+biSize - смещение палитры */ xbmp=bmpgetc(18)+256*bmpgetc(19); ybmp=bmpgetc(22)+256*bmpgetc(23); if ((bmpgetc(20)!=0)||(bmpgetc(21)!=0)) {re=1; goto end;} /* размеры xbmp больше 65536 */ l=bmpgetc(24)+256*bmpgetc(25); if (l==0xFFFF) {l=0; ybmp=65535-ybmp; napr=1;} else napr=0; /* определено направление записи BMP */ if (l!=0) {re=1; goto end;} /* размеры ybmp больше 65536 */ if ((xbmp>0x80)||(ybmp>0x40)) {re=1; goto end;} /* размеры больше 128x64 по любой координате */ l=bmpgetc(26)+256*bmpgetc(27); if (l!=1) {re=1; goto end;} /* biPlanes!=1 - не одна плоскость */ l=bmpgetc(28)+256*bmpgetc(29); bitcount=0; if (l==1) bitcount=1; /* biBitCount=1 - монохромное */ if (l==4) bitcount=4; /* biBitCount=4 - 16 цветов */ if (l==8) bitcount=8; /* biBitCount=8 - 256 цветов */ if (l==16) bitcount=16; /* 2 байта/цвет */ if (l==24) bitcount=24; /* 3 байта/цвет */ if (l==32) bitcount=32; /* 4 байта/цвет */ if (bitcount==0) {re=1; goto end;} /* формат BMP программой не поддерживается */ if ((bmpgetc(30)!=0)||(bmpgetc(31)!=0)||(bmpgetc(32)!=0)||(bmpgetc(33)!=0)) {re=1; goto end;} /* biCompression без сжатия BI_RGB=0, остальное не поддерживается */ /* проверить палитру - найти чёрный цвет или наиболее тёмный по критерию 0.30 R + 0.59 G + 0.11 B */ cbmp=-1; if (bitcount==1) /* монохромый файл - два цвета - прямой поиск */ { cbmpy=cb*bmpgetc(loffpal)+cg*bmpgetc(loffpal+1)+cr*bmpgetc(loffpal+2); /* серый для цвета 0 */ if (cbmpy < (cb*bmpgetc(loffpal+4)+cg*bmpgetc(loffpal+5)+cr*bmpgetc(loffpal+6))) cbmp=0; else cbmp=1; } if ((bitcount==4)||(bitcount==8)) /* 16 или 256 цветов */ { cbmpymin=0xFFFF; /* > (11+59+30)*255=25500 */ if (bitcount==8) j=256; else j=16; for (i=0; i1) c=1; pict[x][y]=c; } /* конец цикла по x */ } /* конец цикла по y */ /* записать MKL */ sprintf(str,"%s: %s",fname[0],mes0); fputs(str,fp2); /* v0.11 - изменён формат вывода */ strcpy(str," .DB "); k2str1(xbmp); strcat(str,str1); strcat(str,", "); k2str1(ybmp); strcat(str,str1); strcat(str,mes0); fputs(str,fp2); if (ybmp%8==0) y1=ybmp/8; else y1=ybmp/8+1; /* высота в байтах */ for (x=0; x2) j=2; strncpy(fname[j+1],argv[i],255); if (j<2) fname_vsego++; } else { c=argv[i][1]; if (c=='-') c=argv[i][2]; /* для --help и т.п.*/ k=1; if ((c=='h')||(c=='H')||(c=='?')) { /* help */ printf("bmp2mkl - converter BMP (max 128x64) to MKL, MKI and TXT files %s",mes0); printf("bmp2mkl BMPfile [key] %s",mes0); /* v0.11 */ printf("bmp2mkl [-h|-v|-w] %s",mes0); printf("\t-h,-H,-?\tthis help; %s",mes0); printf("\t-v,-V\tversion; %s",mes0); printf("\t-w,-W\twarranty and copyright; %s",mes0); printf("\t-e,-E\techo (if X<80); %s", mes0); printf("\t-f,-F\tformat (-f0 DEC; -f1 HEX; -f2 DEC/HEX (default))."); goto end; } if ((c=='v')||(c=='V')) { /* version */ printf(version); if (dos==0) printf(" (GNU/Linux)"); if (dos==1) printf(" (DOS)"); if (dos==2) printf(" (Win32)"); goto end; } if ((c=='w')||(c=='W')) { /* copyleft & warranty */ printf("Copyright (C) 2009-2010 by NPP SEMIKO (Russia, Novosibirsk) %s%s",mes0,mes0); printf("This program is free software; you can redistribute it and/or modify %s",mes0); printf("it under the terms of the GNU General Public License as published by %s",mes0); printf("the Free Software Foundation; either version 2 of the License, or %s",mes0); printf("(at your option) any later version. %s%s",mes0,mes0); printf("This program is distributed in the hope that it will be useful, %s",mes0); printf("but WITHOUT ANY WARRANTY; without even the implied warranty of %s",mes0); printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the %s",mes0); printf("GNU General Public License for more details. %s%s",mes0,mes0); printf("You should have received a copy of the GNU General Public License %s",mes0); printf("along with this program; if not, write to the Free Software %s",mes0); printf("Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"); goto end; } if ((c=='e')||(c=='E')) { /* echo */ kluch_e=1; k=0; } if ((c=='f')||(c=='F')) { /* format .DB v0.11 */ switch(argv[i][2]) { case '0': kluch_f=0; break; case '1': kluch_f=1; break; case '2': kluch_f=2; break; default: kluch_f=0; } k=0; } if (k!=0) {printf("bmp2mkl -h for help"); goto end;} /* v0.11 */ } } nach: if (fname_vsego<=0) {re=EX_USAGE; goto end;} /* нет файла */ fp1=fopen(fname[1],"rb"); /* открыть BMP как двоичный для чтения */ if (fp1==NULL) {re=EX_NOINPUT; printf("BMP not found"); printf(mes0); goto end;} /* файл BMP не открыт */ k=strlen(fname[1]); for (i=k; i>0; i--) { if ( (fname[1][i]=='.')&&(i0)&&(i