]> git.sesse.net Git - casparcg/blob - modules/psd/psd_document.cpp
* Enabled PSD producer in Linux
[casparcg] / modules / psd / psd_document.cpp
1 /*
2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
3 *
4 * This file is part of CasparCG (www.casparcg.com).
5 *
6 * CasparCG is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * CasparCG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Author: Niklas P Andersson, niklas.p.andersson@svt.se
20 */
21
22 #include "psd_document.h"
23 #include "descriptor.h"
24 #include <iostream>
25
26 namespace caspar { namespace psd {
27
28 psd_document::psd_document()
29         : channels_(0)
30         , width_(0)
31         , height_(0)
32         , depth_(0)
33         , color_mode_(psd::color_mode::InvalidColorMode)
34 {
35 }
36
37 void psd_document::parse(const std::wstring& filename)
38 {
39         filename_ = filename;
40         input_.open(filename_);
41         read_header();
42         read_color_mode();
43         read_image_resources();
44         read_layers();
45 }
46
47 void psd_document::read_header()
48 {
49         auto signature = input_.read_long();
50         auto version = input_.read_short();
51         if(!(signature == '8BPS' && version == 1))
52                 CASPAR_THROW_EXCEPTION(psd_file_format_exception() << msg_info("!(signature == '8BPS' && version == 1)"));
53
54         input_.discard_bytes(6);
55         channels_= input_.read_short();
56         height_ = input_.read_long();
57         width_ = input_.read_long();
58         depth_ = input_.read_short();   //bits / channel
59
60         color_mode_ = int_to_color_mode(input_.read_short());
61 }
62
63 void psd_document::read_color_mode()
64 {
65         auto length = input_.read_long();
66         input_.discard_bytes(length);
67 }
68
69 void psd_document::read_image_resources()
70 {
71         unsigned long section_length = input_.read_long();
72
73         if(section_length > 0)
74         {
75                 std::streamoff end_of_section = input_.current_position() + section_length;
76         
77                 try
78                 {
79                         while(input_.current_position() < end_of_section)
80                         {
81                                 auto signature = input_.read_long();
82                                 if(signature != '8BIM')
83                                         CASPAR_THROW_EXCEPTION(psd_file_format_exception() << msg_info("signature != '8BIM'"));
84
85                                 auto resource_id = input_.read_short();
86                                 
87                                 std::wstring name = input_.read_pascal_string(2);
88
89                                 auto resource_length = input_.read_long();
90                                 auto end_of_chunk = input_.current_position() + resource_length;
91
92                                 try
93                                 {
94                                         //TODO: read actual data
95                                         switch(resource_id)
96                                         {
97                                         case 1026:              //layer group information. describes linked layers
98                                                 {
99                                                         int layer_count = resource_length / 2;
100                                                         for(int i = 0; i < layer_count; ++i)
101                                                         {
102                                                                 short id = input_.read_short();
103
104                                                                 if(i == layers_.size())
105                                                                         layers_.push_back(std::make_shared<layer>());
106
107                                                                 layers_[i]->set_link_group_id(id);
108                                                         }
109
110                                                 }
111                                                 break;
112                                         case 1075:              //timeline information
113                                                 {
114                                                         input_.read_long();     //descriptor version, should be 16
115                                                         descriptor timeline_descriptor;
116                                                         timeline_descriptor.populate(input_);
117                                                         timeline_desc_.swap(timeline_descriptor.items());
118                                                 }
119                                                 break;
120
121                                         case 1005:
122                                                 {       
123                                                         ////resolutionInfo
124                                                         //struct ResolutionInfo
125                                                         //{
126                                                         //Fixed hRes;
127                                                         //int16 hResUnit;
128                                                         //int16 widthUnit;
129                                                         //Fixed vRes;
130                                                         //int16 vResUnit;
131                                                         //int16 heightUnit;
132                                                         //};
133                                                 }
134                                         case 1006:              //names of alpha channels
135                                         case 1008:              //caption
136                                         case 1010:              //background color
137                                         case 1024:              //layer state info (2 bytes containing the index of target layer (0 = bottom layer))
138                                         case 1028:              //IPTC-NAA. File Info...
139                                         case 1029:              //image for raw format files
140                                         case 1036:              //thumbnail resource
141                                         case 1045:              //unicode Alpha names (Unicode string (4 bytes length followed by string))
142                                         case 1053:              //alpha identifiers (4 bytes of length, followed by 4 bytes each for every alpha identifier.)
143                                         case 1060:              //XMP metadata
144                                         case 1065:              //layer comps
145                                         case 1069:              //layer selection ID(s)
146                                         case 1072:              //layer group(s) enabled id
147                                         case 1077:              //DisplayInfo
148                                         case 2999:              //name of clipping path
149                                         default:
150                                                 {
151                                                         if(resource_id >= 2000 && resource_id <=2997)   //path information
152                                                         {
153                                                         }
154                                                         else if(resource_id >= 4000 && resource_id <= 4999)     //plug-in resources
155                                                         {
156                                                         }
157                                                 }
158                                                 input_.discard_bytes(resource_length);
159                                                 break;
160                                         }
161
162                                         if((resource_length & 1) == 1)  //each resource is padded to an even amount of bytes
163                                                 input_.discard_bytes(1);
164                                 }
165                                 catch(psd_file_format_exception&)
166                                 {
167                                         input_.set_position(end_of_chunk);
168                                 }
169                         }
170                 }
171                 catch(psd_file_format_exception&)
172                 {
173                         //if an error occurs, just skip this section
174                         input_.set_position(end_of_section);
175                 }
176         }
177 }
178
179
180 void psd_document::read_layers()
181 {
182         //"Layer And Mask information"
183         auto total_length = input_.read_long(); //length of "Layer and Mask information"
184         auto end_of_layers = input_.current_position() + total_length;
185
186         try
187         {
188                 //"Layer info section"
189                 {
190                         auto layer_info_length = input_.read_long();    //length of "Layer info" section
191                         auto end_of_layers_info = input_.current_position() + layer_info_length;
192
193                         auto layers_count = std::abs(static_cast<short>(input_.read_short()));
194                         //std::clog << "Expecting " << layers_count << " layers" << std::endl;
195
196                         for(int layer_index = 0; layer_index < layers_count; ++layer_index)
197                         {
198                                 if(layer_index  == layers_.size())
199                                         layers_.push_back(std::make_shared<layer>());
200                                 
201                                 layers_[layer_index]->populate(input_, *this);
202                                 //std::clog << "Added layer: " << std::string(layers_[layerIndex]->name().begin(), layers_[layerIndex]->name().end()) << std::endl;
203                         }
204
205                         auto end = layers_.end();
206                         for(auto layer_it = layers_.begin(); layer_it != end; ++layer_it)
207                         {
208                                 (*layer_it)->read_channel_data(input_); //each layer reads it's "image data"
209                         }
210
211                         input_.set_position(end_of_layers_info);
212                 }
213
214                 //global layer mask info
215                 auto global_layer_mask_length = input_.read_long();
216                 input_.discard_bytes(global_layer_mask_length);
217
218         }
219         catch(std::exception&)
220         {
221                 input_.set_position(end_of_layers);
222         }
223 }
224
225 }       //namespace psd
226 }       //namespace caspar