Skip to content

Instantly share code, notes, and snippets.

@non-static
Last active January 8, 2020 04:32
Show Gist options
  • Save non-static/8f5b2ee17d6dbf3d200132ce64e226aa to your computer and use it in GitHub Desktop.
Save non-static/8f5b2ee17d6dbf3d200132ce64e226aa to your computer and use it in GitHub Desktop.
Need libpng v1.6.x.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iomanip>
#include <cstring>
#include <png.h> // Need to be libpng v1.6.x
using namespace std;
int read_png(string file_path, unsigned char** buffer)
{
ifstream is(file_path, ifstream::binary);
if (is)
{
is.seekg (0, is.end);
int length = is.tellg();
is.seekg (0, is.beg);
*buffer = new unsigned char [length];
cout << "Reading " << length << " characters ... ";
is.read ((char*)(&(*buffer)[0]),length);
if (is)
cout << "all characters read successfully." << endl;
else
cout << "error: only " << is.gcount() << " could be read" << endl;
is.close();
return length;
}
}
void write_png(string file_path, unsigned char* buffer, int length)
{
ofstream os(file_path, ofstream::binary);
cout << "Writing " << length << " characters ...";
os.write((char*)buffer, length);
if (os)
cout << "all characters written successfully." << endl;
else
cout << "error" << endl;
os.close();
}
int main()
{
const string Input_PNG = "pic/c.png";
const string Output_PNG = "output/output.png";
cout << "Input file name: " << Input_PNG << endl;
unsigned char* file_buffer = nullptr;
int length = read_png(Input_PNG, &file_buffer);
// print_mem(buffer, length);
cout << "PNG_LIBPNG_VER_STRING: " << PNG_LIBPNG_VER_STRING << endl;
bool is_png = 0 == png_sig_cmp(file_buffer, 0, 8);
cout << "Is PNG: " << is_png << endl;
// READING......
png_image image; /* The control structure used by libpng */
/* Initialize the 'png_image' structure. */
memset(&image, 0, (sizeof image));
image.version = PNG_IMAGE_VERSION;
if (png_image_begin_read_from_memory(&image, file_buffer, length) == 0)
{
return -1;
}
png_bytep buffer;
image.format = PNG_FORMAT_BGR;
size_t input_data_length = PNG_IMAGE_SIZE(image);
if (input_data_length != 720 * 720 * 3) {
printf("input_data_length:%zd\n", input_data_length);
return -1;
}
buffer = (png_bytep)malloc(input_data_length);
memset(buffer, 0, input_data_length);
if (png_image_finish_read(&image, NULL /*background*/, buffer,
0 /*row_stride*/, NULL /*colormap*/) == 0)
{
return -1;
}
// MODIFICATION ......
for (int i = 0; i < input_data_length; i++)
{
buffer[i] = ~buffer[i];
}
// WRITING......
png_image wimage;
memset(&wimage, 0, (sizeof wimage));
wimage.version = PNG_IMAGE_VERSION;
wimage.format = PNG_FORMAT_BGR;
wimage.height = 720;
wimage.width = 720;
size_t wlength = 0;
// Get memory size
bool wresult = png_image_write_to_memory(&wimage, nullptr, &wlength, 0, buffer, 0, nullptr);
if (!wresult)
{
cout << "Error: " << image.message << endl;
}
// Real write to memory
unsigned char* wbuffer = (unsigned char*)malloc(wlength);
wresult = png_image_write_to_memory(&wimage, wbuffer, &wlength, 0, buffer, 0, nullptr);
write_png(Output_PNG, wbuffer, wlength);
free(wbuffer);
free(buffer);
free(file_buffer);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment