# Wie kann ich eine TGA- datei in C öffnen?



## fantastico (27. August 2006)

Hallo,
ich bin gerade dabei was in der Programmierumgebung C zu basteln;
ich möchte also ein Programmchen schreiben, mit dem sich TGA- Bilddateien  öffnen und bearbeiten lassen. Wenn die Datei geöffnet wird, muss das Programm ( mit ein paar Klicken des Benutzers auf der Laufbahn einer Buchstabe des TGA-Bildes, z.B "n" )diese Buchstabe nachbilden.

Wer könnte mir helfen  erstmal den ersten Schritt, also die Bilddatei zu öffnen, zu machen?

Danke


----------



## Flegmon (27. August 2006)

Hi,

um eine tga zu schreiben oder auszulesen, musst du nur ihren Aufbau wissen.
Nach kurzem googln bin ich auf folgenden link gestoßen http://www.gamers.org/dEngine/quake3/TGA.txt
Dort wird der Aufbau von TGA dateien beschrieben.
Du musst nichts weiter machen als die Datei zu öffnen und nach den Angaben auszulesen.

EDIT: oder du nutzt irgend eine Bibliothek -> google


----------



## fantastico (28. August 2006)

Das hat mir ein stück geholfen; danke dafür


----------



## Kriz (29. August 2006)

Hallo,

wenn ich dich richtig verstanden habe, soll dein Programm aus einer TGA Datei heraus  Buchstaben erkennen? Ich möchte dich ja nicht entmutigen, aber hast du auch nur den blassesten Schimmer, _was_ du da machen willst?

Du müsstest das TGA Bild nach dem Laden vorzugsweise vektorisieren, d.h. in eine vektorbasierte Darstellung konvertieren, um danach anhand von bestimmten Algorithmen nach Buchstabenmustern suchen zu lassen. Ein 'n' kann in vielen Formen und Varianten existieren. Nicht umsonst sind OCR Systeme bis heute recht fehleranfällig (bei 5000 Zeichen sind eine Fehlerquote von guten 5% immernoch 250 falsch erkannte Zeichen) und werden selten von Einzelleuten, sondern von professionellen Entwicklerteams programmiert.

Sollte ich dich falsch verstanden haben, wünsche ich dir trotzdem viel Erfolg bei deiner Idee


----------



## fantastico (29. August 2006)

Hallo Allerseits und Danke für die jeweiligen Beiträge. ich lerne "C" und habe nur  wenig Erfahrung; dabei wurde es mir beraten, dass die bestmöglichkeit die Sprache zu lernen, ist programmchen selber zu schreiben.

Ich habe  mit dem Programm  (unten) die Bilddatei geöffnet.
Ich programmiere mit LCC; Das Programm liest die Datei und schreibt sie in eine unkomprimierte TGA- Datei um; diese Datei ist grösser als die ursprungliche und ist dabei gespiegelt... verstehe nicht warum!

Die neue Datei ("tgatest.tga": eigentlich, die die gern auf einem Fernster erscheinen sollte) wird im LCC- Verzeichnis generiert.  wie kann ich es so umprogrammieren, dass die unkomprimierte Datei in ein Fenster beim starten des programms erscheint oder lieber mithilfe einer GUI  zur Bearbeitung geöffnet wird?

 1) Kritz, das programm soll nicht aus einer TGA Datei heraus Buchstaben erkennen.
Die tga- Datei "tgatest.tga " wird in einem fenster (Zum Anschauen und Bearbeiten) geöffnet. wie ich die Bearbeitung programmiere, muss ich mich sclauch machen; mit mouse- Events vielleicht? ein paar Tips würden mir bestimmt ein Stück näher an die Lösung bringen.

