| 113 | } |
| 114 | |
| 115 | void PsdImage::readMetadata() { |
| 116 | #ifdef EXIV2_DEBUG_MESSAGES |
| 117 | std::cerr << "Exiv2::PsdImage::readMetadata: Reading Photoshop file " << io_->path() << "\n"; |
| 118 | #endif |
| 119 | if (io_->open() != 0) { |
| 120 | throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError()); |
| 121 | } |
| 122 | IoCloser closer(*io_); |
| 123 | // Ensure that this is the correct image type |
| 124 | if (!isPsdType(*io_, false)) { |
| 125 | if (io_->error() || io_->eof()) |
| 126 | throw Error(ErrorCode::kerFailedToReadImageData); |
| 127 | throw Error(ErrorCode::kerNotAnImage, "Photoshop"); |
| 128 | } |
| 129 | clearMetadata(); |
| 130 | |
| 131 | /* |
| 132 | The Photoshop header goes as follows -- all numbers are in big-endian byte order: |
| 133 | |
| 134 | offset length name description |
| 135 | ====== ======= ========= ========= |
| 136 | 0 4 bytes signature always '8BPS' |
| 137 | 4 2 bytes version always equal to 1 |
| 138 | 6 6 bytes reserved must be zero |
| 139 | 12 2 bytes channels number of channels in the image, including alpha channels (1 to 24) |
| 140 | 14 4 bytes rows the height of the image in pixels |
| 141 | 18 4 bytes columns the width of the image in pixels |
| 142 | 22 2 bytes depth the number of bits per channel |
| 143 | 24 2 bytes mode the color mode of the file; Supported values are: Bitmap=0; Grayscale=1; |
| 144 | Indexed=2; RGB=3; CMYK=4; Multichannel=7; Duotone=8; Lab=9 |
| 145 | */ |
| 146 | byte buf[26]; |
| 147 | if (io_->read(buf, 26) != 26) { |
| 148 | throw Error(ErrorCode::kerNotAnImage, "Photoshop"); |
| 149 | } |
| 150 | pixelWidth_ = getLong(buf + 18, bigEndian); |
| 151 | pixelHeight_ = getLong(buf + 14, bigEndian); |
| 152 | |
| 153 | // immediately following the image header is the color mode data section, |
| 154 | // the first four bytes of which specify the byte size of the whole section |
| 155 | if (io_->read(buf, 4) != 4) { |
| 156 | throw Error(ErrorCode::kerNotAnImage, "Photoshop"); |
| 157 | } |
| 158 | |
| 159 | // skip it |
| 160 | if (io_->seek(getULong(buf, bigEndian), BasicIo::cur)) { |
| 161 | throw Error(ErrorCode::kerNotAnImage, "Photoshop"); |
| 162 | } |
| 163 | |
| 164 | // after the color data section, comes a list of resource blocks, preceded by the total byte size |
| 165 | if (io_->read(buf, 4) != 4) { |
| 166 | throw Error(ErrorCode::kerNotAnImage, "Photoshop"); |
| 167 | } |
| 168 | uint32_t resourcesLength = getULong(buf, bigEndian); |
| 169 | Internal::enforce(resourcesLength < io_->size(), Exiv2::ErrorCode::kerCorruptedMetadata); |
| 170 | |
| 171 | while (resourcesLength > 0) { |
| 172 | Internal::enforce(resourcesLength >= 8, Exiv2::ErrorCode::kerCorruptedMetadata); |
nothing calls this directly
no test coverage detected