C++ library for streaming images (png/jpg/bmp)
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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

99 lines
2.2 KiB

//
// 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 <cstdio>
#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>
J_COLOR_SPACE color_space(){
int num_colors = pixel_formats::traits<P>::num_colors;
switch (num_colors) {
case 1: return JCS_GRAYSCALE;
case 3: return JCS_RGB;
default: return JCS_UNKNOWN;
}
}
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 = color_space<pixel>();
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 95, 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
unsigned char * ptr = reinterpret_cast<unsigned char *>(row.data());
jpeg_write_scanlines(&cinfo, &ptr, 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