gnuastro-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnuastro-commits] master 738a3812 3/3: Fixed the errors in tiff_img_wri


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 738a3812 3/3: Fixed the errors in tiff_img_write function
Date: Wed, 12 Jul 2023 13:00:40 -0400 (EDT)

branch: master
commit 738a381231e8a94b50b41c2348667b14842f7583
Author: Fathma Mehnoor <fathmamehnoor@gmail.com>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Fixed the errors in tiff_img_write function
    
    Until now, the 'tiff_img_write' function had several errors that prevented
    it from functioning correctly.
    
    With this commit, the following changes have been implemented to address
    these errors and improving the overall functionality of the function:
    
      1. Replaced the function TIFFWriteEncodedStrip which was causing error
         with TIFFWriteScanline for writing into tiff file.
    
      2. Updated the corresponding parts of the function to accommodate the use
         of TIFFWriteScanline.
    
    These modifications rectify the errors in the previous commit and it can
    now successfully write images to TIFF files as intended.
---
 NEWS                         |   7 ++
 bin/convertt/convertt.c      |   5 +-
 bin/convertt/main.h          |   4 -
 bin/convertt/ui.h            |   7 +-
 lib/gnuastro/tiff.h          |   4 +-
 lib/tiff.c                   | 216 ++++++++++++++++++++++++-------------------
 tests/Makefile.am            |   2 +-
 tests/convertt/fitstotiff.sh |   3 +-
 8 files changed, 139 insertions(+), 109 deletions(-)

diff --git a/NEWS b/NEWS
index b18c58b0..fe12ef2a 100644
--- a/NEWS
+++ b/NEWS
@@ -51,6 +51,11 @@ See the end of the file for license conditions.
     - pool-mean: Similar to 'pool-min' but using mean.
     - pool-median: Similar to 'pool-min' but using median.
 
+  ConvertType:
+  - It is now possible to write TIFF files in the output (until now,
+    Gnuastro could only read TIFF files). This step was written by Fathma
+    Mehnoor.
+
   Table:
   - '$_all' in column arithmetic: when an arithmetic expression contains
     this string, it will be repeated independently for all the columns of
@@ -70,6 +75,8 @@ See the end of the file for license conditions.
   - gal_pool_sum: sum-pooling function, see 'pool-min' above.
   - gal_pool_mean: mean-pooling function, see 'pool-min' above.
   - gal_pool_median: median-pooling function, see 'pool-min' above.
+  - gal_tiff_write: write 'gal_data_t' to a TIFF file; written by
+    Fathma Mehnoor.
 
 ** Removed features
 
diff --git a/bin/convertt/convertt.c b/bin/convertt/convertt.c
index 20e8e573..540b4682 100644
--- a/bin/convertt/convertt.c
+++ b/bin/convertt/convertt.c
@@ -366,10 +366,9 @@ convertt(struct converttparams *p)
     /* TIFF */
     case OUT_FORMAT_TIFF:
       if(p->colormap) color_map_prepare(p); else convertt_scale_to_uchar(p);
-      gal_tiff_write(p->chll, p->cp.output, p->widthinpx, p->heightinpx, 
-                    p->bitspersample, p->numch);
+      gal_tiff_write(p->chll, p->cp.output);
       break;
-      
+
 
     /* Not recognized. */
     default:
diff --git a/bin/convertt/main.h b/bin/convertt/main.h
index d30986f4..9ad1233c 100644
--- a/bin/convertt/main.h
+++ b/bin/convertt/main.h
@@ -119,10 +119,6 @@ struct converttparams
   uint8_t      sizeinarcsec;  /* Sizes are in arcseconds (in WCS-mode).*/
   uint8_t      sizeinarcmin;  /* Sizes are in arcminutes (in WCS-mode).*/
   uint8_t marktextprecision;  /* Precision to convert floats.          */
-  int             widthinpx;  /* Width of image in pixel.              */
-  int            heightinpx;  /* Height of image in pixel.             */
-  int         bitspersample;  /* Number of bits used to represent color 
-                                 of a single pixel.                    */
 
   /* Internal */
   struct change     *change;  /* The value conversion string.          */
