Last active
January 8, 2020 04:32
-
-
Save non-static/8f5b2ee17d6dbf3d200132ce64e226aa to your computer and use it in GitHub Desktop.
Need libpng v1.6.x.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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