Convert base64 encoded stream into TIF file
Hi All,
I have a requirement where I have to create a TIF file from base64 encoded string comes in HL7 message.
I am reading content and writing to
IS this even possible in cache? what is the correct way of doing this?
$ZV: IRIS for Windows (x86-64) 2020.1
The possibilities to get a corrupted file are:
- you do not read the (Base64) encoded file in chunks of N*4 (where N is an integer)
- your stream wasn't rewinded before starting with reading
- your (incoming) stream is (already) corrupted (but this would in some cases trigger an error in Base64Decode() method).
Just for a test, try this
str = is your incoming Base64 stream
set filename = "test.tiff" open filename:"nwu":1 if '$test write "Can't open",! quit do str.Rewind() use file while 'str.AtEnd { write $system.Encryption.Base64Decode(str.Read(32000)) } // 32000 = 4 * 8000 close file
If the incoming stream is not corruoted, the right now created tiff file should be readable
One more possibility is that the input Base64 stream has line breaks, which have to be omitted. And just read correct length would not be enough, it needs to remove all line breaks, truncate to the closest divisible by 4 length, and using the left tail with the next iteration.
Periodically I see, that some systems may replace symbols such as "+" or "/" in Base64 with something like URL compatible.
Yes I am doing that, below is the code I am using
Set obj=##class(%Stream.FileBinary).%New()
Set input = ""
For i=1:1:$L(obx5,"\.br\")
{
Set decodeline=$system.Encryption.Base64Decode($P(obx5,"\.br\",i))
Set input = input_decodeline
}
Do obj.Write(input)
You are sure, for each and every $P(obx5,"\.br\",i) the equation $L($P(obx5,"\.br\",i))#4=0 holds?
no I am not sure about that
According to your code, the variable obx5 contains the base64 encoded tiff image. There is one thing I do not understand: what are those "\.br\" char-sequences, how they came into the base64 stream?
Anyway, I suppose they are OK (those "\.br\"s), so put all those pieces together and decode all at once:
set input = "" for i=1:1:$L(obx5,"\.br\") { set input = input _ $P(obx5,"\.br\",i)) } Do obj.Write($system.Encryption.Base64Decode(input))
Now you should have a correct decoded image, provided, the obx5 variable really contains the original base64 encoded tiff image with randomly inserted "\.br\" chars (for whatever reason).
The variable obx5 most likely refers to the OBX:5 field of an HL7 message, which is normally used for narrative or image result data in healthcare. \.br\ is a commonly used mechanism for representing line breaks in formatted text data. Why they're included in a base64 string/stream is a mystery, but I've seen stranger.
I think the reason is because of file size my input message.
HL7 file size is 1mb, this code works fine for small messages
The maximum string length for HL7 fields in Health Connect/IRIS for Health is something like 3.6MB; larger than that, the field itself is represented as a stream. You may want to look into the stream methods for accessing fields for your use case.
Ach, the linebreaks, good point, спасибо!