[Solved] convert raw image data to png image data in memory?

is there any way to convert a raw image data (unsigned char * data) to png image data in memory?

i got the raw data from RenderTexture and No i don’t want to use saveToFile() method because i want to convert it in memory.

after searching for a quite a while it appears that there are two ways to accomplish this . the first is Microsoft windows only library (that’s way i am not going with it) called Windows Imaging Component (WIC) the other is libpng which It is a platform-independent library that contains C functions for handling PNG images.
and here is the fun part !! … both libraries are integrated and used internally by cocos2d-x so you don’t have to download or do anything special because they were right there in front of you the whole time
i choose the second way (libpng) to accomplish this crazy idea.

so first in order to use this integrated library i have to include it and since am on pc i included the win32 version of the library but remember that there are other versions of it depending on your platform (win32|android|mac|ios|)

#include "png\include\win32\png.h"

in case you get linker errors after you include the header file you have to add the full path of the prebuilt version of library in your IDE and you have do it accordingly to your platform so if you are on windows pc like me you have to take the full path of the file libpng.lib which is located in png\prbulilt\your platform\libpng.lib and then after you get the full path of file accordingly to your platform and in case you are on visual studio like me just right click on your working project => properties => expand linker option => input =>additional dependency then add the full path there and add after it ; so the path should look like this when you add it:

C:\Users\your username here\Documents\project name here\cocos2d\external\png\prebuilt\your platform here\libpng.lib;

Then after that copy this code into where you wanna use it (i altered it a bite from the original) :

static void PngWriteCallback(png_structp  png_ptr, png_bytep data, png_size_t length) {
	auto p = (std::vector<uint8_t>*)png_get_io_ptr(png_ptr);
	p->insert(p->end(), data, data + length);
}

struct TPngDestructor {
	png_struct *p;
	TPngDestructor(png_struct *p) : p(p)  {}
	~TPngDestructor() { if (p) { png_destroy_write_struct(&p, NULL); } }
};

void WritePngToMemory(size_t w, size_t h, const uint8_t *dataRGBA, std::vector<uint8_t>* out) {
	out->clear();
	png_structp p = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	TPngDestructor destroyPng(p);
	png_infop info_ptr = png_create_info_struct(p);
	png_set_IHDR(p, info_ptr, w, h, 8,
		PNG_COLOR_TYPE_RGBA,
		PNG_INTERLACE_NONE,
		PNG_COMPRESSION_TYPE_DEFAULT,
		PNG_FILTER_TYPE_DEFAULT);
	//png_set_compression_level(p, 1);
	std::vector<uint8_t*> rows(h);
	for (size_t y = 0; y < h; ++y)
		rows[y] = (uint8_t*)dataRGBA + y * w * 4;
	png_set_rows(p, info_ptr, &rows[0]);
	png_set_write_fn(p, out, PngWriteCallback, NULL);
	png_write_png(p, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
}

The code is not mind and I found it in here if you wanna check:


And here how I used it:

std::vector<uint8_t> out;
auto img = rt->newImage();

WritePngToMemory(img->getWidth(), img->getHeight(), img->getData(), &out);
// some code
CC_SAFE_DELETE_ARRAY(img);