[SOLVED] CS python algorithm /*

$25

File Name: CS_python_algorithm_/*.zip
File Size: 207.24 KB

5/5 - (1 vote)

/*
Author: Yotam Gingold
License: Public Domain [CC0](http://creativecommons.org/publicdomain/zero/1.0/)
GitHub: https://github.com/yig/yimg
*/

#include image.h

#include
#include
#include // malloc, free, realloc

#include
#include // copy
#include // tolower
#include // move

// For load()
#define STB_IMAGE_IMPLEMENTATION
#include stb_image.h

// For save()
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include stb_image_write.h

// For rescale()
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#include stb_image_resize.h

namespace
{
/// From my: stl.h

// Behaves like the python os.path.splitext() function.
inline std::pair< std::string, std::string > os_path_splitext( const std::string& path )
{
const std::string::size_type split_dot = path.find_last_of( . );
const std::string::size_type split_slash = path.find_last_of( / );
if( split_dot != std::string::npos && (split_slash == std::string::npos || split_slash < split_dot) )return std::make_pair( path.substr( 0, split_dot ), path.substr( split_dot ) );elsereturn std::make_pair( path, std::string() );}}namespace graphics101{static_assert( sizeof( ColorRGBA8 ) == 4, “Color struct shouldn’t be padded” );Image::Image() {}Image::Image( const Image& rhs ){*this = rhs;}Image::Image( Image&& rhs ){*this = std::move( rhs );}Image::Image( int width_, int height_ ): m_width( width_ ), m_height( height_ ){// Dimensions must be non-negative.assert( width_ >= 0 && height_ >= 0 );
// Dimensions must be both 0 or both non-zero.
assert( width_ > 0 == height_ > 0 );

// Stop with m_data = nullptr (set by the default initializer in the header).
if( width_ == 0 || height_ == 0 ) return;

m_data = reinterpret_cast ( malloc( width_ * height_ * sizeof(ColorRGBA8) ) );
}

Image::Image( int width_, int height_, ColorRGBA8 color )
: Image( width_, height_ )
{
fill( color );
}

Image::Image( const ColorRGBA8* data, int width, int height )
: Image::Image( width, height )
{
memcpy( m_data, data, width * height * sizeof(ColorRGBA8) );
}

Image::Image( const ColorRGBA8* data, int width, int height, int pixels_per_row )
: Image::Image( width, height )
{
for( int j = 0; j < height; ++j ) {memcpy( scanline(j), data + j*pixels_per_row, width * sizeof(ColorRGBA8) );}}Image&Image::operator=( const Image& rhs ){if( !rhs.m_data ){assert( 0 == rhs.m_width );assert( 0 == rhs.m_height );clear();return *this;}if( m_width != rhs.m_width || m_height != rhs.m_height ){m_width = rhs.m_width;m_height = rhs.m_height;m_data = reinterpret_cast< ColorRGBA8* >( realloc( m_data, m_width * m_height * sizeof(ColorRGBA8) ) );
}

assert( m_data );
memcpy( m_data, rhs.m_data, m_width * m_height * sizeof(ColorRGBA8) );

return *this;
}
Image&
Image::operator=( Image&& rhs )
{
// The move operator takes the data from rhs, so long as they arent the same object.
if( this != &rhs ) {
// Erase the current image.
clear();

// Take data from `rhs`.
m_width = rhs.m_width;
m_height = rhs.m_height;
m_data = rhs.m_data;

// Set `rhs` to a valid state without its data.
rhs.m_width = rhs.m_height = 0;
rhs.m_data = nullptr;
}
return *this;
}

Image::~Image() { clear(); }

ColorRGBA8* Image::data() { return m_data; }
const ColorRGBA8* Image::data() const { return m_data; }
ColorRGBA8* Image::scanline( int row ) { return m_data + row*m_width; }
const ColorRGBA8* Image::scanline( int row ) const { return m_data + row*m_width; }

ColorRGBA8& Image::pixel( int i, int j )
{
assert( i >= 0 && i < m_width );assert( j >= 0 && j < m_height );return m_data[ i + j * m_width ];}const ColorRGBA8&Image::pixel( int i, int j )const{assert( i >= 0 && i < m_width );assert( j >= 0 && j < m_height );return m_data[ i + j * m_width ];}int Image::width() const{return m_width;}int Image::height() const{return m_height;}bool Image::empty() const{return m_data == nullptr;}Image& Image::clear(){free( m_data );m_data = nullptr;m_width = m_height = 0;return *this;}Image& Image::fill( ColorRGBA8 color ){if( empty() ) return *this;for( int i = 0; i < m_width*m_height; ++i ) m_data[i] = color;return *this;}Image& Image::resize( int width_, int height_, ColorRGBA8 clear_ ){// If new dimensions are the same, do nothing.if( m_width == width_ && m_height == height_ ) return *this;// Create a resized image.Image resized( width_, height_ );// Fill it with the clear color.resized.fill( clear_ );// If the current image isn’t empty, copy what we can.if( m_data ){const int min_width = std::min( m_width, width_ );const int min_height = std::min( m_height, height_ );for( int j = 0; j < min_height; ++j ) {memcpy( resized.scanline(j), scanline(j), min_width * sizeof(ColorRGBA8) );}}// Set the current image to the new resized image (by moving its data over).*this = std::move(resized);return *this;}Image& Image::rescale( int width_, int height_ ){// If new dimensions are the same, do nothing.if( m_width == width_ && m_height == height_ ) return *this;Image rescaled( width_, height_ );// If there is currently no data, set the output to transparent black and return.if( empty() ) {rescaled.fill( ColorRGBA8(0,0,0,0) );// Set the current image to the new image (by moving its data over).*this = std::move(rescaled);return *this;}// If we are here, we have data.assert( m_data );assert( m_width > 0 && m_height > 0 );

// Call stbir_resize_uint8()
const bool success = stbir_resize_uint8(
reinterpret_cast< const unsigned char* >( m_data ), m_width, m_height, 0,
reinterpret_cast< unsigned char* >( rescaled.data() ), width_, height_, 0,
4 // number of channels
);
assert( success );

// Set the current image to the new image (by moving its data over).
*this = std::move(rescaled);
return *this;
}

Image& Image::flip()
{
for( int j = 0; j < m_height / 2; ++j )for( int i = 0; i < m_width; ++i ){ColorRGBA8* lhs = &pixel( i,j );ColorRGBA8* rhs = &pixel( i, m_height – j – 1 );ColorRGBA8 temp = *lhs;*lhs = *rhs;*rhs = temp;}return *this;}Image& Image::mirror(){for( int j = 0; j < m_height; ++j )for( int i = 0; i < m_width / 2; ++i ){ColorRGBA8* lhs = &pixel( i,j );ColorRGBA8* rhs = &pixel( m_width – i – 1, j );ColorRGBA8 temp = *lhs;*lhs = *rhs;*rhs = temp;}return *this;}bool Image::same( const Image& rhs ) const{if( m_height != rhs.m_height || m_width != rhs.m_width ) return false;// Check if this->m_data and rhs.m_data point to the same data.
// This also checks for if both are nullptr.
if( m_data == rhs.m_data ) return true;

assert( m_data && rhs.m_data );
return 0 == memcmp( m_data, rhs.m_data, m_width * m_height * sizeof(ColorRGBA8) );
}
bool Image::same_rgb( const Image& rhs ) const
{
if( m_height != rhs.m_height || m_width != rhs.m_width ) return false;

// Check if this->m_data and rhs.m_data point to the same data.
// This also checks for if both are nullptr.
if( m_data == rhs.m_data ) return true;

assert( m_data && rhs.m_data );

for( int i = 0; i < m_height*m_width; ++i ){if(m_data[i].r != rhs.m_data[i].r ||m_data[i].g != rhs.m_data[i].g ||m_data[i].b != rhs.m_data[i].b )return false;}return true;}bool Image::save( const std::string& fname )const{// Don’t call this with an empty image.assert( m_data );assert( m_width > 0 && m_height > 0 );

std::string extension = os_path_splitext( fname ).second;
// ::tolower instead of std::tolower because MingW doesnt find std::tolower.
// More: https://sourceforge.net/p/mingw/mailman/mingw-users/thread/elbtvatk.fsf%40wanadoo.es/
std::transform( extension.begin(), extension.end(), extension.begin(), ::tolower );

bool success = false;
if( extension == .png ) {
success = stbi_write_png( fname.c_str(), m_width, m_height, 4, m_data, 0 );
} else if( extension == .bmp ) {
success = stbi_write_bmp( fname.c_str(), m_width, m_height, 4, m_data );
} else if( extension == .tga ) {
success = stbi_write_tga( fname.c_str(), m_width, m_height, 4, m_data );
} else if( extension == .jpg || extension == .jpeg ) {
success = stbi_write_jpg( fname.c_str(), m_width, m_height, 4, m_data, 85 );
}

return success;
}

bool Image::load( const std::string& fname )
{
int width_, height_, num_raw_channels;
unsigned char *data = stbi_load( fname.c_str(), &width_, &height_, &num_raw_channels, 4 );
// An error is indicated by stbi_load() returning NULL.
if( nullptr == data ) {
stbi_image_free( data );
return false;
}

// Reallocate memory as needed.
if( m_width != width_ || m_height != height_ ) {
m_width = width_;
m_height = height_;
m_data = reinterpret_cast ( realloc( m_data, m_width * m_height * sizeof(ColorRGBA8) ) );
}
assert( m_data );

// Copy the loaded data.
memcpy( m_data, data, m_width * m_height * sizeof(ColorRGBA8) );

stbi_image_free( data );

return true;
}

}

Reviews

There are no reviews yet.

Only logged in customers who have purchased this product may leave a review.

Shopping Cart
[SOLVED] CS python algorithm /*
$25