-1

I am working on a personal project using C++, and I am trying to write to a TGA file. I have no issues reading/opening the input file, but when I open the output file that I generate this is a snippet of what it displays: TGA displaying hex code

I created a small tester portion of my code, which reads in a TGA file and immediately writes it back out as a new TGA file. This is that section:

    //Create TRL template object image and TRL output object image
    Pixel pix;
    TRLImage trlTemp;
    TRLImage trlData;
    trlData = trlTemp;

    //Load and read data for the TRL template image
    ifstream trlTemplate("input/TRL template.tga", ios_base::binary);
    trlTemp.fileRead(trlTemplate, pix);
    ofstream test("output/test.tga", ios_base::binary);
    trlTemp.fileWrite(test);
    test.close();

Since it is probably an issue with my fileRead and fileWrite functions, I will attach those too:

void Image::fileRead(ifstream& inFile, Pixel& pix)
{
    //read in Header
    inFile.read((char*)&head.idLength, sizeof(head.idLength));
    inFile.read((char*)&head.colorMapType, sizeof(head.colorMapType));
    inFile.read((char*)&head.dataTypeCode, sizeof(head.dataTypeCode));
    inFile.read((char*)&head.colorMapOrigin, sizeof(head.colorMapOrigin));
    inFile.read((char*)&head.colorMapLength, sizeof(head.colorMapLength));
    inFile.read((char*)&head.colorMapDepth, sizeof(head.colorMapDepth));
    inFile.read((char*)&head.xOrigin, sizeof(head.xOrigin));
    inFile.read((char*)&head.yOrigin, sizeof(head.yOrigin));
    inFile.read((char*)&head.width, sizeof(head.width));
    inFile.read((char*)&head.height, sizeof(head.height));
    inFile.read((char*)&head.bitsPerPixel, sizeof(head.bitsPerPixel));
    inFile.read((char*)&head.imageDescriptor, sizeof(head.imageDescriptor));

    //read in ImageData
    for (int i = 0; i < head.height; i++)
    {
        for (int j = 0; j < head.width; j++)
        {
            inFile.read((char*)&pix.b, sizeof(pix.b));
            inFile.read((char*)&pix.g, sizeof(pix.g));
            inFile.read((char*)&pix.r, sizeof(pix.r));
            imageData.pixels.push_back(pix);
        }
    }
}
void Image::fileWrite(ofstream& outFile)
{
    outFile.write((char*)&head.idLength, sizeof(head.idLength));
    outFile.write((char*)&head.colorMapType, sizeof(head.colorMapType));
    outFile.write((char*)&head.dataTypeCode, sizeof(head.dataTypeCode));
    outFile.write((char*)&head.colorMapOrigin, sizeof(head.colorMapOrigin));
    outFile.write((char*)&head.colorMapLength, sizeof(head.colorMapLength));
    outFile.write((char*)&head.colorMapDepth, sizeof(head.colorMapDepth));
    outFile.write((char*)&head.xOrigin, sizeof(head.xOrigin));
    outFile.write((char*)&head.yOrigin, sizeof(head.yOrigin));
    outFile.write((char*)&head.width, sizeof(head.width));
    outFile.write((char*)&head.height, sizeof(head.height));
    outFile.write((char*)&head.bitsPerPixel, sizeof(head.bitsPerPixel));
    outFile.write((char*)&head.imageDescriptor, sizeof(head.imageDescriptor));

    int count = 0;
    for (short i = 0; i < head.height; i++)
    {
        for (short j = 0; j < head.width; j++)
        {
            outFile.write((char*)&imageData.pixels[count].b, sizeof(imageData.pixels[count].b));
            outFile.write((char*)&imageData.pixels[count].g, sizeof(imageData.pixels[count].g));
            outFile.write((char*)&imageData.pixels[count].r, sizeof(imageData.pixels[count].r));
            count++;
        }
    }
}
      

I also want to note that I have structs created for the image header (head, in the code samples) and image body (imageData, in the code samples). The Image class where the above functions are from contains a Header object called head and an ImageData object called imageData. I really have no idea what the issue is because I have used these functions in the past and they worked fine. Please let me know if you catch any errors in my code, or if you have experienced this issue what worked for you. Thanks!

Amy
  • 1
  • 1
  • Only discrepancy that jumps out at me is the read loop is `for (int i = 0; i < head.height; i++)`, using `int` and the write loop is `or (short i = 0; i < head.height; i++)` using `short`, but if you had an image big enough to overflow `short`, something that might be impossible (I don't know the TGA format), I'd expect infinite loop. – user4581301 Jul 07 '21 at 19:07
  • 1
    If you `diff` the input and output files are they the same? – user4581301 Jul 07 '21 at 19:12
  • @user4581301 Oddly enough, yes. When you asked I checked it out, and I totally thought there would be some difference. But I compared the output file "test" to the "trlTemp" file and it says they are the same. I also went ahead and changed my loop from short to int, but that didn't fix the issue. – Amy Jul 07 '21 at 19:32
  • If the files are the same, the problem has to be something with how the tools are interpreting the file. Are you trying to open the file in an IDE which may be preferring an internal file viewer (which shows a binary file in hex) rather than the system's registered tga file viewer? If you are, what happens when you open the file from the OS's file browser? – user4581301 Jul 07 '21 at 19:54
  • @user4581301 I don't have a problem opening any other tga files in my viewer. I tried a different viewer and it says the file is corrupted or damaged. I still think that it has something to do with the way the object is being written into the file. I can't think of anything else. – Amy Jul 07 '21 at 20:19
  • If you have two identical files but one file is valid but the other isn't, someone is lying. – user4581301 Jul 07 '21 at 20:26
  • @user4581301 I tried an online tool that compares the text of the files and the only difference is that my input file is slightly longer than the output file. All the characters are the same. But the text doesn't mean anything to me. It is just one long line of special characters, so I can't figure out the issue from that. – Amy Jul 07 '21 at 21:22
  • What OS are you using. There are a number of differencing tools built right into *nix systems, [`cmp` being a good option](https://man7.org/linux/man-pages/man1/cmp.1.html) and are often ported to Windows and packaged with development environments ([Msys2 is a good example](https://www.msys2.org/), though in that case it's more the reverse--the development environment is packaged with the tools) – user4581301 Jul 07 '21 at 21:28
  • 1
    Your code is incomplete and unrunnable, btw. You also assume your multibyte data is little-endian. – Mark Setchell Jul 07 '21 at 22:12

1 Answers1

-1

I ended up figuring out my problem. My read and write functions only included pixels for b, g, and r, but many TGA files have 32 bits per pixel and require a 4th channel of data per pixel. This 4th channel is called the alpha channel. The fix required me to simply add a line to read and write in the alpha channel.

Amy
  • 1
  • 1