Project

General

Profile

Feature #1199 » exiv2-height-160810.diff

Ben Touchette, 10 Aug 2016 22:29

View differences:

exiv2-0.25/src/webpimage.cpp 2016-08-10 17:23:44.466742686 -0400
33 33
#include "config.h"
34 34

  
35 35
#include "webpimage.hpp"
36
#include "image_int.hpp"
37 36
#include "futils.hpp"
38 37
#include "basicio.hpp"
39 38
#include "tags.hpp"
......
120 119

  
121 120
        io_->read(data, TAG_SIZE * 3);
122 121
        uint64_t filesize = Exiv2::getULong(data + 4, littleEndian);
123
        // uint64_t endoffile = 12;
122
        uint64_t endoffile = 12;
124 123

  
125 124
        /* Set up header */
126 125
        if (outIo.write(data, TAG_SIZE * 3) != TAG_SIZE * 3)
127 126
            throw Error(21);
128 127

  
129 128
        /* Parse Chunks */
129
        bool has_size = false;
130 130
        bool has_xmp = false;
131 131
        bool has_exif = false;
132 132
        bool has_vp8x = false;
133 133
        bool has_alpha = false;
134 134
        bool has_icc = false;
135 135

  
136
        int height;
137
        int width;
138

  
136 139
        byte size_buff[4];
137 140
        std::string xmpData;
138 141
        Blob blob;
......
176 179
                uint64_t size = Exiv2::getULong(size_buff, littleEndian);
177 180
                DataBuf payload(size);
178 181
                io_->read(payload.pData_, payload.size_);
182

  
183
                /* Chunk with color profile. */
179 184
                if (equalsWebPTag(chunkId, "ICCP") && !has_alpha) {
180 185
                    has_icc = true;
181 186
                }
