Question
· Jan 13, 2021

Reading TIF file using ObjectScript

Hi, 

I'm trying to read a TIF file using ObjectScript. 

I know that it is possible to achieve using python or R, but I don't know how to do it using ObjectScript.

If anyone has done it before and has some advice, I really appreciate it. 

Best Regards,
Henrique

Product version: IRIS 2020.4
Discussion (10)1
Log in or sign up to continue

If it's just pure import / export  the .TIF you may access it as %Stream.FileBinary

But if you need some more sophisticated processing and have some working method (eg. in Python)
you may use it in some near future with the promised embedded Python  [@Bob Kuszewski ]
 

Until then you may take a look to my example in OEX about using Python methods & classes over CPIPE 

 

with landslide situations.

I don't understand what you mean.

You should understand that ObjectScript is not a good way, to deal with such data as pictures, it's not a task for databases to deal with pictures on a low-level. If you need it on ObjectScript level, I would recommend using imagemagick tool, which is external for sure, and available for any platform. But you will get a lot of functionality. and getting image info as well, and you will not be limited by tiff format only. And in addition you will get the ability to do some other stuff with images, scaling, drawing conversion, and so on, it's very powerful.

After a brief look at the tif format, it found to be quite tricky to get ImageSize.

tif(folder, filename) {
#define READWORD $sconvert(fs.Read(2),"U2",endian)
#define READLONG $sconvert(fs.Read(4),"U4",endian)
#define WORD(%val) $sconvert(%val,"U2",endian)
#define LONG(%val) $sconvert(%val,"U4",endian)

  Set fs = ##class(%Stream.FileBinary).%New()
  Set fs.Filename = ##class(%File).NormalizeFilename(filename, folder)
  Set FileSize = fs.Size
  
  Set Width = 0, Height = 0

  Set Identifier = fs.Read(2)
  If Identifier=$Char(73,73) {
    Set endian = 0
  } ElseIf Identifier=$Char(77,77) {
    Set endian = 1
  } Else {
    Throw "Bad Format"
  }
  Set Version = fs.Read(2)

  Set IFDOffset = $$$READLONG
  
  Do {
    Do fs.MoveTo(IFDOffset+1)
    
    Set NumDirEntries = $$$READWORD
    For i=1:1:NumDirEntries {
      Set tag = fs.Read(12)
      Set TagID = $$$WORD($Extract(tag,1,2))
      Set DataType = $$$WORD($Extract(tag,3,4))
      If (TagID=256)||(TagID=257) {
        Set Value = -1
        If DataType=3 Set Value = $$$WORD($Extract(tag,9,12))
        If DataType=4 Set Value = $$$LONG($Extract(tag,9,12))
        Set:TagID=256 Width = Value
        Set:TagID=257 Height = Value
      }
    }
    Set NextIFDOffset = $$$READLONG
    Set IFDOffset = NextIFDOffset
    
    Quit:(Height>0)&&(Width>0)
  } While NextIFDOffset>0

  ZWrite Height,Width
}

I'm not sure, what you want to do, but if you want to read a tiff file by byte-by-byte and the interpret it in some kind, there is a very simple example for the start.
 The method below returns the file type (gif,jpg,png or tif) based on the magic number.

/// Identify an image by its magic number
/// (only for gif,jpg,png and tif)
ClassMethod ImageType(file, ByRef err)
{
   o file:"ru":0
   i $t {
      s io=$i, err=""
      u file r x#8
      
      i x?1"GIF8"1(1"7",1"9")1"a" { s typ="gif" }
      elseif $e(x,1,2)=$c(255,216), $$end()=$c(255,217) { s typ="jpg" }
      elseif x=$c(137,80,78,71,13,10,26,10) { s typ="png" }
      elseif $case($e(x,1,4), $c(73,73,42,0):1, $c(77,77,0,42):1, :0) { s typ="tif" }
      else { s typ="", err="File type unknown" }
      
      c file
      u:io]"" io
   
   } else { s typ="", err="Can't open "_file }
   
   q typ

end() s t="" r:$zseek(-2,2) t#2 q t
}

I have also a method to retrive the image size (pixelsWidth and pixelsHeight) for the same (gif,jpg,png and tif) files. If you are working on similar problem, I could post this method too.

Ok, here I am... sorry for the delay.

***********************************************

Forget it!

I'm unable to copy and paste a program (in this case a method) into this text box!

After paste operation, some lines are joint, others not,  the indention is lost...

Maybe I'm just too dumb to work with the text box...

*****************************************

If you want this class, you can it download from my FTP.
ftp: ftp.kavay.at
usr: dcmember
psw: member-of-DC