//----------------------------------------------------------------------------- // Prevodni program mezi grafickym formatem IMG a TGA // // Soucast serialu "Graficke formaty" publikovaneho na http://www.root.cz // Autor: Pavel Tisnovsky //----------------------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> #define EXT_IMG ".img" #define EXT_TGA ".tga" //----------------------------------------------------------------------------- // Otevreni souboru typu IMG (jmeno neobsahuje koncovku) //----------------------------------------------------------------------------- FILE *openImg(char *name) { char *imgName=(char *)malloc(strlen(name)+strlen(EXT_IMG)+1); strcpy(imgName, name); strcat(imgName, EXT_IMG); printf("Opening file %s for reading\n", imgName); return fopen(imgName, "rb"); } //----------------------------------------------------------------------------- // Otevreni souboru typu TGA (jmeno neobsahuje koncovku) //----------------------------------------------------------------------------- FILE *openTga(char *name) { char *tgaName=(char *)malloc(strlen(name)+strlen(EXT_TGA)+1); strcpy(tgaName, name); strcat(tgaName, EXT_TGA); printf("Opening file %s for writing\n", tgaName); return fopen(tgaName, "wb"); } //----------------------------------------------------------------------------- // Nacteni hlavicky ze souboru typu IMG, naplnuje se i rozliseni //----------------------------------------------------------------------------- int readIMGHeader(FILE *fin, int *width, int *height) { // makro pro prevod dvojice bytu na integer v usporadani big endian #define twoBytes2int(b1, b2) ((int)(b1)<<8 | (b2)) unsigned char imgHeader[10]; int firstLine, lastLine, bpp; if (fread(imgHeader, 10, 1, fin)!=1) return 0; *width= twoBytes2int(imgHeader[0], imgHeader[1]); *height= twoBytes2int(imgHeader[2], imgHeader[3]); firstLine= twoBytes2int(imgHeader[4], imgHeader[5]); lastLine= twoBytes2int(imgHeader[6], imgHeader[7]); bpp= twoBytes2int(imgHeader[8], imgHeader[9]); printf("IMG header: width= %d\n", *width); printf("IMG header: height= %d\n", *height); printf("IMG header: 1st line= %d\n", firstLine); printf("IMG header: last line= %d\n", lastLine); printf("IMG header: bpp= %d\n", bpp); return 1; } //----------------------------------------------------------------------------- // Ulozeni hlavicky souboru typu TGA //----------------------------------------------------------------------------- int writeTGAHeader(FILE *fout, int width, int height) { unsigned char tgaHeader[18]={ // hlavicka formatu typu TGA 0x00, // typ hlavicky TGA 0x00, // nepouzivame paletu 0x02, // typ obrazku je RGB TrueColor 0x00, 0x00, // delka palety je nulova 0x00, 0x00, 0x00, // pozice v palete nas nezajima 0x00, 0x00, 0x00, 0x00, // obrazek je umisteny na pozici [0, 0] 0x00, 0x00, 0x00, 0x00, // sirka a vyska obrazku (dva byty na polozku) 0x18, // format je 24 bitu na pixel 0x20 // orientace bitmapy v obrazku }; memcpy(tgaHeader+12, &width, 2); // do hlavicky TGA zapsat sirku obrazku memcpy(tgaHeader+14, &height, 2); // do hlavicky TGA zapsat vysku obrazku return fwrite(tgaHeader, 18, 1, fout)==1; // zapsat hlavicku TGA do souboru } //----------------------------------------------------------------------------- // Prevod obrazovych dat z formatu IMG do formatu TGA //----------------------------------------------------------------------------- int convert(FILE *fin, FILE *fout) { int count, r, g, b; // nacteme vsechny ctverice hodnot ve sledu ("runu") while ((count=fgetc(fin))!=EOF && (r=fgetc(fin))!=EOF && (g=fgetc(fin))!=EOF && (b=fgetc(fin))!=EOF) { // rozkodovat cely sled a zapsat do vystupniho TGA while (count--) { if (fputc(r, fout)==EOF) return 0; if (fputc(g, fout)==EOF) return 0; if (fputc(b, fout)==EOF) return 0; } } return 1; } //----------------------------------------------------------------------------- // Hlavni funkce konzolove aplikace //----------------------------------------------------------------------------- int main(int argc, char **argv) { #define my_assert(cond, text)\ if ((cond)) {\ fprintf(stderr, "error: %s\n", (text));\ return 1;\ } FILE *fin; FILE *fout; int width, height; puts("img2tga processing:"); my_assert(argc<2, "file name (without extension) required!"); my_assert(!(fin=openImg(argv[1])), "open IMG for reading failed!"); my_assert(!(fout=openTga(argv[1])), "open TGA for writing failed!"); my_assert(!readIMGHeader(fin, &width, &height), "read IMG header failed!"); my_assert(!writeTGAHeader(fout, width, height), "write TGA header failed!"); my_assert(!convert(fin, fout), "unable to convert data!"); my_assert(fclose(fin), "close IMG failed!"); my_assert(fclose(fout), "close TGA failed!"); puts("img2tga done.\n"); return 0; } //----------------------------------------------------------------------------- // finito //-----------------------------------------------------------------------------