2 Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <dcp/raw_convert.h>
23 #include "image_proxy.h"
25 #include "exceptions.h"
32 using std::stringstream;
33 using boost::shared_ptr;
35 RawImageProxy::RawImageProxy (shared_ptr<Image> image)
41 RawImageProxy::RawImageProxy (shared_ptr<cxml::Node> xml, shared_ptr<Socket> socket)
44 xml->number_child<int> ("Width"), xml->number_child<int> ("Height")
47 _image.reset (new Image (PIX_FMT_RGB24, size, true));
48 _image->read_from_socket (socket);
52 RawImageProxy::image () const
58 RawImageProxy::add_metadata (xmlpp::Node* node) const
60 node->add_child("Type")->add_child_text (N_("Raw"));
61 node->add_child("Width")->add_child_text (dcp::raw_convert<string> (_image->size().width));
62 node->add_child("Height")->add_child_text (dcp::raw_convert<string> (_image->size().height));
66 RawImageProxy::send_binary (shared_ptr<Socket> socket) const
68 _image->write_to_socket (socket);
71 MagickImageProxy::MagickImageProxy (boost::filesystem::path path)
73 /* Read the file into a Blob */
75 boost::uintmax_t const size = boost::filesystem::file_size (path);
76 FILE* f = fopen_boost (path, "rb");
78 throw OpenFileError (path);
81 uint8_t* data = new uint8_t[size];
82 if (fread (data, 1, size, f) != size) {
84 throw ReadFileError (path);
88 _blob.update (data, size);
92 MagickImageProxy::MagickImageProxy (shared_ptr<cxml::Node>, shared_ptr<Socket> socket)
94 uint32_t const size = socket->read_uint32 ();
95 uint8_t* data = new uint8_t[size];
96 socket->read (data, size);
97 _blob.update (data, size);
102 MagickImageProxy::image () const
108 Magick::Image* magick_image = 0;
110 magick_image = new Magick::Image (_blob);
112 throw DecodeError (_("Could not decode image file"));
115 dcp::Size size (magick_image->columns(), magick_image->rows());
117 _image.reset (new Image (PIX_FMT_RGB24, size, true));
119 using namespace MagickCore;
121 uint8_t* p = _image->data()[0];
122 for (int y = 0; y < size.height; ++y) {
124 for (int x = 0; x < size.width; ++x) {
125 Magick::Color c = magick_image->pixelColor (x, y);
126 *q++ = c.redQuantum() * 255 / QuantumRange;
127 *q++ = c.greenQuantum() * 255 / QuantumRange;
128 *q++ = c.blueQuantum() * 255 / QuantumRange;
130 p += _image->stride()[0];
139 MagickImageProxy::add_metadata (xmlpp::Node* node) const
141 node->add_child("Type")->add_child_text (N_("Magick"));
145 MagickImageProxy::send_binary (shared_ptr<Socket> socket) const
147 socket->write (_blob.length ());
148 socket->write ((uint8_t *) _blob.data (), _blob.length ());
151 shared_ptr<ImageProxy>
152 image_proxy_factory (shared_ptr<cxml::Node> xml, shared_ptr<Socket> socket)
154 if (xml->string_child("Type") == N_("Raw")) {
155 return shared_ptr<ImageProxy> (new RawImageProxy (xml, socket));
156 } else if (xml->string_child("Type") == N_("Magick")) {
157 return shared_ptr<MagickImageProxy> (new MagickImageProxy (xml, socket));
160 throw NetworkError (_("Unexpected image type received by server"));