diff --git a/bin/convertt/ui.h b/bin/convertt/ui.h
index 7020b39f..888deaab 100644
--- a/bin/convertt/ui.h
+++ b/bin/convertt/ui.h
@@ -43,8 +43,8 @@ enum program_args_groups
 
 /* Available letters for short options:
 
-   a d e f j k n s t v y z
-   E G J Q R X Y
+   a d e f j k l n p s t v y z
+   E G J Q R W X Y
 */
 enum option_keys_enum
 {
@@ -64,9 +64,6 @@ enum option_keys_enum
   UI_KEY_INVERT              = 'i',
   UI_KEY_MODE                = 'O',
   UI_KEY_MARKCOORDS          = 'r',
-  UI_KEY_WIDTHINPX           = 'W',
-  UI_KEY_HEIGHTINPX          = 'l',
-  UI_KEY_BITSPERSAMPLE       = 'p',
 
   /* Only with long version (start with a value 1000, the rest will be set
      automatically). */
diff --git a/lib/gnuastro/tiff.h b/lib/gnuastro/tiff.h
index 744f9534..63680c5f 100644
--- a/lib/gnuastro/tiff.h
+++ b/lib/gnuastro/tiff.h
@@ -5,6 +5,7 @@ This is part of GNU Astronomy Utilities (Gnuastro) package.
 Original author:
      Mohammad Akhlaghi <mohammad@akhlaghi.org>
 Contributing author(s):
+     Fathma Mehnoor <fathmamehnoor@gmail.com>
 Copyright (C) 2018-2023 Free Software Foundation, Inc.
 
 Gnuastro is free software: you can redistribute it and/or modify it
@@ -67,8 +68,7 @@ gal_data_t *
 gal_tiff_read(char *filename, size_t dir, size_t minmapsize, int quietmmap);
 
 void
-gal_tiff_write(gal_data_t *in, char *filename, int widthinpx, int heightinpx, 
-               int bitspersample, int numimg);
+gal_tiff_write(gal_data_t *in, char *filename);
 
 
 __END_C_DECLS    /* From C++ preparations */
diff --git a/lib/tiff.c b/lib/tiff.c
index c1a32205..848efa25 100644
--- a/lib/tiff.c
+++ b/lib/tiff.c
@@ -5,6 +5,7 @@ This is part of GNU Astronomy Utilities (Gnuastro) package.
 Original author:
      Mohammad Akhlaghi <mohammad@akhlaghi.org>
 Contributing author(s):
+     Fathma Mehnoor <fathmamehnoor@gmail.com>
 Copyright (C) 2018-2023 Free Software Foundation, Inc.
 
 Gnuastro is free software: you can redistribute it and/or modify it
@@ -632,74 +633,117 @@ gal_tiff_read(char *filename, size_t dir, size_t 
minmapsize, int quietmmap)
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 /*************************************************************
  ****************    Write into a TIFF file   ****************
  *************************************************************/
-
-/* Write image data into a TIFF file using libtiff library*/
 #ifdef HAVE_LIBTIFF
-static int
-tiff_img_write(TIFF *tif, gal_data_t *in, char *filename, int widthinpx, 
-              int heightinpx, size_t numch, int bitspersample, int numimg) 
+static void
+tiff_img_write(TIFF *tif, gal_data_t *in, char *filename)
 {
-    
-    size_t c;
-    int i, out;
-    uint32_t stripoffset, stripcount;
-    size_t bytespersample = bitspersample / 8;
-    uint32_t stripsize = TIFFDefaultStripSize(tif, widthinpx * numch 
-                                              * bytespersample);
-    uint32_t rowsperstrip = stripsize / (widthinpx * numch * bytespersample);
-  
-    /*Make sure rowspwerstrip is not 0*/
-    if (rowsperstrip == 0) {
-        rowsperstrip = 1;
+  gal_data_t *channel = in;
+  size_t index, offset, row, col, ch;
+  size_t numch = gal_list_data_number(in);
+  unsigned char *image, *buf, *colors[4] = {NULL};
+  size_t width = in->dsize[1], height = in->dsize[0];
+
+  /* Small sanity checks. */
+  if(numch==2 || numch>4)
+    error(EXIT_FAILURE, 0, "%s: only 1, 3, and 4 color channels are "
+          "acceptable, input is a list of %zu data sets", __func__,
+          numch);
+  if(in->type!=GAL_TYPE_UINT8)
+    error(EXIT_FAILURE, 0, "%s: input has a '%s' type, but TIFF "
+          "images can currently only have a 'uint8' type", __func__,
+          gal_type_name(in->type, 1));
+
+  /* Allocate memory for image */
+  image = (unsigned char*)malloc(in->size * numch);
+  if(image == NULL)
+    error(EXIT_FAILURE, errno, "%s: %s: failed to allocate memory"
+          "for image", __func__, filename);
+
+  /* Extract color channels from input data */
+  for(ch = 0; ch < numch; ch++)
+    {
+      if(channel != NULL && channel->array != NULL)
+        {
+          colors[ch] = channel->array;
+          channel = channel->next;
+        }
+      else
+        {
+          error(EXIT_FAILURE, errno, "%s: %s: missing or invalid color"
+                "channel", __func__, filename);
+          free(image);
+        }
     }
 
-    /*Recalculate stripsize based on the rowsperstrip*/
-    stripsize = rowsperstrip * widthinpx * numch * bytespersample;
-    
-    /*Set TIFF tags that define image properties for image data*/
-    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, widthinpx);
-    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, heightinpx);
-    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, numch);
-    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
-    TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
-    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_SEPARATE);
-    
-    /*For each number of image and channel, write the data into the TIFF file*/
-    for (i = 0; i < numimg; i++) {
-        for (c = 0; c < numch; c++) {
-            /*Calculate the offset of current strip*/
-            stripoffset = i * rowsperstrip * widthinpx * numch;
-
-            /*Calculate the number of rows per each strip while making sure 
-            that it does not exceed the image height*/
-            stripcount = heightinpx - stripoffset * rowsperstrip;
-            if (stripcount > rowsperstrip) {
-                stripcount = rowsperstrip;
-            }
-
-            /*Write the data of the current strip into the TIFF file*/
-            out = TIFFWriteEncodedStrip(tif, c, (void*)((char*)in + 
-                                       (stripoffset * widthinpx * numch + c)
-                                        * bytespersample), stripsize * 
stripcount);
+  /* Copy input data to image buffer */
+  for(row = 0; row < height; row++)
+    {
+      for(col = 0; col < width; col++)
+        {
+          index = row * width + col;
+          offset = index * numch;
 
-            /*If there is an error writing into TIFF file close the file and
-            return -1 */
-            if (out < 0) {
-                TIFFClose(tif);
-                return -1;
-            }
+          for(ch = 0; ch < numch; ch++)
+            image[offset + ch] = colors[ch][index];
         }
+    }
+
+  /* Set TIFF tags */
+  TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
+  TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
+  if(numch==1)
+    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
+  else
+    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+  TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
+  TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, numch);
+  TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
+  TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+
+  /* Allocate memory for scanline buffer */
+  errno=0;
+  buf = (unsigned char*)_TIFFmalloc(TIFFScanlineSize(tif));
+  if(buf == NULL)
+    error(EXIT_FAILURE, errno, "%s: %s: failed to allocate necessary"
+          "memory for the scanline buffer" , __func__, filename);
+
+  /* Write each scanline of the image to the TIFF file */
+  for(row = height; row > 0; row--)
+    {
+      _TIFFmemcpy(buf, &image[(row - 1) * width * numch], width * numch);
 
-        /*Write the TIFF directory for current image*/
-        TIFFWriteDirectory(tif);
+      if(TIFFWriteScanline(tif, buf, height - row, 0) < 0)
+        {
+          error(EXIT_FAILURE, errno, "%s: problem in writing to %s",
+                __func__, filename);
+          _TIFFfree(buf);
+          free(image);
+        }
     }
-    /*return success*/
-    return 0;
-    
-    
+
+  /* Clean up */
+  _TIFFfree(buf);
+  free(image);
 }
 #endif
 
