int tiff_initialize()

in graphics/tiff/tiff_initialize.c [437:899]


int tiff_initialize(FAR struct tiff_info_s *info)
{
  uint16_t val16;
#ifdef CONFIG_DEBUG_TIFFOFFSETS
  off_t offset = 0;
#endif
  char timbuf[TIFF_DATETIME_STRLEN + 8];
  int ret = -EINVAL;

  DEBUGASSERT(info && info->outfile && info->tmpfile1 && info->tmpfile2);

  /* Open all output files */

  info->outfd = open(info->outfile, O_RDWR|O_CREAT|O_TRUNC, 0666);
  if (info->outfd < 0)
    {
      gerr("ERROR: Failed to open %s for reading/writing: %d\n",
           info->outfile, errno);
      goto errout;
    }

  info->tmp1fd = open(info->tmpfile1, O_RDWR|O_CREAT|O_TRUNC, 0666);
  if (info->tmp1fd < 0)
    {
      gerr("ERROR: Failed to open %s for reading/writing: %d\n",
           info->tmpfile1, errno);
      goto errout;
    }

  info->tmp2fd = open(info->tmpfile2, O_RDWR|O_CREAT|O_TRUNC, 0666);
  if (info->tmp2fd < 0)
    {
      gerr("ERROR: Failed to open %s for reading/writing: %d\n",
           info->tmpfile2, errno);
      goto errout;
    }

  /* Make some decisions using the color format.  Only the following are
   * supported:
   */

  info->pps = info->imgwidth * info->rps;           /* Pixels per strip */
  switch (info->colorfmt)
    {
      case FB_FMT_Y1:                               /* BPP=1, monochrome, 0=black */
        info->filefmt  = &g_bilevinfo;              /* Bi-level file image file info */
        info->imgflags = IMGFLAGS_FMT_Y1;           /* Bit encoded image characteristics */
        info->bps      = (info->pps + 7) >> 3;      /* Bytes per strip */
        break;

      case FB_FMT_Y4:                               /* BPP=4, 4-bit greyscale, 0=black */
        info->filefmt  = &g_greyinfo;               /* Greyscale file image file info */
        info->imgflags = IMGFLAGS_FMT_Y4;           /* Bit encoded image characteristics */
        info->bps      = (info->pps + 1) >> 1;      /* Bytes per strip */
        break;

      case FB_FMT_Y8:                               /* BPP=8, 8-bit greyscale, 0=black */
        info->filefmt  = &g_greyinfo;               /* Greyscale file image file info */
        info->imgflags = IMGFLAGS_FMT_Y8;           /* Bit encoded image characteristics */
        info->bps      = info->pps;                 /* Bytes per strip */
        break;

      case FB_FMT_RGB16_565:                        /* BPP=16 R=6, G=6, B=5 */
        info->filefmt  = &g_rgbinfo;                /* RGB file image file info */
        info->imgflags = IMGFLAGS_FMT_RGB16_565;    /* Bit encoded image characteristics */
        info->bps      = 3 * info->pps;             /* Bytes per strip */
        break;

      case FB_FMT_RGB24:                            /* BPP=24 R=8, G=8, B=8 */
        info->filefmt  = &g_rgbinfo;                /* RGB file image file info */
        info->imgflags = IMGFLAGS_FMT_RGB24;        /* Bit encoded image characteristics */
        info->bps      = 3 *info->pps;              /* Bytes per strip */
        break;

      default:
        gerr("ERROR: Unsupported color format: %d\n", info->colorfmt);
        return -EINVAL;
    }

  /* Write the TIFF header data to the outfile:
   *
   * Header:    0    Byte Order                  "II" or "MM"
   *            2    Magic Number                42
   *            4    1st IFD offset              10
   *            8    [2 bytes padding]
   */

  ret = tiff_putheader(info);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, TIFF_IFD_OFFSET);

  /* Write the Number of directory entries
   *
   * All formats: Offset 10 Number of Directory Entries 12
   */

  ret = tiff_putint16(info->outfd, info->filefmt->nifdentries);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, 2);

  /* Write the NewSubfileType IFD entry
   *
   * All formats: Offset 12 NewSubfileType
   */

  ret = tiff_putifdentry16(info, IFD_TAG_NEWSUBFILETYPE, IFD_FIELD_LONG, 1, 0);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, SIZEOF_IFD_ENTRY);

  /* Write ImageWidth and ImageLength
   *
   * All formats: Offset 24 ImageWidth  Number of columns is a user parameter
   *                     36 ImageLength Number of rows is a user parameter
   */

  ret = tiff_putifdentry16(info, IFD_TAG_IMAGEWIDTH, IFD_FIELD_SHORT, 1, info->imgwidth);
  if (ret == OK)
    {
      ret= tiff_putifdentry16(info, IFD_TAG_IMAGELENGTH, IFD_FIELD_SHORT, 1, info->imgheight);
    }

  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, 2*SIZEOF_IFD_ENTRY);

  /* Write BitsPerSample
   *
   * Bi-level Images: None
   * Greyscale:       Offset 48 BitsPerSample (4 or 8)
   * RGB:             Offset 48 BitsPerSample (8,8,8)
   */

  tiff_checkoffs(offset, 48);
  if (IMGFLAGS_ISGREY(info->imgflags))
    {
      if (IMGFLAGS_ISGREY8(info->imgflags))
        {
          val16 = 8;
        }
      else
        {
          val16 = 4;
        }

      ret = tiff_putifdentry16(info, IFD_TAG_BITSPERSAMPLE, IFD_FIELD_SHORT, 1, val16);
      if (ret < 0)
        {
          goto errout;
        }
      tiff_offset(offset, SIZEOF_IFD_ENTRY);
    }
  else if (IMGFLAGS_ISRGB(info->imgflags))
    {
      ret = tiff_putifdentry(info, IFD_TAG_BITSPERSAMPLE, IFD_FIELD_SHORT, 3, TIFF_RGB_BPSOFFSET);
      if (ret < 0)
        {
          goto errout;
        }
      tiff_offset(offset, SIZEOF_IFD_ENTRY);
    }

  /* Write Compression:
   *
   * Bi-level Images: Offset 48 Hard-coded no compression (for now)
   * Greyscale:       Offset 60  "  " "   " "" "          " " " " "
   * RGB:             Offset 60 "  " "   " "" "          " " " " "
   */

  ret = tiff_putifdentry16(info, IFD_TAG_COMPRESSION, IFD_FIELD_SHORT, 1, TAG_COMP_NONE);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, SIZEOF_IFD_ENTRY);

  /* Write PhotometricInterpretation:
   *
   * Bi-level Images: Offset 48 Hard-coded BlackIsZero
   * Greyscale:       Offset 72 Hard-coded BlackIsZero
   * RGB:             Offset 72 Hard-coded RGB
   */

  if (IMGFLAGS_ISRGB(info->imgflags))
    {
      val16 = TAG_PMI_RGB;
    }
  else
    {
      val16 = TAG_PMI_BLACK;
    }

  ret = tiff_putifdentry16(info, IFD_TAG_PMI, IFD_FIELD_SHORT, 1, val16);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, SIZEOF_IFD_ENTRY);

  /* Write StripOffsets:
   *
   * Bi-level Images: Offset 72 Value determined by switch statement above
   * Greyscale:       Offset 84 Value determined by switch statement above
   * RGB:             Offset 84 Value determined by switch statement above
   */

  tiff_checkoffs(offset, info->filefmt->soifdoffset);
  ret = tiff_putifdentry(info, IFD_TAG_STRIPOFFSETS, IFD_FIELD_LONG, 0, 0);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, SIZEOF_IFD_ENTRY);

  /* Write SamplesPerPixel
   *
   * Bi-level Images: N/A
   * Greyscale:       N/A
   * RGB:             Offset 96 Hard-coded to 3
   */

  if (IMGFLAGS_ISRGB(info->imgflags))
    {
      ret = tiff_putifdentry16(info, IFD_TAG_SAMPLESPERPIXEL, IFD_FIELD_SHORT, 1, 3);
      if (ret < 0)
        {
          goto errout;
        }
      tiff_offset(offset, SIZEOF_IFD_ENTRY);
    }

  /* Write RowsPerStrip:
   *
   * Bi-level Images: Offset  84 Value is a user parameter
   * Greyscale:       Offset  96 Value is a user parameter
   * RGB:             Offset 108 Value is a user parameter
   */

  ret = tiff_putifdentry16(info, IFD_TAG_ROWSPERSTRIP, IFD_FIELD_SHORT, 1, info->rps);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, SIZEOF_IFD_ENTRY);

  /* Write StripByteCounts:
   *
   * Bi-level Images: Offset  96 Count determined as strips added, Value offset = 216
   * Greyscale:       Offset 108 Count determined as strips added, Value offset = 228
   * RGB:             Offset 120 Count determined as strips added, Value offset = 248
   */

  tiff_checkoffs(offset, info->filefmt->sbcifdoffset);
  ret = tiff_putifdentry(info, IFD_TAG_STRIPCOUNTS, IFD_FIELD_LONG, 0, info->filefmt->sbcoffset);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, SIZEOF_IFD_ENTRY);

  /* Write XResolution and YResolution:
   *
   * Bi-level Images: Offset 108 and 120, Values are a user parameters
   * Greyscale:       Offset 120 and 132, Values are a user parameters
   * RGB:             Offset 132 and 144, Values are a user parameters
   */

  ret = tiff_putifdentry(info, IFD_TAG_XRESOLUTION, IFD_FIELD_RATIONAL, 1, info->filefmt->xresoffset);
  if (ret == OK)
    {
      ret = tiff_putifdentry(info, IFD_TAG_YRESOLUTION, IFD_FIELD_RATIONAL, 1, info->filefmt->yresoffset);
    }

  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, 2*SIZEOF_IFD_ENTRY);

  /* Write ResolutionUnit:
   *
   * Bi-level Images: Offset 132, Hard-coded to "inches"
   * Greyscale:       Offset 144, Hard-coded to "inches"
   * RGB:             Offset 156, Hard-coded to "inches"
   */

  ret = tiff_putifdentry16(info, IFD_TAG_RESUNIT, IFD_FIELD_SHORT, 1, TAG_RESUNIT_INCH);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, SIZEOF_IFD_ENTRY);

  /* Write Software:
   *
   * Bi-level Images: Offset 144 Count, Hard-coded "NuttX"
   * Greyscale:       Offset 156 Count, Hard-coded "NuttX"
   * RGB:             Offset 168 Count, Hard-coded "NuttX"
   */

  ret = tiff_putifdentry(info, IFD_TAG_SOFTWARE, IFD_FIELD_ASCII, TIFF_SOFTWARE_STRLEN, info->filefmt->swoffset);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, SIZEOF_IFD_ENTRY);

  /* Write DateTime:
   *
   * Bi-level Images: Offset 156 Count, Format "YYYY:MM:DD HH:MM:SS"
   * Greyscale:       Offset 168 Count, Format "YYYY:MM:DD HH:MM:SS"
   * RGB:             Offset 180 Count, Format "YYYY:MM:DD HH:MM:SS"
   */

  ret = tiff_putifdentry(info, IFD_TAG_DATETIME, IFD_FIELD_ASCII, TIFF_DATETIME_STRLEN, info->filefmt->dateoffset);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, SIZEOF_IFD_ENTRY);

  /* Write Next IFD Offset and 2 bytes of padding:
   *
   * Bi-level Images: Offset 168, Next IFD offset
   *                  Offset 170, [2 bytes padding]
   * Greyscale:       Offset 180, Next IFD offset
   *                  Offset 182, [2 bytes padding]
   * RGB:             Offset 192, Next IFD offset
   *                  Offset 194, [2 bytes padding]
   */

  ret = tiff_putint32(info->outfd, 0);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, 4);

  /* Now we begin the value section of the file */

  tiff_checkoffs(offset, info->filefmt->valoffset);

  /* Write the XResolution and YResolution data:
   *
   * Bi-level Images: Offset 172 Count, Hard-coded to 300/1
   *                  Offset 180 Count, Hard-coded to 300/1
   * Greyscale:       Offset 184 Count, Hard-coded to 300/1
   *                  Offset 192 Count, Hard-coded to 300/1
   * RGB:             Offset 196 Count, Hard-coded to 300/1
   *                  Offset 204 Count, Hard-coded to 300/1
   */

  tiff_checkoffs(offset, info->filefmt->xresoffset);
  ret = tiff_putint32(info->outfd, 300);
  if (ret == OK)
    {
      ret = tiff_putint32(info->outfd, 1);
    }

  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, 8);

  tiff_checkoffs(offset, info->filefmt->yresoffset);
  ret = tiff_putint32(info->outfd, 300);
  if (ret == OK)
    {
      ret = tiff_putint32(info->outfd, 1);
    }

  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, 8);

  /* Write RGB BitsPerSample Data:
   *
   * Bi-level Images: N/A
   * Greyscale:       N/A
   * RGB:             Offset 212 BitsPerSample (8,8,8)
   *                  Offset 218  [2 bytes padding]
   */

  if (IMGFLAGS_ISRGB(info->imgflags))
    {
      tiff_checkoffs(offset, TIFF_RGB_BPSOFFSET);
      tiff_putint16(info->outfd, 8);
      tiff_putint16(info->outfd, 8);
      tiff_putint16(info->outfd, 8);
      tiff_putint16(info->outfd, 0);
      tiff_offset(offset, 8);
    }

  /* Write the Software string:
   *
   *
   * Bi-level Images: Offset 188, Hard-coded "NuttX"
   * Greyscale:       Offset 200, Hard-coded "NuttX"
   * RGB:             Offset 220, Hard-coded "NuttX"
   */

  tiff_checkoffs(offset, info->filefmt->swoffset);
  ret = tiff_putstring(info->outfd, TIFF_SOFTWARE_STRING, TIFF_SOFTWARE_STRLEN);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, TIFF_SOFTWARE_STRLEN);

  /* Write the DateTime string:
   *
   *
   * Bi-level Images: Offset 188, Format "YYYY:MM:DD HH:MM:SSS"
   * Greyscale:       Offset 200, Hard-coded "NuttX"
   * RGB:             Offset 220, Hard-coded "NuttX"
   */

  tiff_checkoffs(offset, info->filefmt->dateoffset);
  ret = tiff_datetime(timbuf, TIFF_DATETIME_STRLEN + 8);
  if (ret < 0)
    {
      goto errout;
    }

  ret = tiff_putstring(info->outfd, timbuf, TIFF_DATETIME_STRLEN);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, TIFF_DATETIME_STRLEN);

  /* Add two bytes of padding */

  ret = tiff_putint16(info->outfd, 0);
  if (ret < 0)
    {
      goto errout;
    }
  tiff_offset(offset, 2);

  /* And that should do it! */

  tiff_checkoffs(offset, info->filefmt->sbcoffset);
  info->outsize = info->filefmt->sbcoffset;
  return OK;

errout:
  tiff_abort(info);
  return ret;
}