/* 'checkit_tiff' is a conformance checker for baseline TIFFs
 *
 * author: Andreas Romeyke, 2015-2022
 * licensed under conditions of libtiff
 * (see http://libtiff.maptools.org/misc.html)
 *
 */

#include "check.h"
#include "check_helper.h"
#include "ctstring.h"

static ret_t check_specific_ifd_word_aligned(uint32 ifd_pos, tag_t tag) {
    GET_EMPTY_RET(ret);
    if (0 == (ifd_pos & 1)) {
        ret.returncode = is_valid;
        return ret;
    } else {
        // FIXME: tif_fails?
        ret = set_value_found_ret_formatted_with_returncode(&ret, ifderror_offset_not_word_aligned, "offset of tag-ifd (%lu) points to 0x%08x and is not word-aligned", tag, ifd_pos);
        return ret;
    }
}

static ret_t check_first_ifd_word_aligned(uint32 ifd_pos) {
    GET_EMPTY_RET(ret);
    if (0 == (ifd_pos & 1)) {
        ret.returncode = is_valid;
        return ret;
    } else {
        // FIXME: tif_fails?
        ret = set_value_found_ret_formatted_with_returncode(&ret, ifderror_offset_not_word_aligned, "offset of first ifd points to 0x%08x and is not word-aligned", ifd_pos);
        return ret;
    }
}

/* check if IFDs are word aligned */
ret_t check_all_IFDs_are_word_aligned(ctiff_t *ctif) {
  TIFP_CHECK( ctif, ret);
  uint32 ifd = get_ifd0_pos( ctif );
  uint16 count = get_ifd0_count( ctif);
  for (uint16 tagidx = 0; tagidx< count; tagidx++) {
      ifd_entry_t ifd_entry = TIFFGetRawTagIFDListEntry(ctif, ctif->ifd0, tagidx);
      if (ifd_entry.datatype == TIFF_IFD || ifd_entry.datatype == TIFF_IFD8) {
          uint32 offset = ifd_entry.data32offset;
          tag_t tag = TIFFGetRawTagListEntry( ctif, ctif->ifd0, tagidx);
          ret_t ret = check_specific_ifd_word_aligned(offset, tag);
          if (ret.returncode != is_valid ) { return ret; }
      }
  }
  return check_first_ifd_word_aligned(ifd);
}
/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/
