Нашел тему на cyberforum.ru посвященную конвертору bmp <-> tga. : Конвертер из Bmp в Tga
Человек писал курсовую по этой теме на C (СИ) и оставил готовый код:
#include <stdio.h> #include <string.h> #include <locale.h> #include "stdlib.h" #include "math.h" // Структура BITMAP FILE HEADER --------------------------------------------------------------------------------------------------------- #pragma pack(push) #pragma pack(1) typedef struct { unsigned char b1, b2; unsigned long bfSize; //Размер файла в байтах (Смещение 2, длина 4) unsigned short bfReserved1; //Бесполезно (Смещение 6, длина 2) unsigned short bfReserved2; //Бесполезно (Смещение 8, длина 2) unsigned long bfOffBits; //Смещение до самого изображения (Смещение 10, длина 4) } BmpHeader; #pragma pack(pop) // Структура BITMAP INFO HEADER --------------------------------------------------------------------------------------------------------- typedef struct { unsigned long biSize; //Размер данной структуры в байтах. Опред. версия формата unsigned long biWidth; //Ширина изображения в пикселях. unsigned long biHeight; //Высота изображения в пикселях. unsigned short biPlanes; //Количество цветовых плоскостей и в формате BMP содержит единицу. unsigned short biBitCount; //Количество бит на пиксель. unsigned short biCompression; //Тип сжатия для сжатых изображений unsigned short biSizeImage; //Размер изображения в байтах. Может содержать ноль для BI_RGB-изображений. unsigned long biXPelsPerMeter; //Горизонтальное разрешение в пикселях на метр для целевого устройства. unsigned long biYPelsPerMeter; //Вертикальное разрешение в пикселях на метр для целевого устройства. unsigned short biClrUsed; //Количество используемых цветовых индексов в палитре. unsigned short biClrImportant; //Количество элементов палитры, необходимых для отображения изображения. } BmpImageInfo; // Структура TGA INFO HEADER --------------------------------------------------------------------------------------------------------- typedef struct { char idlength; char colourmaptype; char datatypecode; short int colourmaporigin; short int colourmaplength; char colourmapdepth; short int x_origin; short int y_origin; short width; short height; char bitsperpixel; char imagedescriptor; } TgaImageInfo; typedef struct { unsigned char r; unsigned char g; unsigned char b; //unsigned char rgbReserved; } RGB; void MergeBytes(RGB *,unsigned char *,int); void Code(FILE *, FILE *); void Decode(FILE *, FILE *); int spaw(int); int main(int argc, char *argv[]) { int ch; setlocale(LC_ALL, ""); FILE *BmpImage; FILE *TgaImage; printf("Code or decode?\n"); printf("1 - Code\n2 - Decode\n"); scanf("%d",&ch); if (ch == 1){ BmpImage = fopen("E:/Jazblki programmirovanija/Kursovaya_Revchenko_10-IT-3/Bmp_24_in.bmp","rb"); TgaImage = fopen("E:/Jazblki programmirovanija/Kursovaya_Revchenko_10-IT-3/TgaOut.tga","wb"); Code(BmpImage,TgaImage); } else { BmpImage = fopen("E:/Jazblki programmirovanija/Kursovaya_Revchenko_10-IT-3/BmpOut.bmp","wb"); TgaImage = fopen("E:/Jazblki programmirovanija/Kursovaya_Revchenko_10-IT-3/Tga_24_in.tga","rb"); Decode(TgaImage,BmpImage); } fclose(BmpImage); fclose(TgaImage); return 0; } void MergeBytes(RGB *pixel,unsigned char *p,int bytes) { if (bytes == 4) { pixel->r = p[2]; pixel->g = p[1]; pixel->b = p[0]; } else if (bytes == 3) { pixel->r = p[2]; pixel->g = p[1]; pixel->b = p[0]; } else if (bytes == 2) { pixel->r = (p[1] & 0x7c) << 1; pixel->g = ((p[1] & 0x03) << 6) | ((p[0] & 0xe0) >> 2); pixel->b = (p[0] & 0x1f) << 3; } } void Code(FILE *BmpImage, FILE *TgaImage) { BmpHeader bmpheader; BmpImageInfo bmpimageinfo; int pad; RGB *pixels; int size; int bytes2read; unsigned char tmp[5]; if (!BmpImage ) { printf("Ошибка чтения BMP-файла.\n"); exit(-1); } //Выравнивание структуры-------------------------------------------------- pad = sizeof(BmpHeader); printf("BmpHeader до выравнивания: %d\n", pad); if (pad > 14) { while (pad != 14) { pad -= 1; } } printf("BmpHeader после выравнивания: %d\n", pad); //--------------------------------------------------------------------------------------- if (fread(&bmpheader, pad, 1, BmpImage) != 1){ printf("Ошибка чтения заголовка Bmp-изображения\n"); exit(-1); } if (fread (&bmpimageinfo, sizeof(BmpImageInfo), 1, BmpImage) != 1 ){ printf("Ошибка чтения информации Bmp-изображения.\n"); exit(-1); } printf("_______Данные_о_BITMAP_FILE_HEADER_______\n"); printf("Тип файла : %c%c\n", bmpheader.b1, bmpheader.b2); printf("Размер файла : %d bytes\n", bmpheader.bfSize); printf("Резервный слот 1 : %d\n", bmpheader.bfReserved1); printf("Резервный слот 2 : %d\n", bmpheader.bfReserved2); printf("Смешение до изображения : %d bytes\n\n", bmpheader.bfOffBits); printf("_______Данные_о_BITMAP_INFO_HEADER_______\n"); printf("Размер структ. в байтах : %d bytes\n", bmpimageinfo.biSize); printf("Ширина изображения : %d px\n", bmpimageinfo.biWidth); printf("Высота изображения : %d px\n", bmpimageinfo.biHeight); printf("Кол. цветовых плоск. : %d\n", bmpimageinfo.biPlanes); printf("Кол. бит на пиксель : %d-bit\n", bmpimageinfo.biBitCount); printf("Тип сжатия : %d\n", bmpimageinfo.biCompression); bmpimageinfo.biSizeImage = bmpimageinfo.biXPelsPerMeter; bmpimageinfo.biXPelsPerMeter = bmpimageinfo.biYPelsPerMeter; bmpimageinfo.biYPelsPerMeter = bmpimageinfo.biClrUsed; bmpimageinfo.biClrUsed = 0; printf("Размер изобр. в байтах : %d bytes\n", bmpimageinfo.biSizeImage); printf("Горизонт. разрешение : %d px\n", bmpimageinfo.biXPelsPerMeter); printf("Вертикальное разрешение : %d px\n", bmpimageinfo.biYPelsPerMeter); printf("Кол. цветов. инд. в пал.: %d\n", bmpimageinfo.biClrUsed); printf("Кол. элементов палитры : %d\n\n", bmpimageinfo.biClrImportant); size = bmpimageinfo.biHeight * bmpimageinfo.biWidth; if ((pixels = (RGB *) malloc(size * sizeof(RGB))) == NULL){ printf("Malloc error\n"); } for (int i=0;i<size;i++) { pixels[i].r = 0; pixels[i].g = 0; pixels[i].b = 0; } // Считываем Цветовые индексы------------------------------------------------------------------------------------------------------------------- fseek(BmpImage, bmpheader.bfOffBits, 0); //смещение на bmpheader.bfOffBits = 54 символа (пропускаем данные о BmpHeader и BmpImageInfo) bytes2read = bmpimageinfo.biBitCount / 8; printf("Считывание\n"); if(size > 0){ for (int i=0; i<size; i++) { fread(tmp, 1, bytes2read, BmpImage); MergeBytes(&(pixels[i]),tmp,bytes2read); } printf("Цветовые индексы считаны\n"); } printf("Запись информации в Tga-header..\n"); putc(0,TgaImage); putc(0,TgaImage); putc(2,TgaImage); /* uncompressed RGB */ putc(0,TgaImage); putc(0,TgaImage); putc(0,TgaImage); putc(0,TgaImage); putc(0,TgaImage); putc(0,TgaImage); putc(0,TgaImage); /* X origin */ putc(0,TgaImage); putc(0,TgaImage); /* y origin */ putc((bmpimageinfo.biWidth & 0x00FF),TgaImage); putc((bmpimageinfo.biWidth & 0xFF00) / 256,TgaImage); putc((bmpimageinfo.biHeight & 0x00FF),TgaImage); putc((bmpimageinfo.biHeight & 0xFF00) / 256,TgaImage); putc(24,TgaImage); /* 24-bit bitmap */ putc(0,TgaImage); printf("Готово.\n"); printf("Запись информации о пикселях в Tga-изображение..\n"); for (int i=0;i<size;i++) { putc(pixels[i].b,TgaImage); putc(pixels[i].g,TgaImage); putc(pixels[i].r,TgaImage); } printf("Готово.\n"); } void Decode(FILE *TgaImage, FILE *BmpImage) { TgaImageInfo tgaimageinfo; int n=0,i,j; int bytes2read,skipover = 0; unsigned char tmp[5]; RGB *pixels; int size; if((!TgaImage)||(TgaImage==NULL)) { printf("File open failed\n"); exit(-1); } // Выводим поля хедера tgaimageinfo.idlength = fgetc(TgaImage); printf("ID length: %d\n",tgaimageinfo.idlength); tgaimageinfo.colourmaptype = fgetc(TgaImage); printf("Colourmap type: %d\n",tgaimageinfo.colourmaptype); tgaimageinfo.datatypecode = fgetc(TgaImage); printf("Image type: %d\n",tgaimageinfo.datatypecode); fread(&tgaimageinfo.colourmaporigin,2,1,TgaImage); printf("Colour map offset: %d\n",tgaimageinfo.colourmaporigin); fread(&tgaimageinfo.colourmaplength,2,1,TgaImage); printf("Colour map length: %d\n",tgaimageinfo.colourmaplength); tgaimageinfo.colourmapdepth = fgetc(TgaImage); printf("Colour map depth: %d\n",tgaimageinfo.colourmapdepth); fread(&tgaimageinfo.x_origin,2,1,TgaImage); printf("X origin: %d\n",tgaimageinfo.x_origin); fread(&tgaimageinfo.y_origin,2,1,TgaImage); printf("Y origin: %d\n",tgaimageinfo.y_origin); fread(&tgaimageinfo.width,2,1,TgaImage); printf("Width: %d\n",tgaimageinfo.width); fread(&tgaimageinfo.height,2,1,TgaImage); printf("Height: %d\n",tgaimageinfo.height); tgaimageinfo.bitsperpixel = fgetc(TgaImage); printf("Bits per pixel: %d\n",tgaimageinfo.bitsperpixel); tgaimageinfo.imagedescriptor = fgetc(TgaImage); printf("Descriptor: %d\n",tgaimageinfo.imagedescriptor); size = tgaimageinfo.width * tgaimageinfo.height; if ((pixels = (RGB *) malloc(size * sizeof(RGB))) == NULL){ printf("Malloc error\n"); } for (int i=0;i<size;i++) { pixels[i].r = 0; pixels[i].g = 0; pixels[i].b = 0; } skipover += tgaimageinfo.idlength; skipover += tgaimageinfo.colourmaptype * tgaimageinfo.colourmaplength; printf("Skipover = %d\n",skipover); fseek(TgaImage,skipover,0); printf("Считывание\n"); bytes2read = tgaimageinfo.bitsperpixel / 8; if (size>0){ for (int i=0; i<size; i++){ if (fread(tmp, 1, bytes2read, TgaImage) != bytes2read) { printf("Unexpected end of dile at pixel %d\n",i); exit(-1); } MergeBytes(&(pixels[i]), tmp, bytes2read); } printf("Цветовые индексы считаны\n"); } printf("Запись информации в Bmp-file-header..\n"); //_______Данные_о_BITMAP_FILE_HEADER_______ putc('B',BmpImage); putc('M',BmpImage); int sz = (size*bytes2read)+56; //размер putc(sz&0x00FF,BmpImage); sz = sz/256; putc(sz&0x00FF,BmpImage); sz = sz/256; putc(sz&0x00FF,BmpImage); sz = sz/256; putc(sz&0x00FF,BmpImage); sz = sz/256; putc(0,BmpImage); putc(0,BmpImage); putc(0,BmpImage);putc(0,BmpImage); putc(54,BmpImage); putc(0,BmpImage); putc(0,BmpImage); putc(0,BmpImage); //Смещение до изображения printf("Готово.\n"); printf("Запись информации в Bmp-info-header..\n"); //_______Данные_о_BITMAP_INFO_HEADER_______ putc(40,BmpImage); putc(0,BmpImage); putc(0,BmpImage); putc(0,BmpImage); int temp = tgaimageinfo.width; putc(temp&0x00FF,BmpImage); temp = temp/256; putc(temp&0x00FF,BmpImage); temp = temp/256; putc(temp&0x00FF,BmpImage); temp = temp/256; putc(temp&0x00FF,BmpImage); //ширина temp = tgaimageinfo.height; putc(temp&0x00FF,BmpImage); temp = temp/256; putc(temp&0x00FF,BmpImage); temp = temp/256; putc(temp&0x00FF,BmpImage); temp = temp/256; putc(temp&0x00FF,BmpImage) ; //высота putc(1,BmpImage); putc(0,BmpImage); //число плоскостей putc(tgaimageinfo.bitsperpixel,BmpImage); putc(0,BmpImage); //бит на пиксель putc(0,BmpImage);putc(0,BmpImage); putc(0,BmpImage); putc(0,BmpImage); //тип сжатия putc(0,BmpImage); putc(0,BmpImage); putc(0,BmpImage); putc(0,BmpImage); //0 или размер сжатого изображения в байтах temp = 945; putc(temp&0x00FF,BmpImage); temp = temp/256; putc(temp&0x00FF,BmpImage); temp = temp/256;putc(temp&0x00FF,BmpImage); temp = temp/256;putc(temp&0x00FF,BmpImage); //Горизонтальное разрешение, пиксел/м temp = 945; putc(temp&0x00FF,BmpImage); temp = temp/256; putc(temp&0x00FF,BmpImage); temp = temp/256;putc(temp&0x00FF,BmpImage); temp = temp/256;putc(temp&0x00FF,BmpImage); //Вертикальное разрешение, пиксел/м putc(0,BmpImage); putc(0,BmpImage); putc(0,BmpImage); putc(0,BmpImage);//Количество используемых цветов putc(0,BmpImage); putc(0,BmpImage); putc(0,BmpImage); putc(0,BmpImage);//Количество "важных" цветов. printf("Готово.\n"); printf("Запись информации о пикселях в Bmp-изображение..\n"); for (int i=0;i<size;i++) { putc(pixels[i].b,BmpImage); putc(pixels[i].g,BmpImage); putc(pixels[i].r,BmpImage); } printf("Готово.\n"); }
Может кто-то сможет его партировать на HiAsm? Для меня это к сожалению слишком сложно. (((
|