Skip to content

Instantly share code, notes, and snippets.

@AndrewFromMelbourne
Created September 17, 2016 07:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndrewFromMelbourne/a25289fc23ba69e90f5f40525da548a1 to your computer and use it in GitHub Desktop.
Save AndrewFromMelbourne/a25289fc23ba69e90f5f40525da548a1 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <jpeglib.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/fl_ask.H>
#include <FL/fl_draw.H>
#include <FL/fl_file_chooser.H>
using namespace std;
//-------------------------------------------------------------------------
void jpeg_output_message(j_common_ptr cinfo);
int arg(int argc, char** argv, int& i);
//-------------------------------------------------------------------------
class Image_Window
:
public Fl_Window
{
public:
Image_Window();
~Image_Window();
void fill_buffer();
const char* get_name()
{
return m_name;
}
void set_name(const char* name)
{
m_name = name;
}
private:
void set_label();
void draw();
//---------------------------------------------------------------------
const char* m_name;
JDIMENSION m_width;
JDIMENSION m_height;
unsigned char* m_buffer;
};
Image_Window image_window;
//-------------------------------------------------------------------------
Image_Window::Image_Window()
:
Fl_Window(10,10),
m_name(0),
m_width(10),
m_height(10),
m_buffer(0)
{
box(FL_NO_BOX);
}
//-------------------------------------------------------------------------
Image_Window::~Image_Window()
{
delete [] m_buffer;
}
//-------------------------------------------------------------------------
void
Image_Window::set_label()
{
const char* sname = strrchr(m_name, '/');
if (sname == 0)
{
sname = m_name;
}
else
{
sname += 1;
}
char buffer[100];
snprintf(buffer,
sizeof(buffer),
"%s - (%lux%lu)",
sname,
(unsigned long)m_width,
(unsigned long)m_height);
label(buffer);
}
//-------------------------------------------------------------------------
void
Image_Window::draw()
{
fl_draw_image(m_buffer, 0, 0, m_width, m_height);
}
//-------------------------------------------------------------------------
void
Image_Window::fill_buffer()
{
FILE* fpin = fopen(m_name, "rb");
if (fpin == 0)
{
fl_alert("Can't open file for reading");
exit(EXIT_FAILURE);
}
//---------------------------------------------------------------------
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
cinfo.err->output_message = jpeg_output_message;
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, fpin);
jpeg_read_header(&cinfo, TRUE);
cinfo.out_color_space = JCS_RGB;
jpeg_start_decompress(&cinfo);
m_width = cinfo.output_width;
m_height = cinfo.output_height;
//---------------------------------------------------------------------
if (m_buffer)
{
delete [] m_buffer;
}
m_buffer = new unsigned char[m_width * m_height * 3];
//---------------------------------------------------------------------
for (JDIMENSION j = 0; j < m_height; ++j)
{
unsigned char* row = m_buffer + (j * 3 * m_width);
jpeg_read_scanlines(&cinfo, &row, 1);
}
//---------------------------------------------------------------------
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(fpin);
//---------------------------------------------------------------------
set_label();
size(m_width, m_height);
damage(FL_DAMAGE_ALL);
}
//-------------------------------------------------------------------------
void jpeg_output_message(j_common_ptr cinfo)
{
char buffer[JMSG_LENGTH_MAX];
(*cinfo->err->format_message) (cinfo, buffer);
fl_alert(buffer);
}
//-------------------------------------------------------------------------
int arg(int argc, char** argv, int& i)
{
if (argv[i][0] == '-')
{
return 0;
}
image_window.set_name(argv[i]);
++i;
return 1;
}
//-------------------------------------------------------------------------
int main(int argc, char ** argv)
{
const char* program_name = fl_filename_name(argv[0]);
fl_message_title(program_name);
int i = 0;
if (Fl::args(argc, argv, i, arg) < argc)
{
Fl::error("%s <file.jpg>", program_name);
}
const char* name = image_window.get_name();
if (name == 0)
{
name = fl_file_chooser("JPEG file", "*.jpg", "");
if (name != 0)
{
image_window.set_name(name);
}
}
if (name == 0)
{
return 0;
}
//---------------------------------------------------------------------
Fl::visual(FL_RGB);
image_window.end();
image_window.show(argc, argv);
image_window.set_name(name);
image_window.fill_buffer();
//---------------------------------------------------------------------
return Fl::run();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment