/* '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"

/*
#define DEBUG
*/

ret_t check_tag_has_valuelist(ctiff_t * ctif, tag_t tag, unsigned int count, const unsigned int * values) {
  GET_EMPTY_RET(ret);
  TIFP_CHECK( ctif, ret);
  EXIST_TAG(ctif, tag, ret);
  unsigned int v[count];
  char * msg = calloc(256,sizeof(char));
  for (unsigned int i=0; i< count; i++) {
      v[i] = *values;
      snprintf(msg, 255, "v[%u]=%u ", i, v[i]);
      values++;
  }
  ret= set_expected_value_formatted(&ret, "%s", msg);
  ifd_entry_t ifd_entry = TIFFGetRawIFDEntry(ctif, tag);
  if (count != ifd_entry.count) {
    ret = set_value_found_ret_formatted(&ret, "has %u values", ifd_entry.count);
    ret.returncode = tagerror_expected_count_differs;
    return ret;
  }
  switch (ifd_entry.datatype) {
    case TIFF_LONG: {
                      /*  value */
                      if (ifd_entry.value_or_offset == is_value) {
                        for (unsigned int i=0; i< count; i++) {
                          if (v[i] != ifd_entry.data32) {
                            ret = set_value_found_ret_formatted(&ret, "at [%u]=%u", i,  ifd_entry.data32);
                            ret.returncode = tagerror_value_differs;
                            return ret;
                          }
                        }
                      }
                      /*  offset */
                      if (ifd_entry.value_or_offset == is_offset) {
                        offset_t offset;
                        ret = read_offsetdata(ctif, ifd_entry.data32offset, count, ifd_entry.datatype, &offset, &ret);
                        if (ret.returncode != is_valid) {
                           return ret;
                        }
                        const uint32 * p = offset.data32p;
                        for (unsigned int i=0; i< count; i++) {
                          uint32 pval = *p;
#ifdef DEBUG
                          printf("OFFSET: v[%u]=%u p[%u]=%u\n", i,v[i],i,pval);
#endif
                          if (v[i] != *p) {
                            ret = set_value_found_ret_formatted(&ret, "at [%u]=%u", i,  pval);
                            ret.returncode = tagerror_value_differs;
                            return ret;
                          }
                          p++;
                        }
                      }
                      break;
                    }
    case TIFF_SHORT: {
                       /*  value */
                       if (ifd_entry.value_or_offset == is_value) {
                         for (unsigned int i=0; i< count; i++) {
                           int c = (v[i]) == (ifd_entry.data16[i]);
                           if (!c) {
                             ret = set_value_found_ret_formatted( &ret, "at [%u]=%u", i,  ifd_entry.data16[i]);
                             ret.returncode = tagerror_value_differs;
                             return ret;
                           }
                         }
                       }
                       /*  offset */
                       if (ifd_entry.value_or_offset == is_offset) {
                         offset_t offset;
                         ret = read_offsetdata(ctif, ifd_entry.data32offset, count, ifd_entry.datatype, &offset, &ret);
                         if (ret.returncode != is_valid) {
                           return ret;
                         }
                         const uint16 * p = offset.data16p;
                         for (unsigned int i=0; i< count; i++) {
                           uint16 pval = *p;
#ifdef DEBUG
                           printf("SHORTOFFSET (tag=%u): v[%u]=%u p[%u]=0x%04x\n", tag, i,v[i],i,pval);
#endif
                           if (v[i] != pval) {
                             ret = set_value_found_ret_formatted(&ret,  "at [%u]=%u", i,  pval);
                             ret.returncode = tagerror_value_differs;
                             return ret;
                           }
                           p++;
                         }
                       }
                       break;
                     }
    default: /*  none */
                      {
                        ret = set_value_found_ret_formatted(&ret, "type:%s", TIFFTypeName(ifd_entry.datatype));
                        ret.returncode = tagerror_unexpected_type_found;
                        return ret;
                      }

  }
  ret.returncode=is_valid;
  return ret;
}
/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/
