Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Language IDEs » C / C++ IDE (CDT) » Trying to convert data to an image
Trying to convert data to an image [message #1828624] Mon, 15 June 2020 10:38 Go to next message
Guadalupe Hairston is currently offline Guadalupe HairstonFriend
Messages: 1
Registered: June 2020
Junior Member
Hello.
I've been trying to convert a hex string to a image for a while now. I found most of the conversion code on github, an I called it and was able to figure out the first step of what I needed to do, turn the hex string into data.

Now, I need to turn the data into an image. There is already a function I'm trying to call that I'm pretty sure will do what I want, it's called BlockDecompressImageDXT5. I'm pretty sure I want to call that after I call DecompressImageDXT5, so I can convert the data to an actual image.

The problem is, I'm pretty confused on where I should call in my second function to convert the data to an image, as well as how to save the image to a .jpeg or .png, I don't know what image format I want because I want to use the easiest one lol.

Here is my current code:
#include<iostream>
#include<stdlib.h>
#include<fstream>

using namespace std;

void DecompressBlockDXT5(unsigned long, unsigned long, unsigned long, const unsigned char*, unsigned long*);
unsigned long PackRGBA(unsigned char, unsigned char, unsigned char, unsigned char);
void BlockDecompressImageDXT5(unsigned long, unsigned long, const unsigned char*, unsigned long*);

std::string hex_string = "BFBDBAB8B5B3B0ADABA8A6A3A19E9C999694918F8C8A878582807D7A787573706E6B696663615E5C595754524F4D4A474542403D3B";
//placeholder hex string

int main(){

    unsigned long x = 0;
    unsigned long y = 0;
    unsigned long width = 512;
    unsigned long height = 512;
    //std::string key = "thasodif028374woiefjasdfjsj";
    const unsigned char* blockStorage = reinterpret_cast<const unsigned char*>(hex_string.data());
    unsigned long* image = new unsigned long[ width * height];


  

    DecompressBlockDXT5(x,y,width,blockStorage,image);

    std::ofstream fout("image.dat");
    for(int i = 0; i < (width * height); ++i)
    {
    	fout << image[i];
    }

    BlockDecompressImageDXT5(width,height,blockStorage,image);

    delete[] image;

}
/**
 * void DecompressBlockDXT5(): Decompresses one block of a DXT5 texture and stores the resulting pixels at the appropriate offset in 'image'.
 *
 * unsigned long x:						x-coordinate of the first pixel in the block.
 * unsigned long y:						y-coordinate of the first pixel in the block.
 * unsigned long width: 				width of the texture being decompressed.
 * unsigned long height:				height of the texture being decompressed.
 * const unsigned char *blockStorage:	pointer to the block to decompress.
 * unsigned long *image:				pointer to image where the decompressed pixel data should be stored.
 */
void DecompressBlockDXT5(unsigned long x, unsigned long y, unsigned long width, const unsigned char *blockStorage, unsigned long *image) {
	unsigned char alpha0 = *reinterpret_cast<const unsigned char *>(blockStorage);
	unsigned char alpha1 = *reinterpret_cast<const unsigned char *>(blockStorage + 1);

	const unsigned char *bits = blockStorage + 2;
	unsigned long alphaCode1 = bits[2] | (bits[3] << 8) | (bits[4] << 16) | (bits[5] << 24);
	unsigned short alphaCode2 = bits[0] | (bits[1] << 8);

	unsigned short color0 = *reinterpret_cast<const unsigned short *>(blockStorage + 8);
	unsigned short color1 = *reinterpret_cast<const unsigned short *>(blockStorage + 10);

	unsigned long temp;

	temp = (color0 >> 11) * 255 + 16;
	unsigned char r0 = (unsigned char)((temp/32 + temp)/32);
	temp = ((color0 & 0x07E0) >> 5) * 255 + 32;
	unsigned char g0 = (unsigned char)((temp/64 + temp)/64);
	temp = (color0 & 0x001F) * 255 + 16;
	unsigned char b0 = (unsigned char)((temp/32 + temp)/32);

	temp = (color1 >> 11) * 255 + 16;
	unsigned char r1 = (unsigned char)((temp/32 + temp)/32);
	temp = ((color1 & 0x07E0) >> 5) * 255 + 32;
	unsigned char g1 = (unsigned char)((temp/64 + temp)/64);
	temp = (color1 & 0x001F) * 255 + 16;
	unsigned char b1 = (unsigned char)((temp/32 + temp)/32);

	unsigned long code = *reinterpret_cast<const unsigned long *>(blockStorage + 12);

	for (int j=0; j < 4; j++) {
		for (int i=0; i < 4; i++) {
			int alphaCodeIndex = 3*(4*j+i);
			int alphaCode;

			if (alphaCodeIndex <= 12) {
				alphaCode = (alphaCode2 >> alphaCodeIndex) & 0x07;
			} else if (alphaCodeIndex == 15) {
				alphaCode = (alphaCode2 >> 15) | ((alphaCode1 << 1) & 0x06);
			} else { // alphaCodeIndex >= 18 && alphaCodeIndex <= 45
				alphaCode = (alphaCode1 >> (alphaCodeIndex - 16)) & 0x07;
			}

			unsigned char finalAlpha;
			if (alphaCode == 0) {
				finalAlpha = alpha0;
			} else if (alphaCode == 1) {
				finalAlpha = alpha1;
			} else {
				if (alpha0 > alpha1) {
					finalAlpha = ((8-alphaCode)*alpha0 + (alphaCode-1)*alpha1)/7;
				} else {
					if (alphaCode == 6) {
						finalAlpha = 0;
					} else if (alphaCode == 7) {
						finalAlpha = 255;
					} else {
						finalAlpha = ((6-alphaCode)*alpha0 + (alphaCode-1)*alpha1)/5;
					}
				}
			}

			unsigned char colorCode = (code >> 2*(4*j+i)) & 0x03;

			unsigned long finalColor;
			switch (colorCode) {
				case 0:
					finalColor = PackRGBA(r0, g0, b0, finalAlpha);
					break;
				case 1:
					finalColor = PackRGBA(r1, g1, b1, finalAlpha);
					break;
				case 2:
					finalColor = PackRGBA((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, finalAlpha);
					break;
				case 3:
					finalColor = PackRGBA((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, finalAlpha);
					break;
			}

			if (x + i < width) image[(y + j)*width + (x + i)] = finalColor;
		}
	}
}

/**
 * unsigned long PackRGBA(): Helper method that packs RGBA channels into a single 4 byte pixel.
 *
 * unsigned char r: red channel.
 * unsigned char g: green channel.
 * unsigned char b: blue channel.
 * unsigned char a: alpha channel.
 */


unsigned long PackRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
	return ((r << 24) | (g << 16) | (b << 8) | a);
}

/**
 * void BlockDecompressImageDXT5(): Decompresses all the blocks of a DXT5 compressed texture and stores the resulting pixels in 'image'.
 *
 * unsigned long width:               Texture width.
 * unsigned long height:              Texture height.
 * const unsigned char *blockStorage: pointer to compressed DXT5 blocks.
 * unsigned long *image:              pointer to the image where the decompressed pixels will be stored.
 */

void BlockDecompressImageDXT5(unsigned long width, unsigned long height, const unsigned char *blockStorage, unsigned long *image)
{
	unsigned long blockCountX = (width + 3) / 4;
	unsigned long blockCountY = (height + 3) / 4;
	unsigned long blockWidth = (width < 4) ? width : 4;
	unsigned long blockHeight = (height < 4) ? height : 4;

	for (unsigned long j = 0; j < blockCountY; j++) {
		for (unsigned long i = 0; i < blockCountX; i++) DecompressBlockDXT5(i*4, j*4, width, blockStorage + i * 16, image);
		blockStorage += blockCountX * 16;
	}
}
Re: Trying to convert data to an image [message #1828639 is a reply to message #1828624] Mon, 15 June 2020 13:53 Go to previous message
David VavraFriend
Messages: 1426
Registered: October 2012
Senior Member
The are a number of forums regarding DXT but this is not one of them.
This forum is for dealing with issues with Eclipse/CDT.
Programming questions are off-topic here.
Previous Topic:Feature Request - Cleaner project root navigation
Next Topic:Open file in current workspace from command line (reuse the open workspace)
Goto Forum:
  


Current Time: Fri Apr 26 18:03:36 GMT 2024

Powered by FUDForum. Page generated in 0.03003 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top