182
                if (equalsWebPTag(chunkId, "VP8X")) {
187

  
188
                /* Chunk with information about features
189
                   used in the file. */
190
                if (equalsWebPTag(chunkId, "VP8X") && !has_vp8x) {
183 191
                    has_vp8x = true;
184 192
                }
185
#if 0 // May need to verify for alpha for these chunks in the future
186
                if (equalsWebPTag(chunkId, "VP8 ") && !has_alpha) {
187
                    has_alpha = true;
193
                if (equalsWebPTag(chunkId, "VP8X") && !has_size) {
194
                    has_size = true;
195
                    byte size_buf[4];
196

  
197
                    // Fetch width
198
                    memcpy(&size_buf, &payload.pData_[4], 3);
199
                    size_buf[3] = 0;
200
                    width = Exiv2::getULong(size_buf, littleEndian) + 1;
201

  
202
                    // Fetch height
203
                    memcpy(&size_buf, &payload.pData_[7], 3);
204
                    size_buf[3] = 0;
205
                    height = Exiv2::getULong(size_buf, littleEndian) + 1;
188 206
                }
207

  
208
                /* Chunk with with animation control data. */
209
#ifdef __CHECK_FOR_ALPHA__  // Maybe in the future
189 210
                if (equalsWebPTag(chunkId, "ANIM") && !has_alpha) {
190 211
                    has_alpha = true;
191 212
                }
192 213
#endif
214

  
215
                /* Chunk with with lossy image data. */
216
#ifdef __CHECK_FOR_ALPHA__ // Maybe in the future
217
                if (equalsWebPTag(chunkId, "VP8 ") && !has_alpha) {
218
                    has_alpha = true;
219
                }
220
#endif
221
                if (equalsWebPTag(chunkId, "VP8 ") && !has_size) {
222
                    has_size = true;
223
                    byte size_buf[4];
224

  
225
                    // Fetch width
226
                    memcpy(&size_buf, &payload.pData_[6], 2);
227
                    size_buf[2] = 0;
228
                    size_buf[3] = 0;
229
                    width = Exiv2::getULong(size_buf, littleEndian) & 0x3fff;
230

  
231
                    // Fetch height
232
                    memcpy(&size_buf, &payload.pData_[8], 2);
233
                    size_buf[2] = 0;
234
                    size_buf[3] = 0;
235
                    height = Exiv2::getULong(size_buf, littleEndian) & 0x3fff;
236
                }
237

  
238
                /* Chunk with with lossless image data. */
193 239
                if (equalsWebPTag(chunkId, "VP8L") && !has_alpha) {
194 240
                    if ((payload.pData_[5] & 0x10) == 0x10) {
195 241
                      has_alpha = true;
196 242
                    }
197 243
                }
244
                if (equalsWebPTag(chunkId, "VP8L") && !has_size) {
245
                    has_size = true;
246
                    byte size_buf_w[2];
247
                    byte size_buf_h[3];
248

  
249
                    // Fetch width
250
                    memcpy(&size_buf_w, &payload.pData_[1], 2);
251
                    size_buf_w[1] &= 0x3F;
252
                    width = Exiv2::getUShort(size_buf_w, littleEndian) + 1;
253

  
254
                    // Fetch height
255
                    memcpy(&size_buf_h, &payload.pData_[2], 3);
256
                    size_buf_h[0] = ((size_buf_h[0] >> 6) & 0x3) | ((size_buf_h[1] & 0x3F) << 0x2);
257
                    size_buf_h[1] = ((size_buf_h[1] >> 6) & 0x3) | ((size_buf_h[2] & 0xF) << 0x2);
258
                    height = Exiv2::getUShort(size_buf_h, littleEndian) + 1;
259
                }
260

  
261
                /* Chunk with animation frame. */
198 262
                if (equalsWebPTag(chunkId, "ANMF") && !has_alpha) {
199 263
                    if ((payload.pData_[5] & 0x2) == 0x2) {
200 264
                      has_alpha = true;
201 265
                    }
202 266
                }
267
                if (equalsWebPTag(chunkId, "ANMF") && !has_size) {
268
                    has_size = true;
269
                    byte size_buf[4];
270

  
271
                    // Fetch width
272
                    memcpy(&size_buf, &payload.pData_[6], 3);
273
                    size_buf[3] = 0;
274
                    width = Exiv2::getULong(size_buf, littleEndian) + 1;
275

  
276
                    // Fetch height
277
                    memcpy(&size_buf, &payload.pData_[9], 3);
278
                    size_buf[3] = 0;
279
                    height = Exiv2::getULong(size_buf, littleEndian) + 1;
280
                }
281

  
282
                /* Chunk with alpha data. */
203 283
                if (equalsWebPTag(chunkId, "ALPH") && !has_alpha) {
204 284
                    has_alpha = true;
205 285
                }
206 286
            }
207 287

  
288
            std::cout << "VP8X res. size [" << width << "x" << height << "]\n";
289
            /* Inject a VP8X chunk if one isn't available. */
208 290
            if (!has_vp8x) {
209
                inject_VP8X(outIo, has_xmp, has_exif, has_alpha, has_icc);
291
                inject_VP8X(outIo, has_xmp, has_exif, has_alpha,
292
                            has_icc, width, height);
210 293
            }
211 294
        }
