void Image::flip() { // create a temp swap space size_t bpChannel = getBytesPerChannel(); unsigned char *buf = new unsigned char[bpChannel]; for (size_t i=0; i<m_width; ++i) { for (size_t j=0; j<m_height/2; ++j) { for (size_t k=0; k<m_nChannels; ++k) { // swap pixels memcpy(buf, &m_data[m_bytesPerPixel*(j*m_height + i) + bpChannel*k], bpChannel); memcpy( &m_data[m_bytesPerPixel*(j*m_height + i) + bpChannel*k], &m_data[m_bytesPerPixel*((m_height-1-j)*m_height + i) + bpChannel*k], bpChannel); memcpy(&m_data[m_bytesPerPixel*((m_height-1-j)*m_height + i) + bpChannel*k], buf, bpChannel); } } } }
bool ImagePNG::save(std::string filename, int compression_level) { FILE *file; #ifndef NDEBUG std::cout << "Writing PNG file " << filename << std::endl; #endif /* make sure the file is there and open it read-only (binary) */ if ((file = fopen(filename.c_str(), "wb")) == NULL) { std::cerr << "File write access failed : " << filename << std::endl; return false; } png_structp PNG_writer = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (PNG_writer == NULL) { std::cerr << "png_create_write_struct failed for file "<< filename << std::endl; fclose(file); return false; } png_infop PNG_info = png_create_info_struct(PNG_writer); if (PNG_info == NULL) { std::cerr << "png_create_info_struct failed for file " << filename << std::endl; png_destroy_write_struct(&PNG_writer, NULL); fclose(file); return false; } if (setjmp(png_jmpbuf(PNG_writer))) { std::cerr << "Writing failed for PNG file " << filename << std::endl; png_destroy_write_struct(&PNG_writer, &PNG_info); fclose(file); return false; } //png_init_io(PNG_writer, file); png_set_write_fn(PNG_writer, file, png_my_write_data, png_default_flush); png_uint_32 width, height; png_uint_32 bit_depth, channels, color_type; width = getWidth(); height = getHeight(); bit_depth = getBytesPerChannel() * 8; channels = getChannelCount(); if (channels == 1) color_type = PNG_COLOR_TYPE_GRAY; else if (channels == 2) color_type = PNG_COLOR_TYPE_GRAY_ALPHA; else if (channels == 3) color_type = PNG_COLOR_TYPE_RGB; else color_type = PNG_COLOR_TYPE_RGB_ALPHA; if (bit_depth != 8) { std::cerr << "Unsupported bitdepth "<< bit_depth <<" to write to PNG file "<<filename<<std::endl; png_destroy_write_struct(&PNG_writer, &PNG_info); fclose(file); return false; } #ifndef NDEBUG std::cout << "PNG image "<<filename<<": "<<width<<"x"<<height<<"x"<<bit_depth*channels<<std::endl; #endif png_set_IHDR(PNG_writer, PNG_info, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); /* set the zlib compression level */ if (compression_level!=-1) { if (compression_level>=0 && compression_level<=9) png_set_compression_level(PNG_writer, compression_level); else std::cerr << "ERROR: compression level must be a value between 0 and 9" << std::endl; } png_byte** PNG_rows = (png_byte**)malloc(height * sizeof(png_byte*)); unsigned char *data = getPixels(); unsigned lineSize = getLineSize(0); for (png_uint_32 row = 0; row < height; ++row) PNG_rows[height - 1 - row] = data+row*lineSize; png_set_rows(PNG_writer, PNG_info, PNG_rows); png_write_png(PNG_writer, PNG_info, PNG_TRANSFORM_IDENTITY, NULL); free(PNG_rows); png_destroy_write_struct(&PNG_writer, &PNG_info); fclose(file); return true; }
int ofPixels_<PixelType>::getBitsPerChannel() const{ return getBytesPerChannel() * 8; }
int ofPixels_<PixelType>::getBytesPerPixel() const{ return getBytesPerChannel() * channels; }