You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.0 KiB
90 lines
2.0 KiB
12 years ago
|
//
|
||
|
// jpg.hpp
|
||
|
// ImageStreams
|
||
|
//
|
||
|
// Created by Joshua Moerman on 9/15/12.
|
||
|
// Copyright (c) 2012 Vadovas. All rights reserved.
|
||
|
//
|
||
|
|
||
|
#ifndef ImageStreams_jpg_hpp
|
||
|
#define ImageStreams_jpg_hpp
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdexcept>
|
||
|
#include <vector>
|
||
|
#include <jpeglib.h>
|
||
|
#include "basics.hpp"
|
||
|
|
||
|
/*
|
||
|
JPEG only supports 8bits or 24bits per pixel (eg grayscale or full color).
|
||
|
Top to bottom
|
||
|
*/
|
||
|
|
||
|
namespace jpg{
|
||
|
|
||
|
template <typename P = pixel_formats::rgb>
|
||
|
struct ostream{
|
||
|
typedef P pixel;
|
||
|
|
||
|
ostream() = delete;
|
||
|
ostream(ostream const &) = delete;
|
||
|
ostream & operator=(ostream const &) = delete;
|
||
|
|
||
|
ostream(uint32_t width, uint32_t height, std::string filename)
|
||
|
: fp(0)
|
||
|
, cinfo()
|
||
|
, jerr()
|
||
|
, row(width)
|
||
|
, x(0)
|
||
|
{
|
||
|
fp = fopen(filename.c_str(), "wb");
|
||
|
if(!fp) throw std::runtime_error("Could not open file");
|
||
|
|
||
|
cinfo.err = jpeg_std_error(&jerr);
|
||
|
jpeg_create_compress(&cinfo);
|
||
|
jpeg_stdio_dest(&cinfo, fp);
|
||
|
|
||
|
cinfo.image_width = width;
|
||
|
cinfo.image_height = height;
|
||
|
cinfo.input_components = pixel_formats::traits<pixel>::num_colors;
|
||
|
//cinfo.in_color_space = JCS_RGB; // or JCS_GRAYSCALE, will be set in jpeg_set_defaults()
|
||
|
|
||
|
jpeg_set_defaults(&cinfo);
|
||
|
//jpeg_set_quality(&cinfo, 75, true); // quality in [0, 100], boolean indicates "force_baseline" (only matters when quality < 25)
|
||
|
jpeg_start_compress(&cinfo, true); // true means we will write completely
|
||
|
}
|
||
|
|
||
|
~ostream(){
|
||
|
jpeg_finish_compress(&cinfo);
|
||
|
fclose(fp);
|
||
|
jpeg_destroy_compress(&cinfo);
|
||
|
}
|
||
|
|
||
|
ostream& operator<<(pixel const & p){
|
||
|
row[x] = p;
|
||
|
++x;
|
||
|
if(x >= row.size()){
|
||
|
// this will return the number of scanlines written
|
||
|
jpeg_write_scanlines(&cinfo, reinterpret_cast<unsigned char const*>(row.data()), 1);
|
||
|
x = 0;
|
||
|
}
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
FILE* fp;
|
||
|
jpeg_compress_struct cinfo;
|
||
|
jpeg_error_mgr jerr;
|
||
|
|
||
|
std::vector<pixel> row;
|
||
|
uint32_t x;
|
||
|
};
|
||
|
|
||
|
typedef ostream<> colored_ostream;
|
||
|
typedef ostream<pixel_formats::gray> gray_ostream;
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif
|