2) Mit dem Clicken (nur auf Graustufen) auf bestimmten Punkten der Buchstabe "r", "a","n","t" soll das Programm diese((Punkten) binden und somit die Buchstabe nachbilden. Wird es auf weisser Fläche(nicht auf Graustufen) gecklickt, erkennt das programm nichts und bildet somit keine Verbindung zwischen den durch Clicken erzeugten Punkten. 

--------------------------CODE-------------------------

```
#include "stdio.h"
#include "stdlib.h"
#include "math.h"

/*
   The following is rather crude demonstration code to read
   uncompressed and compressed TGA files of 16, 24, or 32 bit
   TGA.
   
*/

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;
} HEADER;

typedef struct {
   unsigned char r,g,b,a;
} PIXEL;

void MergeBytes(PIXEL *,unsigned char *,int);

int main(int argc,char **argv)
{

   int n=0,i,j;
   int bytes2read,skipover = 0;
   unsigned char p[5];
   FILE *fptr;
   HEADER header;
   PIXEL *pixels;

   if (argc < 2) {
      fprintf(stderr,"Usage: %s tgafile\n",argv[0]);
      exit(-1);
   }

   /* Open the file */
   if ((fptr = fopen(argv[1],"rb")) == NULL) {
      fprintf(stderr,"File open failed\n");
      exit(-1);
   }

   /* Display the header fields */
   header.idlength = fgetc(fptr);
   fprintf(stderr,"ID length:         %d\n",header.idlength);
   header.colourmaptype = fgetc(fptr);
   fprintf(stderr,"Colourmap type:    %d\n",header.colourmaptype);
   header.datatypecode = fgetc(fptr);
   fprintf(stderr,"Image type:        %d\n",header.datatypecode);
   fread(&header.colourmaporigin,2,1,fptr);
   fprintf(stderr,"Colour map offset: %d\n",header.colourmaporigin);
   fread(&header.colourmaplength,2,1,fptr);
   fprintf(stderr,"Colour map length: %d\n",header.colourmaplength);
   header.colourmapdepth = fgetc(fptr);
   fprintf(stderr,"Colour map depth:  %d\n",header.colourmapdepth);
   fread(&header.x_origin,2,1,fptr);
   fprintf(stderr,"X origin:          %d\n",header.x_origin);
   fread(&header.y_origin,2,1,fptr);
   fprintf(stderr,"Y origin:          %d\n",header.y_origin);
   fread(&header.width,2,1,fptr);
   fprintf(stderr,"Width:             %d\n",header.width);
   fread(&header.height,2,1,fptr);
   fprintf(stderr,"Height:            %d\n",header.height);
   header.bitsperpixel = fgetc(fptr);
   fprintf(stderr,"Bits per pixel:    %d\n",header.bitsperpixel);
   header.imagedescriptor = fgetc(fptr);
   fprintf(stderr,"Descriptor:        %d\n",header.imagedescriptor);

   /* Allocate space for the image */
   if ((pixels = malloc(header.width*header.height*sizeof(PIXEL))) == NULL) {
      fprintf(stderr,"malloc of image failed\n");
      exit(-1);
   }
   for (i=0;i<header.width*header.height;i++) {
      pixels[i].r = 0;
      pixels[i].g = 0;
      pixels[i].b = 0;
      pixels[i].a = 0;
   }

   /* What can we handle */
   /*if (header.datatypecode != 2 && header.datatypecode != 10) {
      printf(stderr,"Can only handle image type 2 and 10\n");
      exit(-1);
   }*/
   if (header.bitsperpixel != 16 &&
       header.bitsperpixel != 24 && header.bitsperpixel != 32) {
      fprintf(stderr,"Can only handle pixel depths of 16, 24, and 32\n");
      exit(-1);
   }
   if (header.colourmaptype != 0 && header.colourmaptype != 1) {
      fprintf(stderr,"Can only handle colour map types of 0 and 1\n");
      exit(-1);
   }

   /* Skip over unnecessary stuff */
   skipover += header.idlength;
   skipover += header.colourmaptype * header.colourmaplength;
   fprintf(stderr,"Skip over %d bytes\n",skipover);
   fseek(fptr,skipover,SEEK_CUR);

   /* Read the image */
   bytes2read = header.bitsperpixel / 8;
   while (n < header.width * header.height) {
      if (header.datatypecode == 2) {                     /* Uncompressed */
         if (fread(p,1,bytes2read,fptr) != bytes2read) {
            fprintf(stderr,"Unexpected end of file at pixel %d\n",i);
            exit(-1);
         }
         MergeBytes(&(pixels[n]),p,bytes2read);
         n++;
      } else if (header.datatypecode == 10) {             /* Compressed */
         if (fread(p,1,bytes2read+1,fptr) != bytes2read+1) {
            fprintf(stderr,"Unexpected end of file at pixel %d\n",i);
            exit(-1);
         }
         j = p[0] & 0x7f;
         MergeBytes(&(pixels[n]),&(p[1]),bytes2read);
         n++;
         if (p[0] & 0x80) {         /* RLE chunk */
            for (i=0;i<j;i++) {
               MergeBytes(&(pixels[n]),&(p[1]),bytes2read);
               n++;
            }
         } else {                   /* Normal chunk */
            for (i=0;i<j;i++) {
               if (fread(p,1,bytes2read,fptr) != bytes2read) {
                  fprintf(stderr,"Unexpected end of file at pixel %d\n",i);
                  exit(-1);
               }
               MergeBytes(&(pixels[n]),p,bytes2read);
               n++;
            }
         }
      }
   }
   fclose(fptr);

   /* Write the result as a uncompressed TGA */
   if ((fptr = fopen("tgatest.tga","wb")) == NULL) {
      fprintf(stderr,"Failed to open outputfile\n");
      exit(-1);
   }
   putc(0,fptr);
   putc(0,fptr);
   putc(2,fptr);                         /* uncompressed RGB */
   putc(0,fptr); putc(0,fptr);
   putc(0,fptr); putc(0,fptr);
   putc(0,fptr);
   putc(0,fptr); putc(0,fptr);           /* X origin */
   putc(0,fptr); putc(0,fptr);           /* y origin */
   putc((header.width & 0x00FF),fptr);
   putc((header.width & 0xFF00) / 256,fptr);
   putc((header.height & 0x00FF),fptr);
   putc((header.height & 0xFF00) / 256,fptr);
   putc(32,fptr);                        /* 24 bit bitmap */
   putc(0,fptr);
   for (i=0;i<header.height*header.width;i++) {
      putc(pixels[i].b,fptr);
      putc(pixels[i].g,fptr);
      putc(pixels[i].r,fptr);
      putc(pixels[i].a,fptr);
   }
   fclose(fptr);
}

void MergeBytes(PIXEL *pixel,unsigned char *p,int bytes)
{
   if (bytes == 4) {
      pixel->r = p[2];
      pixel->g = p[1];
      pixel->b = p[0];
      pixel->a = p[3];
   } else if (bytes == 3) {
      pixel->r = p[2];
      pixel->g = p[1];
      pixel->b = p[0];
      pixel->a = 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;
      pixel->a = (p[1] & 0x80);
   }
}
```

-------------------------------------------------------------

Ich würde mich auf  Tips/oder sogar Korrekturen  freuen;  

*PS: Die Dateien "rant.tga" (Ursprungsdatei)  und "tgatest.tga" (auf dem fenster und zu bearbeitende Datei) befinden sich im Anhang*


----------

