github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/webp/libwebp/examples/tiffdec.c (about)

     1  // Copyright 2012 Google Inc. All Rights Reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style license
     4  // that can be found in the COPYING file in the root of the source
     5  // tree. An additional intellectual property rights grant can be found
     6  // in the file PATENTS. All contributing project authors may
     7  // be found in the AUTHORS file in the root of the source tree.
     8  // -----------------------------------------------------------------------------
     9  //
    10  // TIFF decode.
    11  
    12  #include "./tiffdec.h"
    13  
    14  #ifdef HAVE_CONFIG_H
    15  #include "config.h"
    16  #endif
    17  
    18  #include <stdio.h>
    19  
    20  #ifdef WEBP_HAVE_TIFF
    21  #include <tiffio.h>
    22  
    23  #include "webp/encode.h"
    24  #include "./metadata.h"
    25  
    26  static const struct {
    27    ttag_t tag;
    28    size_t storage_offset;
    29  } kTIFFMetadataMap[] = {
    30    { TIFFTAG_ICCPROFILE, METADATA_OFFSET(iccp) },
    31    { TIFFTAG_XMLPACKET,  METADATA_OFFSET(xmp) },
    32    { 0, 0 },
    33  };
    34  
    35  // Returns true on success. The caller must use MetadataFree() on 'metadata' in
    36  // all cases.
    37  static int ExtractMetadataFromTIFF(TIFF* const tif, Metadata* const metadata) {
    38    int i;
    39    toff_t exif_ifd_offset;
    40  
    41    for (i = 0; kTIFFMetadataMap[i].tag != 0; ++i) {
    42      MetadataPayload* const payload =
    43          (MetadataPayload*)((uint8_t*)metadata +
    44                             kTIFFMetadataMap[i].storage_offset);
    45      void* tag_data;
    46      uint32 tag_data_len;
    47  
    48      if (TIFFGetField(tif, kTIFFMetadataMap[i].tag, &tag_data_len, &tag_data) &&
    49          !MetadataCopy((const char*)tag_data, tag_data_len, payload)) {
    50        return 0;
    51      }
    52    }
    53  
    54    // TODO(jzern): To extract the raw EXIF directory some parsing of it would be
    55    // necessary to determine the overall size. In addition, value offsets in
    56    // individual directory entries may need to be updated as, depending on the
    57    // type, they are file based.
    58    // Exif 2.2 Section 4.6.2 Tag Structure
    59    // TIFF Revision 6.0 Part 1 Section 2 TIFF Structure #Image File Directory
    60    if (TIFFGetField(tif, TIFFTAG_EXIFIFD, &exif_ifd_offset)) {
    61      fprintf(stderr, "Warning: EXIF extraction from TIFF is unsupported.\n");
    62    }
    63    return 1;
    64  }
    65  
    66  int ReadTIFF(const char* const filename,
    67               WebPPicture* const pic, int keep_alpha,
    68               Metadata* const metadata) {
    69    TIFF* const tif = TIFFOpen(filename, "r");
    70    uint32 width, height;
    71    uint32* raster;
    72    int ok = 0;
    73    tdir_t dircount;
    74  
    75    if (tif == NULL) {
    76      fprintf(stderr, "Error! Cannot open TIFF file '%s'\n", filename);
    77      return 0;
    78    }
    79  
    80    dircount = TIFFNumberOfDirectories(tif);
    81    if (dircount > 1) {
    82      fprintf(stderr, "Warning: multi-directory TIFF files are not supported.\n"
    83                      "Only the first will be used, %d will be ignored.\n",
    84                      dircount - 1);
    85    }
    86  
    87    if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) &&
    88          TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))) {
    89      fprintf(stderr, "Error! Cannot retrieve TIFF image dimensions.\n");
    90      return 0;
    91    }
    92    raster = (uint32*)_TIFFmalloc(width * height * sizeof(*raster));
    93    if (raster != NULL) {
    94      if (TIFFReadRGBAImageOriented(tif, width, height, raster,
    95                                    ORIENTATION_TOPLEFT, 1)) {
    96        const int stride = width * sizeof(*raster);
    97        pic->width = width;
    98        pic->height = height;
    99        // TIFF data is ABGR
   100  #ifdef __BIG_ENDIAN__
   101        TIFFSwabArrayOfLong(raster, width * height);
   102  #endif
   103        pic->use_argb = 1;
   104        ok = keep_alpha
   105           ? WebPPictureImportRGBA(pic, (const uint8_t*)raster, stride)
   106           : WebPPictureImportRGBX(pic, (const uint8_t*)raster, stride);
   107      }
   108      _TIFFfree(raster);
   109    } else {
   110      fprintf(stderr, "Error allocating TIFF RGBA memory!\n");
   111    }
   112  
   113    if (ok) {
   114      if (metadata != NULL) {
   115        ok = ExtractMetadataFromTIFF(tif, metadata);
   116        if (!ok) {
   117          fprintf(stderr, "Error extracting TIFF metadata!\n");
   118          MetadataFree(metadata);
   119          WebPPictureFree(pic);
   120        }
   121      }
   122    }
   123  
   124    TIFFClose(tif);
   125    return ok;
   126  }
   127  #else  // !WEBP_HAVE_TIFF
   128  int ReadTIFF(const char* const filename,
   129               struct WebPPicture* const pic, int keep_alpha,
   130               struct Metadata* const metadata) {
   131    (void)filename;
   132    (void)pic;
   133    (void)keep_alpha;
   134    (void)metadata;
   135    fprintf(stderr, "TIFF support not compiled. Please install the libtiff "
   136            "development package before building.\n");
   137    return 0;
   138  }
   139  #endif  // WEBP_HAVE_TIFF
   140  
   141  // -----------------------------------------------------------------------------