/* 'checkit_tiff' is a conformance checker for baseline TIFFs
 *
 * author: Andreas Romeyke, 2015-2024
 * 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_has_tags(ctiff_t * ctif, const cifd_t * ifd) {
    GET_EMPTY_RET(ret);
    TIFP_CHECK( ctif, ret);
    uint16 count = get_ifd_count( ifd);
    ret.returncode=is_valid;
    if (count == 0) {
        char msg_if_subifd[8192] = {0};
        if (ifd->tag_if_subifd < 0) {
            sprintf( msg_if_subifd, "sub IFD (tag=%u)", - ifd->tag_if_subifd);
        } else {
            sprintf( msg_if_subifd, "base IFD");
        }
        ret = set_value_found_ret_formatted_with_returncode(&ret, ifderror_zero_tags, "%s contains zero tags", msg_if_subifd);
    }
    return ret;
}

/* check if offsets are within filesize */
ret_t check_all_IFDs_have_tags(ctiff_t * ctif) {
  GET_EMPTY_RET(ret);
  TIFP_CHECK( ctif, ret);
  ret = check_specific_ifd_has_tags(ctif, ctif->ifd0);
  if (ret.returncode != is_valid) {
      return ret;
  }
  uint16 count = get_ifd0_count( ctif);
  for (int tagidx = 0; tagidx< count; tagidx++) {
      ifd_entry_t ifd_entry = TIFFGetRawTagIFDListEntry(ctif, ctif->ifd0, tagidx);
      uint32 tag = TIFFGetRawTagListEntry(ctif, ctif->ifd0, tagidx);
      if (
              tag_is_an_IFD(&ifd_entry)
            || (tag == TIFFTAG_EXIFIFD)
      ) {

          //printf("DEBUG: found IFD type for tag %u\n", tag);
          uint32 offset = ifd_entry.data32offset;
          cifd_t ifd = {0};
          ifd.tag_if_subifd = -tag;
          get_IFD_at_pos(ctif, offset, &ifd);
          ret = check_specific_ifd_has_tags( ctif, &ifd);
          if (ret.returncode!=is_valid) { return ret; }
      }
  }
  ret.returncode=is_valid;
  return ret;
}


/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/
