(committing very old stuff) Adds png input stream (IIRC the height is wrongly read)
This commit is contained in:
parent
fcad14e7bf
commit
744844d5ef
1 changed files with 92 additions and 0 deletions
|
@ -90,6 +90,98 @@ namespace png{
|
|||
|
||||
typedef ostream<> colored_ostream;
|
||||
typedef ostream<pixel_formats::gray> gray_ostream;
|
||||
|
||||
struct istream{
|
||||
//typedef pixel pixel;
|
||||
|
||||
istream(std::string filename)
|
||||
: fp(0)
|
||||
, png_ptr(0)
|
||||
, info_ptr(0)
|
||||
, row()
|
||||
, stride(0)
|
||||
, x(0)
|
||||
, y(0)
|
||||
{
|
||||
fp = fopen(filename.c_str(), "rb");
|
||||
if(!fp) throw std::runtime_error(filename + " could not be opened");
|
||||
|
||||
png_byte header[8];
|
||||
fread(header, 1, 8, fp);
|
||||
|
||||
if(png_sig_cmp(header, 0, 8) != 0) throw std::runtime_error("File is not a PNG file.");
|
||||
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
|
||||
if(!png_ptr) throw std::runtime_error("PNG structure could not be allocated");
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if(!info_ptr) throw std::runtime_error("PNG information structure could not be allocated");
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
png_set_sig_bytes(png_ptr, 8);
|
||||
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
if(png_get_interlace_type(png_ptr, info_ptr) != PNG_INTERLACE_NONE)
|
||||
throw std::runtime_error("Interalced PNG's are not supported");
|
||||
|
||||
auto width = png_get_image_width(png_ptr, info_ptr);
|
||||
auto bit_depth = png_get_bit_depth(png_ptr, info_ptr);
|
||||
auto channels = png_get_channels(png_ptr, info_ptr);
|
||||
|
||||
// number of bytes in one row
|
||||
stride = bit_depth * channels / 8;
|
||||
size_t row_size = width * stride;
|
||||
|
||||
if(bit_depth < 8) throw std::runtime_error("Bitdepths lower than 8 are not supported (yet)");
|
||||
|
||||
row.resize(row_size);
|
||||
png_read_row(png_ptr, (png_bytep)row.data(), 0);
|
||||
}
|
||||
|
||||
~istream(){
|
||||
png_read_end(png_ptr, 0);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, 0);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
template <typename Pixel>
|
||||
istream& operator>>(Pixel & p){
|
||||
p = row[x];
|
||||
|
||||
if(++x >= row.size()){
|
||||
x = 0;
|
||||
++y;
|
||||
if(*this)
|
||||
png_read_row(png_ptr, (png_bytep)row.data(), 0);
|
||||
}
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
uint32_t height = 183;
|
||||
png_get_IHDR(png_ptr, info_ptr, 0, &height, 0, 0, 0, 0, 0);
|
||||
|
||||
if(y >= height) return false;
|
||||
else return true;
|
||||
}
|
||||
|
||||
uint32_t width() const {
|
||||
return row.size();
|
||||
}
|
||||
|
||||
private:
|
||||
FILE* fp;
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
|
||||
std::vector<char> row;
|
||||
uint32_t stride;
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Reference in a new issue