bmp2h.c

Go to the documentation of this file.
00001 
00015 #include <stdio.h>
00016 #include <string.h>
00017 #include <stdlib.h>
00018 
00019 //#define DEBUG
00020 //#define VERBOSE
00021 
00022 typedef struct {
00023    unsigned char B;
00024    unsigned char G;
00025    unsigned char R;
00026 } COR;
00027 
00028 typedef struct {
00029     unsigned char fator; // RLE 8 bits
00030     unsigned char R1G1;
00031     unsigned char B1R2;
00032     unsigned char G2B2;
00033 } RLE8;
00034 
00035 typedef struct {
00036    unsigned int largura;
00037    unsigned int altura;
00038    unsigned short int numeroDeBits;
00039    unsigned int tamanho;
00040    unsigned int dados;
00041 } CABECALHO;
00042 
00043 int main(int argc, char *argv[]){
00044     FILE *imagemBMP,*imagemRAW;
00045     char *arquivoBMP,*arquivoRAW;
00046     char temp[20];
00047     int tam;
00048     unsigned char junk;
00049     CABECALHO imagemInfo;
00050     COR cor, cor2;
00051     RLE8 imagemRLE[132*132*24];
00052     COR imagemMEM[132*132*24];
00053     COR ordenado[132][132];
00054     int numeroMagico=0, i=0, j=0, k=0, l=0, m=0, n=0, o=0, x=0, y=0, qtd=0;
00055     size_t r;
00056     if(argc < 3 || argc > 3){
00057         printf("%s --- ", argv[0]);
00058         printf("Comversor BMP para o formato C header RAW R1G1B1R2G2B2 comprimido com RLE\n");
00059         printf("Desenvolvido por Jimmy Pinto Stelzer<jimmy.stelzer@gmail.com>\n\n");
00060         printf("Uso: %s <pasta> <quantidade>\n", argv[0]);
00061         return 1;
00062     }else{
00063         arquivoBMP = argv[1];
00064         strcpy(temp, argv[1]);
00065         arquivoRAW = argv[1];
00066         tam = atoi(argv[2]);
00067         //recurso = argv[3];
00068     }
00069     for(qtd = 1; qtd<=tam; qtd++){
00070                 numeroMagico=0, i=0, j=0, k=0, l=0, m=0, n=0, o=0, x=0, y=0;
00071                 for(i=0;i<132*132*24;i++){
00072                         imagemRLE[i].fator = 0x00;
00073                         imagemRLE[i].R1G1 = 0x00;
00074                         imagemRLE[i].B1R2 = 0x00;
00075                         imagemRLE[i].G2B2 = 0x00;
00076                 }
00077 
00078                 sprintf(arquivoBMP, "%s/%d.bmp", temp, qtd);
00079                 imagemBMP=fopen(arquivoBMP,"rb");
00080                 if(imagemBMP==NULL){
00081                         fprintf(stderr,"Erro! O arquivo %s não pode ser lido.\n",arquivoBMP);
00082                         return 1;
00083                 }
00084                 printf("Processando o arquivo %s.\n", arquivoBMP);
00085                 /* Determinar o formato do arquivo */
00086                 r=fread(&numeroMagico,sizeof(unsigned short),1,imagemBMP);
00087                 if(r<=0){ fprintf(stderr,"Erro! Não foi possível ler o formato do arquivo %s.\n",arquivoBMP); return 1; }
00088         #ifdef DEBUG
00089                 printf("numeroMagico=0x%x\n", numeroMagico);
00090         #endif
00091                 if(numeroMagico!=0x4d42){ fprintf(stderr,"Erro! O arquivo %s não é um arquivo BMP válido.\n",arquivoBMP); }
00092 
00093                 /* Determinar o tamanho do arquivo */
00094                 r=fread(&imagemInfo.tamanho,4,1,imagemBMP);
00095                 if(r<=0){ fprintf(stderr,"Erro! Não foi possível ler o tamanho do arquivo %s.\n",arquivoBMP); return 1; }
00096         #ifdef DEBUG
00097                 printf("bmp.tamanho=%d bytes\n", imagemInfo.tamanho);
00098         #endif
00099                 /* Determinar o incio dos dados */
00100                 fseek(imagemBMP,10,SEEK_SET);
00101                 r=fread(&imagemInfo.dados,4,1,imagemBMP);
00102                 if(r<=0){ fprintf(stderr,"Erro! Não foi possível ler a posição inicial dos dados da imagem no arquivo %s.\n",arquivoBMP); return 1; }
00103 
00104                 /* Determinar largura da Imagem */
00105                 fseek(imagemBMP,18,SEEK_SET);
00106                 r=fread(&imagemInfo.largura,4,1,imagemBMP);
00107                 if(r<=0){ fprintf(stderr,"Erro! Não foi possível ler a largura da imagem no arquivo %s.\n",arquivoBMP); return 1; }
00108         #ifdef DEBUG
00109                 printf("bmp.largura=%d\n", imagemInfo.largura);
00110         #endif
00111 
00112                 /* Determinar altura da Imagem */
00113                 fseek(imagemBMP,22,SEEK_SET);
00114                 r=fread(&imagemInfo.altura,4,1,imagemBMP);
00115                 if(r<=0){ fprintf(stderr,"Erro! Não foi possível ler a altura da imagem no arquivo %s.\n",arquivoBMP); return 1; }
00116         #ifdef DEBUG
00117                 printf("bmp.altura=%d\n", imagemInfo.altura);
00118         #endif
00119 
00120                 if(imagemInfo.largura > 132 || imagemInfo.altura > 132){
00121                         fprintf(stderr,"Erro! A Imagem (%s) é muito grande para ser usado no KIT. A resolução do Display LCD é 132x132 px.\n Você de usar uma imagem menor ou igual a esse tamanho.\n",arquivoBMP); return 1;
00122                 }
00123 
00124                 /* Determinar bits/cor */
00125                 fseek(imagemBMP,28,SEEK_SET);
00126                 r=fread(&imagemInfo.numeroDeBits,2,1,imagemBMP);
00127                 if(r<=0){ fprintf(stderr,"Erro! Não foi possível ler o número de bits por cor da imagem no arquivo %s.\n",arquivoBMP); return 1; }
00128         #ifdef DEBUG
00129                 printf("bmp.numeroDeBits=%d\n", imagemInfo.numeroDeBits);
00130         #endif
00131 
00132                 /* Abrir o arquivo C header */
00133                 sprintf(arquivoRAW, "%s/%d", temp, qtd);
00134                 //printf("\n\n%s\n", temp);
00135                 imagemRAW=fopen(arquivoRAW,"wb+");
00136                 if(imagemRAW==NULL){
00137                         fprintf(stderr,"Erro! O arquivo %s não pode ser lido.\n",arquivoRAW);
00138                         return 1;
00139                 }
00140 
00141 //              fprintf(imagemRAW,"/*\n * Arquivo gerado automaticamente por bmp2c\n - bmp2c foi desenvolvido por Jimmy Pinto Stelzer<jimmy.stelzer@gmail.com>\n* Imagem"
00142 //                      " no formato RAW R1G1B1R2G2B2 para usar no Kit de desenvolvimento ARM7 - "
00143 //                      "LPC23XX-ARM7 - 2010/02\n * Em conjunto com a biblioteca gráfica ARM-GL\n"
00144 //                      " */\n\n"
00145 //                      "const unsigned char %s_largura = %d;\n"
00146 //                      "const unsigned char %s_altura = %d;\n"
00147 //                      "const unsigned char %s[] = {\n"
00148 //                      , recurso, imagemInfo.largura, recurso, imagemInfo.altura, recurso);
00149 
00150                 /* Posiciona no inicio da Imagem */
00151                 fseek(imagemBMP,imagemInfo.dados,SEEK_SET);
00152                 n = (imagemInfo.largura * 3);
00153                 while(n>0){
00154                         n-=4;
00155                 }
00156                 if(n<0){
00157                         n=-n;
00158                 }
00159                 for(j=0,i=0,m=imagemInfo.largura;i<(imagemInfo.altura*imagemInfo.largura);i++){
00160                         /* Obtem a cor do Pixel em RGB */
00161                         r=fread(&cor.B,sizeof(unsigned char),1,imagemBMP);
00162                         if(r<=0){ fprintf(stderr,"Erro! Não foi possível ler o bit de cor B do arquivo %s.\n",arquivoBMP); return 1; }
00163                         r=fread(&cor.G,sizeof(unsigned char),1,imagemBMP);
00164                         if(r<=0){ fprintf(stderr,"Erro! Não foi possível ler o bit de cor G do arquivo %s.\n",arquivoBMP); return 1; }
00165                         r=fread(&cor.R,sizeof(unsigned char),1,imagemBMP);
00166                         if(r<=0){ fprintf(stderr,"Erro! Não foi possível ler o bit de cor R do arquivo %s.\n",arquivoBMP); return 1; }
00167 
00168                         imagemMEM[k].R = cor.R;
00169                         imagemMEM[k].G = cor.G;
00170                         imagemMEM[k].B = cor.B;
00171 
00172                         j+=3;
00173         #ifdef DEBUG
00174         #ifdef VERBOSE
00175                 printf("[%04x] (%d) RGB arquivo: %02x,%02x,%02x -> RGB memoria: %02x,%02x,%02x\n", j+imagemInfo.dados, i, cor.R, cor.G, cor.B, imagemMEM[k].R, imagemMEM[k].G, imagemMEM[k].B);
00176         #endif
00177         #endif
00178                         m--; k++;
00179                         if(m==0){
00180                                 m=imagemInfo.largura;
00181                                 for(o=0;o<n;o++){
00182                                         r=fread(&junk,sizeof(unsigned char),1,imagemBMP);
00183                                         if(r<=0){ fprintf(stderr,"Erro! Não foi possível ler o bit de arredondamento do arquivo %s.\n",arquivoBMP); return 1; }
00184                                 }
00185                         }
00186                 }
00187                 fclose(imagemBMP);
00188 
00189                 /* Expelhar Verticalmente*/
00190                 k=0;
00191                 for(y=imagemInfo.altura-1;y>=0;y--){
00192                         for(x=0;x<imagemInfo.largura;x++){
00193                                 ordenado[x][y]=imagemMEM[k++];
00194                         }
00195                 }
00196 
00197                 m=0;k=0;j=0;i=0;
00198                 for(y=0;y<imagemInfo.altura;y++){
00199                         for(x=0;x<imagemInfo.largura;x++){
00200 
00201 
00202                                 if(x+1<imagemInfo.largura){
00203                                         cor.R = ordenado[x][y].R;
00204                                         cor.G = ordenado[x][y].G;
00205                                         cor.B = ordenado[x][y].B;
00206                                         cor2.R = ordenado[++x][y].R;
00207                                         cor2.G = ordenado[x][y].G;
00208                                         cor2.B = ordenado[x][y].B;
00209                                 }else if(y+1<imagemInfo.altura){
00210                                         cor.R = ordenado[x][y].R;
00211                                         cor.G = ordenado[x][y].G;
00212                                         cor.B = ordenado[x][y].B;
00213                                         x=0;
00214                                         cor2.R = ordenado[x][++y].R;
00215                                         cor2.G = ordenado[x][y].G;
00216                                         cor2.B = ordenado[x][y].B;
00217                                 }else{
00218                                         break;
00219                                 }
00220 
00221 
00222                                 /* Encodar RGB em RLE8 R1G1B1R2G2B2 */
00223                                 if(imagemRLE[k].fator != 0 && imagemRLE[k].fator < 0xf9 && imagemRLE[k].R1G1 == ((cor.R & 0xf0)|((cor.G & 0xf0) >> 4)) && imagemRLE[k].B1R2 == ((cor.B & 0xf0)|((cor2.R & 0xf0) >> 4)) && imagemRLE[k].G2B2 == ((cor2.G & 0xf0)|((cor2.B & 0xf0) >> 4))){
00224                                         imagemRLE[k].fator++;
00225                                 }else{
00226                                         if(imagemRLE[k].fator != 0){
00227                                                 k++;
00228                                         }
00229                                         imagemRLE[k].R1G1 = (cor.R & 0xf0)|((cor.G & 0xf0) >> 4);
00230                                         imagemRLE[k].B1R2 = (cor.B & 0xf0)|((cor2.R & 0xf0) >> 4);
00231                                         imagemRLE[k].G2B2 = (cor2.G & 0xf0)|((cor2.B & 0xf0) >> 4);
00232                                         imagemRLE[k].fator = 1;
00233                                 }
00234         #ifdef DEBUG
00235         #ifdef VERBOSE
00236                 printf("[%04x] (%d) RGB: %02x,%02x,%02x -> R1G1B1R2G2B2: %02x,%02x,%02x\n", j, i, cor.R, cor.G, cor.B, imagemRLE[k].R1G1, imagemRLE[k].B1R2, imagemRLE[k].G2B2);
00237         #endif
00238         #endif
00239                         j+=3;i++;
00240                         }
00241                 }
00242 
00243                 /* Gerar Header */
00244                 fputs("    ",imagemRAW);
00245         #ifdef DEBUG
00246                         printf("\nRAW=%d - RLE=%d - Fator de compresão: %1.4f\n", i, k+1, (float) i/(k+1));
00247         #endif
00248                 for(i=0,j=0;i<=k;i++){
00249                         fprintf(imagemRAW,"0x%02x,0x%02x,0x%02x,0x%02x,", imagemRLE[i].fator, imagemRLE[i].R1G1, imagemRLE[i].B1R2, imagemRLE[i].G2B2);
00250                         l+=imagemRLE[i].fator;
00251                         j++;
00252         #ifdef DEBUG
00253         #ifdef VERBOSE
00254                         printf("0x%02x,0x%02x,0x%02x,0x%02x,", imagemRLE[i].fator, imagemRLE[i].R1G1, imagemRLE[i].B1R2, imagemRLE[i].G2B2);
00255                         if(j>4){ printf("\n"); }
00256         #endif
00257         #endif
00258 
00259                         if(j>4){ j=0; fputs("\n    ",imagemRAW); }
00260                 }
00261         #ifdef DEBUG
00262                         printf("\nContagem descompreção RLE=%d\n", l);
00263         #endif
00264                 //fputs("0xfa\n};\n",imagemRAW);
00265                 fputs("0xfa\n",imagemRAW);
00266                 fclose(imagemRAW);
00267         }
00268     return 0;
00269 }
00270