Use a new ImageProxy to hold J2K data from DCP content.
[dcpomatic.git] / src / lib / image_proxy.h
1 /*
2     Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
3
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.
8
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.
13
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.
17
18 */
19
20 /** @file  src/lib/image_proxy.h
21  *  @brief ImageProxy and subclasses.
22  */
23
24 #include <boost/shared_ptr.hpp>
25 #include <boost/filesystem.hpp>
26 #include <Magick++.h>
27 #include <libxml++/libxml++.h>
28
29 class Image;
30 class Socket;
31 class Log;
32
33 namespace cxml {
34         class Node;
35 }
36
37 namespace dcp {
38         class MonoPictureFrame;
39         class StereoPictureFrame;
40 }
41
42 /** @class ImageProxy
43  *  @brief A class which holds an Image, and can produce it on request.
44  *
45  *  This is so that decoding of source images can be postponed until
46  *  the encoder thread, where multi-threading is happening, instead
47  *  of happening in a single-threaded decoder.
48  *
49  *  For example, large TIFFs are slow to decode, so this class will keep
50  *  the TIFF data TIFF until such a time that the actual image is needed.
51  *  At this point, the class decodes the TIFF to an Image.
52  */
53 class ImageProxy : public boost::noncopyable
54 {
55 public:
56         ImageProxy (boost::shared_ptr<Log> log);
57
58         /** @return Image (which must be aligned) */
59         virtual boost::shared_ptr<Image> image () const = 0;
60         virtual void add_metadata (xmlpp::Node *) const = 0;
61         virtual void send_binary (boost::shared_ptr<Socket>) const = 0;
62
63 protected:
64         boost::shared_ptr<Log> _log;
65 };
66
67 class RawImageProxy : public ImageProxy
68 {
69 public:
70         RawImageProxy (boost::shared_ptr<Image>, boost::shared_ptr<Log> log);
71         RawImageProxy (boost::shared_ptr<cxml::Node> xml, boost::shared_ptr<Socket> socket, boost::shared_ptr<Log> log);
72
73         boost::shared_ptr<Image> image () const;
74         void add_metadata (xmlpp::Node *) const;
75         void send_binary (boost::shared_ptr<Socket>) const;
76         
77 private:
78         boost::shared_ptr<Image> _image;
79 };
80
81 class MagickImageProxy : public ImageProxy
82 {
83 public:
84         MagickImageProxy (boost::filesystem::path, boost::shared_ptr<Log> log);
85         MagickImageProxy (boost::shared_ptr<cxml::Node> xml, boost::shared_ptr<Socket> socket, boost::shared_ptr<Log> log);
86
87         boost::shared_ptr<Image> image () const;
88         void add_metadata (xmlpp::Node *) const;
89         void send_binary (boost::shared_ptr<Socket>) const;
90
91 private:        
92         Magick::Blob _blob;
93         mutable boost::shared_ptr<Image> _image;
94 };
95
96 class J2KImageProxy : public ImageProxy
97 {
98 public:
99         J2KImageProxy (boost::shared_ptr<const dcp::MonoPictureFrame> frame, dcp::Size, boost::shared_ptr<Log> log);
100         J2KImageProxy (boost::shared_ptr<const dcp::StereoPictureFrame> frame, dcp::Size, dcp::Eye, boost::shared_ptr<Log> log);
101         J2KImageProxy (boost::shared_ptr<cxml::Node> xml, boost::shared_ptr<Socket> socket, boost::shared_ptr<Log> log);
102
103         boost::shared_ptr<Image> image () const;
104         void add_metadata (xmlpp::Node *) const;
105         void send_binary (boost::shared_ptr<Socket>) const;
106
107 private:
108         boost::shared_ptr<const dcp::MonoPictureFrame> _mono;
109         boost::shared_ptr<const dcp::StereoPictureFrame> _stereo;
110         dcp::Size _size;
111         dcp::Eye _eye;
112 };
113
114 boost::shared_ptr<ImageProxy> image_proxy_factory (boost::shared_ptr<cxml::Node> xml, boost::shared_ptr<Socket> socket, boost::shared_ptr<Log> log);