@@ -708,45 +752,31 @@ tiff_img_write(TIFF *tif, gal_data_t *in, char *filename, 
int widthinpx,
 
 
 void
-gal_tiff_write(gal_data_t *in, char *filename, int widthinpx, int heightinpx,
-              int bitspersample, int numimg)
+gal_tiff_write(gal_data_t* in, char* filename)
 {
-  #ifdef HAVE_LIBTIFF
-
-  int out;
-  size_t numch=gal_list_data_number(in);
- 
-  /*Open the TIFF file*/
-  TIFF* tif = TIFFOpen(filename, "w");
-  if (tif==NULL) {
-    error(EXIT_FAILURE, 0, "%s: '%s' couldn't be opened for writing",
+/* The TIFF library exists and will be used. */
+#ifdef HAVE_LIBTIFF
+  TIFF* tif;
+
+  /* Make sure the input isn't NULL. */
+  if(in == NULL)
+    error(EXIT_FAILURE, 0, "%s: '%s', input data is NULL",
           __func__, filename);
-  }
-
-  /*Check if input parameters have valid values*/
-  if( widthinpx <=0 || bitspersample <= 0 || numch <= 0){
-    error(EXIT_FAILURE, 0, "%s: '%s', widthinpx=%d, bitspersample=%d,"
-        "numch=%zu, values should be greater than 0",
-        __func__, filename, widthinpx, bitspersample, numch);
-  }
-
-  /*Check if the file already exists or has write permissions*/
-  if( gal_checkset_writable_notexist(filename)==0 )
-    error(EXIT_FAILURE, 0, "%s: already exists or its directory doesn't "
-          "write permssion. ", filename);
-
-  /*Write to TIFF file*/
-  out = tiff_img_write(tif, in, filename, widthinpx, heightinpx,
-                       numch, bitspersample, numimg);
-  if(out < 0){
-    error(EXIT_FAILURE, 0, "%s: problem in writing to %s",__func__, filename);
-    
-  }
-  /*Close file*/
+
+  /* Open the TIFF file */
+  tif = TIFFOpen(filename, "w");
+  if(tif == NULL)
+    error(EXIT_FAILURE, errno,
+          "%s: '%s' couldn't be opened for writing", __func__, filename);
+
+  /* Write to TIFF file */
+  tiff_img_write(tif, in, filename);
+
+  /* Close file */
   TIFFClose(tif);
 
-  #else
+  /* The TIFF library didn't exist. */
+#else
   tiff_error_no_litiff(__func__);
-  return NULL;
-  #endif /*HAVE_LIBTIFF*/
+#endif
 }
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3390205f..faa0316d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -320,7 +320,7 @@ EXTRA_DIST = $(TESTS) during-dev.sh \
 
 
 # Files that must be cleaned with 'make clean'.
-CLEANFILES = *.log *.txt *.jpg *.fits *.pdf *.eps simpleio
+CLEANFILES = *.log *.txt *.jpg *.fits *.pdf *.eps *.tif simpleio
 
 
 
diff --git a/tests/convertt/fitstotiff.sh b/tests/convertt/fitstotiff.sh
index 54e863b7..12f70359 100755
--- a/tests/convertt/fitstotiff.sh
+++ b/tests/convertt/fitstotiff.sh
@@ -6,7 +6,8 @@
 # Original author:
 #     Mohammad Akhlaghi <mohammad@akhlaghi.org>
 # Contributing author(s):
-# Copyright (C) 2015-2023 Free Software Foundation, Inc.
+#     Fathma Mehnoor <fathmamehnoor@gmail.com>
+# Copyright (C) 2023-2023 Free Software Foundation, Inc.
 #
 # Copying and distribution of this file, with or without modification,
 # are permitted in any medium without royalty provided the copyright



reply via email to

[Prev in Thread] Current Thread [Next in Thread]