Project

General

Profile

PSD preview implementation ยป exiv2-0.21.1_psd_preview.patch

Michael Ulbrich, 22 Apr 2011 15:51

View differences:

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;
    (1-1/1)