212 295

  
......
448 575

  
449 576
            if (equalsWebPTag(chunkId, "VP8X") && !has_canvas_data) {
450 577
                has_canvas_data = true;
451
                io_->read(payload.pData_, payload.size_);
452 578
                byte size_buf[4];
579

  
580
                io_->read(payload.pData_, payload.size_);
581

  
582
                // Fetch width
453 583
                memcpy(&size_buf, &payload.pData_[4], 3);
454 584
                size_buf[3] = 0;
455 585
                pixelWidth_ = Exiv2::getULong(size_buf, littleEndian) + 1;
586

  
587
                // Fetch height
456 588
                memcpy(&size_buf, &payload.pData_[7], 3);
457 589
                size_buf[3] = 0;
458 590
                pixelHeight_ = Exiv2::getULong(size_buf, littleEndian) + 1;
......
460 592
                has_canvas_data = true;
461 593
                io_->read(payload.pData_, payload.size_);
462 594
                byte size_buf[4];
595

  
596
                // Fetch width""
463 597
                memcpy(&size_buf, &payload.pData_[6], 2);
464 598
                size_buf[2] = 0;
465 599
                size_buf[3] = 0;
466 600
                pixelWidth_ = Exiv2::getULong(size_buf, littleEndian) & 0x3fff;
601

  
602
                // Fetch height
467 603
                memcpy(&size_buf, &payload.pData_[8], 2);
468 604
                size_buf[2] = 0;
469 605
                size_buf[3] = 0;
470 606
                pixelHeight_ = Exiv2::getULong(size_buf, littleEndian) & 0x3fff;
471 607
            } else if (equalsWebPTag(chunkId, "VP8L") && !has_canvas_data) {
472 608
                has_canvas_data = true;
473
                io_->read(payload.pData_, payload.size_);
474 609
                byte size_buf_w[2];
610
                byte size_buf_h[3];
611

  
612
                io_->read(payload.pData_, payload.size_);
613

  
614
                // Fetch width
475 615
                memcpy(&size_buf_w, &payload.pData_[1], 2);
476 616
                size_buf_w[1] &= 0x3F;
477 617
                pixelWidth_ = Exiv2::getUShort(size_buf_w, littleEndian) + 1;
478
                byte size_buf_h[3];
618

  
619
                // Fetch height
479 620
                memcpy(&size_buf_h, &payload.pData_[2], 3);
480
                size_buf_h[0] = ((size_buf_h[0] >> 6) & 0x3) | ((size_buf_h[1] & 0x3F) << 0x2);
481
                size_buf_h[1] = ((size_buf_h[1] >> 6) & 0x3) | ((size_buf_h[2] & 0x3F) << 0x2);
621
                size_buf_h[0] = ((size_buf_h[0] >> 6) & 0x3) | ((size_buf_h[1]  & 0x3F) << 0x2);
622
                size_buf_h[1] = ((size_buf_h[1] >> 6) & 0x3) | ((size_buf_h[2] & 0xF) << 0x2);
482 623
                pixelHeight_ = Exiv2::getUShort(size_buf_h, littleEndian) + 1;
483 624
            } else if (equalsWebPTag(chunkId, "ANMF") && !has_canvas_data) {
484 625
                has_canvas_data = true;
485
                io_->read(payload.pData_, payload.size_);
486 626
                byte size_buf[4];
627

  
628
                io_->read(payload.pData_, payload.size_);
629

  
630
                // Fetch width
487 631
                memcpy(&size_buf, &payload.pData_[6], 3);
488 632
                size_buf[3] = 0;
489 633
                pixelWidth_ = Exiv2::getULong(size_buf, littleEndian) + 1;
634

  
635
                // Fetch height
490 636
                memcpy(&size_buf, &payload.pData_[9], 3);
491 637
                size_buf[3] = 0;
492 638
                pixelHeight_ = Exiv2::getULong(size_buf, littleEndian) + 1;
......
574 720
        return image;
575 721
    }
576 722

  
577
    bool isWebPType(BasicIo& iIo, bool  /*advance*/)
723
    bool isWebPType(BasicIo& iIo, bool /*advance*/)
578 724
    {
579 725
        const int32_t len = 4;
580 726
        const unsigned char RiffImageId[4] = { 'R', 'I', 'F' ,'F'};
......
616 762
     */
617 763
    void WebPImage::inject_VP8X(BasicIo& iIo, bool has_xmp,
618 764
                                bool has_exif, bool has_alpha,
619
                                bool has_icc) {
765
                                bool has_icc, int width, int height) {
620 766
        byte header[4];
621 767
        byte size[4] = { 0x0A, 0x00, 0x00, 0x00 };
622 768
        byte data[10] = { 0x00, 0x00, 0x00, 0x00, 0x00,
......
642 788
        }
643 789

  
644 790
        /* set width */
645
        int w = pixelWidth_- 1;
791
        int w = width - 1;
646 792
        data[4] = w & 0xFF;
647 793
        data[5] = (w >> 8) & 0xFF;
648 794
        data[6] = (w >> 16) & 0xFF;
649 795

  
650 796
        /* set width */
651
        int h = pixelHeight_- 1;
797
        int h = height - 1;
652 798
        data[7] = h & 0xFF;
653 799
        data[8] = (h >> 8) & 0xFF;
654 800
        data[9] = (h >> 16) & 0xFF;
655
-- exiv2-svn/include/exiv2/webpimage.hpp	2016-08-10 17:55:41.717850199 -0400
801
++ exiv2-0.25/include/exiv2/webpimage.hpp	2016-08-10 16:34:29.979442915 -0400
......
94 94
        bool equalsWebPTag(Exiv2::DataBuf& buf ,const char* str);
95 95
        void decodeChunks(uint64_t filesize);
96 96
        void inject_VP8X(BasicIo& iIo, bool has_xmp, bool has_exif,
97
                         bool has_alpha, bool has_icc);
97
                         bool has_alpha, bool has_icc, int width,
98
                         int height);
98 99

  
99 100
        //! Copy constructor
100 101
        WebPImage(const WebPImage& rhs);
(9-9/12)