/* '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 <assert.h>
#include "ctstring.h"
/*
#define DEBUG
*/

ret_t check_tag_has_value_in_range(ctiff_t * ctif, tag_t tag, unsigned int a, unsigned int b) {
  GET_EMPTY_RET(ret);
  TIFP_CHECK( ctif, ret);
  EXIST_TAG(ctif, tag, ret);
  if (a > b) { unsigned int c=a; a=b; b=c; }
    TIFFDataType datatype =  TIFFGetRawTagType( ctif, ctif->ifd0, tag );
    ret.returncode=should_not_occur;
    switch (datatype) {
      case TIFF_LONG: {
                        uint32 * valp = NULL;
                        uint32 found=0;
                        ret=TIFFGetFieldLONG(ctif, ctif->ifd0, tag, &valp, &found);
                        ret = set_expected_value_formatted(&ret, "%lu <= v <=%lu", a, b);
                        if (ret.returncode == is_valid) {
                            if (1 == found && NULL != valp) {
                                uint32 val = *valp;
                                if ((val >= a && val <= b)) {
                                    ret.returncode = is_valid;
                                } else {
                                    ret = set_value_found_ret_formatted_with_returncode(&ret, tagerror_value_differs, "value %u", val);
                                }
                            } else {
                                ret = set_value_found_ret_formatted_with_returncode(&ret, tagerror_value_differs, "%u values", found);
                            }
                        } else {
                            ret = set_value_found_ret_formatted(&ret, "not a parseable long field in IFD");
                        }
                        if (NULL != valp) {
                            free(valp);
                            valp = NULL;
                        }
                        return ret;
                        break;
                      }
      case TIFF_SHORT: {
                         uint16 * valp = NULL;
                         uint32 found=0;
                         ret =TIFFGetFieldSHORT(ctif, ctif->ifd0, tag, &valp, &found);
                         ret = set_expected_value_formatted(&ret, "%lu <= v <=%lu", a, b);
                         if (ret.returncode == is_valid) {
                             if (1 == found && NULL != valp) {
                                 uint16 val = *valp;
                                 if ((val >= a && val <= b)) {
                                     ret.returncode = is_valid;
                                 } else {
                                     ret = set_value_found_ret_formatted_with_returncode(&ret, tagerror_value_differs, "value %u", val);
                                 }
                             } else {
                                 ret = set_value_found_ret_formatted_with_returncode(&ret, tagerror_value_differs, "%u values", found);
                             }
                         }else {
                             ret = set_value_found_ret_formatted(&ret, "not a parseable short field in IFD");
                         }
                         if (NULL != valp) {
                             free(valp);
                             valp = NULL;
                         }
                         return ret;
                         break;
                       }
      case TIFF_RATIONAL: {
                            float * valp = NULL;
                            uint32 found=0;
                            ret=TIFFGetFieldRATIONAL(ctif, ctif->ifd0, tag, &valp, &found);
                            ret = set_expected_value_formatted(&ret, "%lu <= v <=%lu", a, b);
                            if (ret.returncode == is_valid) {
                                if (1 == found && NULL != valp) {
                                    float val = *valp;
                                    if ((val >= (float) a && val <= (float) b)) {
                                        ret.returncode = is_valid;
                                    } else {
                                        ret = set_value_found_ret_formatted_with_returncode(&ret, tagerror_value_differs, "value %f", val);
                                    }
                                } else {
                                    ret = set_value_found_ret_formatted_with_returncode(&ret, tagerror_value_differs, "%u values", found);
                                }
                            }else {
                                ret = set_value_found_ret_formatted(&ret, "not a parseable rational field in TIFF");
                            }
                            if (NULL != valp) {
                                free(valp);
                                valp = NULL;
                            }
                            return ret;
                            break;
                          }
      default: /*  none */
                          {
                            ret = set_value_found_ret_with_returncode(&ret, const_str(TIFFTypeName(datatype)),
                                                                      tagerror_unexpected_type_found);
                          }
    }
    assert( ret.returncode != should_not_occur);
    return ret;
}
/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/
