"checkit_tiff" is an incredibly fast conformance checker for baseline TIFFs (with various extensions), see http://andreas-romeyke.de
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
7.5 KiB

5 years ago
5 years ago
3 years ago
3 years ago
  1. /* rule based checks if given TIFF is a specific baseline TIFF
  2. *
  3. * author: Andreas Romeyke, 2015-2017
  4. * licensed under conditions of libtiff
  5. * (see file LICENSE)
  6. *
  7. */
  8. #include "config_parser.h"
  9. #include "check.h"
  10. #include "check_helper.h"
  11. #include "check_renderer.h"
  12. #include <unistd.h>
  13. #include <assert.h>
  14. #include <dirent.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <ctype.h>
  19. #ifdef __unix__
  20. #include <unistd.h>
  21. #include <sys/stat.h>
  22. #include <sys/types.h>
  23. #else
  24. /* #include <sys\stat.h> */
  25. #include <sys/stat.h>
  26. #endif
  27. #define FLAGGED 1
  28. #define UNFLAGGED 0
  29. /** help function */
  30. void help () {
  31. printf ("checkit_tiff\n");
  32. printf ("\tversion: %s\n", VERSION);
  33. printf ("\trevision: %s\n", REPO_REVISION);
  34. printf ("licensed under conditions of libtiff (see http://libtiff.maptools.org/misc.html)\n\n");
  35. printf ("call it with:\n");
  36. printf ("\tcheckit_tiff [-c|-h|-m|-d|-q] <configfile> <tifffile> [<tifffile>]\n");
  37. printf ("\nwhere <tifffile> is the tiff file (or directory) to be validated\n");
  38. printf ("and <configfile> is the file name of the validation profile\n");
  39. printf ("\t-h this help\n");
  40. printf ("\t-c colorized output using ANSI escape sequences\n");
  41. printf ("\t-m uses memmapped I/O (faster validation, but needs more RAM)\n");
  42. printf ("\t-d check all files in that directory\n");
  43. printf ("\t-q suppresses the output of all valid tags\n");
  44. printf ("example:\n\tcheckit_tiff example_configs/baseline_minimal.cfg tiffs_should_pass/minimal_valid.tiff \n");
  45. printf ("\n");
  46. }
  47. int check_specific_tiff_file( const char * tiff_file, int use_memmapped) {
  48. GET_EMPTY_RET(res)
  49. /* init render pipeline */
  50. retmsg_t * render_pipeline = malloc( sizeof( retmsg_t) );
  51. if (NULL == render_pipeline) {
  52. exit (could_not_allocate_memory);
  53. }
  54. retmsg_t * actual_render = render_pipeline;
  55. actual_render->rm_type = rm_file;
  56. actual_render->rm_msg = malloc ( sizeof(char) * VALUESTRLEN );
  57. if (NULL == actual_render->rm_msg) {
  58. exit (could_not_allocate_memory);
  59. }
  60. actual_render->next=NULL;
  61. assert(NULL != tiff_file);
  62. strncpy(actual_render->rm_msg, tiff_file, VALUESTRLEN);
  63. /* parse TIFF file */
  64. ctiff_t * ctif = initialize_ctif( tiff_file, use_memmapped?is_memmap:is_filep );
  65. res = parse_header_and_endianess( ctif );
  66. if (res.returncode != is_valid) {
  67. assert(NULL != res.value_found);
  68. __add_to_render_pipeline_via_strncpy(&actual_render, res.value_found, rm_hard_error);
  69. __add_to_render_pipeline_via_strncpy(&actual_render, "", rm_endtiff);
  70. //printf("res.val='%s'\n", res.value_found);
  71. goto renderer_exit;
  72. }
  73. uint32 offset;
  74. res=get_first_IFD(ctif, &offset);
  75. if (res.returncode != is_valid) {
  76. assert(NULL != res.value_found);
  77. __add_to_render_pipeline_via_strncpy(&actual_render, res.value_found, rm_hard_error);
  78. __add_to_render_pipeline_via_strncpy(&actual_render, "", rm_endtiff);
  79. goto renderer_exit;
  80. }
  81. execute_plan(ctif);
  82. res = print_plan_results( actual_render);
  83. renderer_exit:
  84. {
  85. const char * render_result_string = renderer( render_pipeline );
  86. printf("%s\n", render_result_string);
  87. /* free all entries of render pipeline */
  88. __clean_render_pipeline( &render_pipeline );
  89. free((void *) render_result_string);
  90. }
  91. free_ctif( ctif );
  92. if (NULL != res.value_found) {
  93. free(res.value_found);
  94. res.value_found = NULL;
  95. }
  96. return res.returncode;
  97. }
  98. /** main */
  99. int main (int argc, char * argv[]) {
  100. printf("'%s' version: %s\n", argv[0], VERSION);
  101. printf ("\trevision: %s\n", REPO_REVISION);
  102. printf("licensed under conditions of libtiff (see http://libtiff.maptools.org/misc.html)\n");
  103. int c;
  104. int flag_check_directory=UNFLAGGED;
  105. int flag_use_memorymapped_io=UNFLAGGED;
  106. while ((c = getopt (argc, argv, "chmdx:q")) != -1) {
  107. switch (c)
  108. {
  109. case 'h': /* help */
  110. help();
  111. exit (0);
  112. case 'c': /* colorize output */
  113. set_renderer_to_ansi();
  114. break;
  115. case 'x': /* xml output */
  116. set_renderer_to_xml( optarg);
  117. break;
  118. case 'd': /* check directory */
  119. flag_check_directory = FLAGGED;
  120. printf("\nCheck all files in given directory\n");
  121. break;
  122. case 'm': /* use memory mapped I/O */
  123. flag_use_memorymapped_io=FLAGGED;
  124. break;
  125. case 'q': /* suppresses output of valid rules/tags */
  126. set_renderer_to_quiet();
  127. break;
  128. case '?': /* something goes wrong */
  129. /*
  130. if (optopt == 'r') {
  131. fprintf (stderr, "Option -%c requires an argument.\n", optopt);
  132. return (-1);
  133. }
  134. else*/ if (isprint (optopt)) {
  135. fprintf (stderr, "Unknown option `-%c'.\n", optopt);
  136. return (-1);
  137. }
  138. else if (0 !=optopt) {
  139. fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
  140. return (-1);
  141. }
  142. break;
  143. default:
  144. abort();
  145. }
  146. }
  147. if (argc - optind < 2) {
  148. help();
  149. fprintf( stderr, "%s needs at least two arguments, first should be the config-file, second the TIFF-file\nexample:\n\t %s example_configs/baseline_minimal.cfg tiffs_should_pass/minimal_valid.tiff\n", argv[0], argv[0]);
  150. exit (EXIT_FAILURE);
  151. }
  152. const char *cfg_file=argv[optind];
  153. printf("cfg_file=%s\n", cfg_file);
  154. int are_valid = 0;
  155. int index_of_tiff_file_or_dir = optind+1;
  156. do {
  157. const char *tiff_file_or_dir=argv[index_of_tiff_file_or_dir++];
  158. printf("tiff file/dir=%s\n", tiff_file_or_dir);
  159. if (flag_check_directory == FLAGGED) {
  160. /* iterate through all files */
  161. size_t len = strlen( tiff_file_or_dir);
  162. char tiff_dir [ len+1 ];
  163. strncpy(tiff_dir, tiff_file_or_dir, len);
  164. tiff_dir[ len ] = 0;
  165. DIR *dir;
  166. /* remove trailing / */
  167. char *dirsuffix = strrchr(tiff_dir, '/');
  168. if (dirsuffix != NULL) { /* found a / */
  169. if ( 0 == strcmp( dirsuffix, "/" ) ) { /* ok, ends with / */
  170. /* remove last / */
  171. assert(len >= 1); // or whatever you want to do with short strings
  172. tiff_dir[len-1] = 0;
  173. }
  174. }
  175. /* iterate through all files in given dir */
  176. if ((dir = opendir (tiff_file_or_dir)) != NULL) {
  177. /* print all the files and directories within directory */
  178. struct dirent *ent;
  179. while ((ent = readdir (dir)) != NULL) {
  180. struct stat attribute;
  181. len = strlen( tiff_dir ) + strlen( ent->d_name ) + 2;
  182. char fqname [ len ];
  183. snprintf( fqname, len, "%s/%s", tiff_dir, ent->d_name);
  184. if (stat( fqname, &attribute) == -1) {
  185. fprintf (stderr, "could not stat on file '%s' in directory '%s' (%s)\n", ent->d_name, tiff_dir, fqname);
  186. exit(EXIT_FAILURE);
  187. }
  188. if(attribute.st_mode & S_IFREG) {
  189. printf ("%s\n", fqname);
  190. parse_plan_via_file(cfg_file);
  191. are_valid += check_specific_tiff_file( fqname, flag_use_memorymapped_io);
  192. clean_plan();
  193. printf("\n");
  194. }
  195. }
  196. closedir (dir);
  197. } else {
  198. /* could not open directory */
  199. fprintf( stderr, "directory '%s' could not be opened\n", tiff_file_or_dir);
  200. exit(EXIT_FAILURE);
  201. }
  202. } else {
  203. /* use tiff_file_or_dir */
  204. parse_plan_via_file(cfg_file);
  205. are_valid = check_specific_tiff_file( tiff_file_or_dir, flag_use_memorymapped_io);
  206. clean_plan();
  207. }
  208. } while (index_of_tiff_file_or_dir < argc );
  209. if (0 == are_valid) {
  210. exit(EXIT_SUCCESS);
  211. } else {
  212. exit(EXIT_FAILURE);
  213. }
  214. }
  215. /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/