1 module psd.parse.parser; 2 import psd.parse.sections; 3 import psd.parse.io; 4 import psd; 5 import std.stdio : File; 6 7 /** 8 Parse a PSD file 9 */ 10 PSD parsePSD(Stream stream) { 11 return parsePSDToCtx(stream).psd; 12 } 13 14 /** 15 Parse a PSD file 16 */ 17 PSD parsePSD(string file) { 18 auto f = File(file, "r"); 19 scope(exit) f.close(); 20 return parsePSD(new FileStream(f)); 21 } 22 23 /** 24 Parse a PSD file 25 */ 26 ParserContext parsePSDToCtx(string file) { 27 auto f = File(file, "r"); 28 scope(exit) f.close(); 29 auto stream = new FileStream(f); 30 writeln("Made a stream."); 31 auto context = parsePSDToCtx(stream); 32 writeln("Parsed"); 33 34 return context; 35 } 36 37 /** 38 Parse a PSD file 39 */ 40 ParserContext parsePSDToCtx(Stream stream) { 41 ParserContext ctx; 42 ctx.stream = stream; 43 44 // Parse the header 45 parseHeader(ctx); 46 47 // Parse image resources (need it for layer tags) 48 parseImageResources(ctx); 49 writeln("Parsed image resources."); 50 51 // Layer & Mask info 52 // This is where the layers we need are!! 53 parseLayerMaskInfo(ctx); 54 writeln("Parsed layer mask info."); 55 56 return ctx; 57 } 58 59 /** 60 Parser context 61 */ 62 struct ParserContext { 63 /** 64 Parser stream 65 */ 66 Stream stream; 67 68 /** 69 The main output PSD file 70 */ 71 PSD psd; 72 73 /** 74 The image resources 75 */ 76 ImageResourceBlock[] imageResources; 77 78 /** 79 Layer mask information 80 */ 81 LayerMaskInfo layerMaskInfo; 82 83 /** 84 Proxy for stream.read 85 */ 86 pragma(inline, true) 87 ubyte[] read(size_t length) { 88 return stream.read(length); 89 } 90 91 /** 92 Proxy for stream.readValue 93 */ 94 pragma(inline, true) 95 T readValue(T)() { 96 return stream.readValue!T; 97 } 98 99 /** 100 Rounds numToRound up to a multiple of multipleOf 101 */ 102 pragma(inline, true) 103 T roundUpToMultiple(T)(T numToRound, T multipleOf) 104 { 105 // make sure that this function is only called for unsigned types, and ensure that we want to round to a power-of-two 106 //static_assert(util::IsUnsigned<T>::value == true, "T must be an unsigned type."); 107 //PSD_ASSERT(IsPowerOfTwo(multipleOf), "Expected a power-of-two."); 108 109 return (numToRound + (multipleOf - 1u)) & ~(multipleOf - 1u); 110 } 111 112 /** 113 Proxy for stream.readValue, but padds the result. 114 */ 115 pragma(inline, true) 116 T readPaddedValue(T)(T multipleOf = 2, T addTo = 0) { 117 T value = stream.readValue!T; 118 return cast(T)roundUpToMultiple(value + addTo, multipleOf); 119 } 120 121 /** 122 Proxy for stream.read 123 */ 124 pragma(inline, true) 125 ubyte[] readData(size_t length) { 126 return stream.read(length); 127 } 128 129 130 /** 131 Proxy for stream.readStr 132 */ 133 pragma(inline, true) 134 string readStr(size_t length) { 135 return stream.readStr(cast(uint)length); 136 } 137 138 139 /** 140 Proxy for stream.readPascalStr 141 */ 142 pragma(inline, true) 143 string readPascalStr() { 144 return stream.readPascalStr(); 145 } 146 147 /** 148 Proxy for stream.peekStr 149 */ 150 pragma(inline, true) 151 string peekStr(size_t length) { 152 return stream.peekStr(cast(uint)length); 153 } 154 155 /** 156 Proxy for stream.skip 157 */ 158 pragma(inline, true) 159 void skip(ptrdiff_t length) { 160 return stream.skip(length); 161 } 162 163 /** 164 Proxy for stream.seek 165 */ 166 pragma(inline, true) 167 void seek(ptrdiff_t position) { 168 return stream.seek(position); 169 } 170 171 /** 172 Proxy for stream.tell 173 */ 174 pragma(inline, true) 175 size_t tell() { 176 return stream.tell(); 177 } 178 179 180 /** 181 Proxy for stream.size 182 */ 183 pragma(inline, true) 184 size_t length() { 185 return stream.length(); 186 } 187 }