PSD preview implementation ยป exiv2-0.21.1_psd_preview.patch
exiv2-0.21.1/src/image.cpp 2011-04-21 13:58:21.000000000 +0200 | ||
---|---|---|
257 | 257 |
comment_ = comment; |
258 | 258 |
} |
259 | 259 | |
260 |
const DataBuf& Image::preview() const |
|
261 |
{ |
|
262 |
return preview_; |
|
263 |
} |
|
264 | ||
265 |
DataBuf& Image::preview() |
|
266 |
{ |
|
267 |
return preview_; |
|
268 |
} |
|
269 | ||
260 | 270 |
void Image::setByteOrder(ByteOrder byteOrder) |
261 | 271 |
{ |
262 | 272 |
byteOrder_ = byteOrder; |
exiv2-0.21.1/src/image.hpp 2011-04-22 22:11:09.000000000 +0200 | ||
---|---|---|
385 | 385 |
bool supportsMetadata(MetadataId metadataId) const; |
386 | 386 |
//! Return the flag indicating the source when writing XMP metadata. |
387 | 387 |
bool writeXmpFromPacket() const; |
388 |
/*! |
|
389 |
@return modifiable reference to this image's native preview |
|
390 |
*/ |
|
391 |
virtual DataBuf& preview(); |
|
392 |
/*! |
|
393 |
@return read only reference to this image's native preview |
|
394 |
*/ |
|
395 |
virtual const DataBuf& preview() const; |
|
388 | 396 |
//@} |
389 | 397 | |
390 | 398 |
protected: |
... | ... | |
397 | 405 |
std::string xmpPacket_; //!< XMP packet |
398 | 406 |
int pixelWidth_; //!< image pixel width |
399 | 407 |
int pixelHeight_; //!< image pixel height |
408 |
DataBuf preview_; //!< generic preview image |
|
400 | 409 | |
401 | 410 |
private: |
402 | 411 |
//! @name NOT implemented |
exiv2-0.21.1/src/preview.cpp 2011-04-22 23:52:35.000000000 +0200 | ||
---|---|---|
236 | 236 |
//! Function to create new LoaderTiff |
237 | 237 |
Loader::AutoPtr createLoaderTiff(PreviewId id, const Image &image, int parIdx); |
238 | 238 | |
239 |
//! Loader for PSD previews in Jpeg format |
|
240 |
class LoaderPsdJpeg : public Loader { |
|
241 |
public: |
|
242 |
// Constructor |
|
243 |
LoaderPsdJpeg(PreviewId id, const Image &image, int parIdx); |
|
244 | ||
245 |
//! Get properties of a preview image with given params |
|
246 |
virtual PreviewProperties getProperties() const; |
|
247 | ||
248 |
//! Get a buffer that contains the preview image |
|
249 |
virtual DataBuf getData() const; |
|
250 | ||
251 |
//! Read preview image dimensions |
|
252 |
virtual bool readDimensions(); |
|
253 | ||
254 |
}; |
|
255 | ||
256 |
//! Function to create new LoaderPsdJpeg |
|
257 |
Loader::AutoPtr createLoaderPsdJpeg(PreviewId id, const Image &image, int parIdx); |
|
258 | ||
239 | 259 |
// ***************************************************************************** |
240 | 260 |
// class member definitions |
241 | 261 | |
... | ... | |
265 | 285 |
{ 0, createLoaderExifJpeg, 5 }, |
266 | 286 |
{ 0, createLoaderExifJpeg, 6 }, |
267 | 287 |
{ "image/x-canon-cr2", createLoaderExifJpeg, 7 }, |
268 |
{ 0, createLoaderExifJpeg, 8 } |
|
288 |
{ 0, createLoaderExifJpeg, 8 }, |
|
289 |
{ 0, createLoaderPsdJpeg, 0 } |
|
269 | 290 |
}; |
270 | 291 | |
271 | 292 |
const LoaderExifJpeg::Param LoaderExifJpeg::param_[] = { |
... | ... | |
663 | 684 |
return DataBuf(mio.mmap(), mio.size()); |
664 | 685 |
} |
665 | 686 | |
687 |
LoaderPsdJpeg::LoaderPsdJpeg(PreviewId id, const Image &image, int parIdx) |
|
688 |
: Loader(id, image) |
|
689 |
{ |
|
690 |
if (image_.preview().size_ > 0) { |
|
691 |
size_ = image_.preview().size_; |
|
692 |
valid_ = true; |
|
693 |
} |
|
694 |
} |
|
695 | ||
696 |
Loader::AutoPtr createLoaderPsdJpeg(PreviewId id, const Image &image, int parIdx) |
|
697 |
{ |
|
698 |
return Loader::AutoPtr(new LoaderPsdJpeg(id, image, parIdx)); |
|
699 |
} |
|
700 | ||
701 |
PreviewProperties LoaderPsdJpeg::getProperties() const |
|
702 |
{ |
|
703 |
PreviewProperties prop = Loader::getProperties(); |
|
704 |
prop.mimeType_ = "image/jpeg"; |
|
705 |
prop.extension_ = ".jpg"; |
|
706 |
#ifdef EXV_UNICODE_PATH |
|
707 |
prop.wextension_ = EXV_WIDEN(".jpg"); |
|
708 |
#endif |
|
709 |
return prop; |
|
710 |
} |
|
711 | ||
712 |
DataBuf LoaderPsdJpeg::getData() const |
|
713 |
{ |
|
714 |
if (!valid()) return DataBuf(); |
|
715 |
return DataBuf(image_.preview().pData_, image_.preview().size_); |
|
716 |
} |
|
717 | ||
718 |
bool LoaderPsdJpeg::readDimensions() |
|
719 |
{ |
|
720 |
if (!valid()) return false; |
|
721 |
if (width_ || height_) return true; |
|
722 | ||
723 |
try { |
|
724 |
Image::AutoPtr image = ImageFactory::open(image_.preview().pData_, image_.preview().size_); |
|
725 |
if (image.get() == 0) return false; |
|
726 |
image->readMetadata(); |
|
727 | ||
728 |
width_ = image->pixelWidth(); |
|
729 |
height_ = image->pixelHeight(); |
|
730 |
} |
|
731 |
catch (const AnyError& /* error */ ) { |
|
732 |
#ifndef SUPPRESS_WARNINGS |
|
733 |
EXV_WARNING << "Invalid JPEG preview image.\n"; |
|
734 |
#endif |
|
735 |
return false; |
|
736 |
} |
|
737 |
return true; |
|
738 |
} |
|
739 | ||
666 | 740 |
} // namespace |
667 | 741 | |
668 | 742 |
// ***************************************************************************** |
exiv2-0.21.1/src/psdimage.cpp 2011-04-22 23:06:29.000000000 +0200 | ||
---|---|---|
296 | 296 |
break; |
297 | 297 |
} |
298 | 298 | |
299 |
// - PS 4.0 preview data is fetched from ThumbnailResource |
|
300 |
// - PS >= 5.0 preview data is fetched from ThumbnailResource2 |
|
301 |
case kPhotoshopResourceID_ThumbnailResource: |
|
302 |
case kPhotoshopResourceID_ThumbnailResource2: |
|
303 |
{ |
|
304 |
/* Photoshop thumbnail resosurce header |
|
305 |
offset length name description |
|
306 |
====== ======= ==== =========== |
|
307 |
0 4 bytes format = 1 (kJpegRGB). Also supports kRawRGB (0). |
|
308 |
4 4 bytes width Width of thumbnail in pixels. |
|
309 |
8 4 bytes height Height of thumbnail in pixels. |
|
310 |
12 4 bytes widthbytes Padded row bytes as (width * bitspixel + 31) / 32 * 4. |
|
311 |
16 4 bytes size Total size as widthbytes * height * planes |
|
312 |
20 4 bytes compressedsize Size after compression. Used for consistentcy check. |
|
313 |
24 2 bytes bitspixel = 24. Bits per pixel. |
|
314 |
26 2 bytes planes = 1. Number of planes. |
|
315 |
28 Variable Data JFIF data in RGB format. |
|
316 |
Note: For resource ID 1033 the data is in BGR format. |
|
317 |
*/ |
|
318 | ||
319 |
byte buf[28]; |
|
320 |
if (io_->read(buf, 28) != 28) |
|
321 |
{ |
|
322 |
throw Error(3, "Photoshop"); |
|
323 |
} |
|
324 |
uint32_t format_ = getLong(buf, bigEndian); |
|
325 |
uint32_t size_ = getLong(buf + 20, bigEndian); // compressedsize |
|
326 | ||
327 |
if (format_ == 1 && size_ > 0) { |
|
328 |
DataBuf preview(size_); |
|
329 |
io_->read(preview.pData_, preview.size_); |
|
330 |
if (io_->error() || io_->eof()) throw Error(14); |
|
331 |
preview_ = preview; |
|
332 |
} |
|
333 |
break; |
|
334 |
} |
|
335 | ||
299 | 336 |
default: |
300 | 337 |
{ |
301 | 338 |
break; |