Catching errors for CIFilter.outputImage when using CIAztecCodeGenerator/CIQRCodeGenerator - ios

I'm trying to create 2D barcode images with iOS and CoreImage using a CIFilter for CIAztecCodeGenerator. Depending on the length of the text and the error correction level settings, CIFilter.outputImage sometimes returns nil.
The following message is printed on the console only:
Unable to create barcode. The message is too large for an Aztec
barcode.
A similar message will be printed when using CIQRCodeGenerator.
Is there a way to catch this kind of error for CIFilter in code or find out in advance if the text will be too long to be processed?
Thank you very much for any suggestions!

The maximum size of the data depends on the correction level and also on the type of message that you want to encode. For example if your text only have numbers then a different encoding is used to put that data in the barcode and more characters will be allowed. You cannot really detect that specific error but you can always just check if the result was nil. If it was nil then probably beacuse message was too long.
According to documentation at https://developer.apple.com/library/archive/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/filter/ci/CIAztecCodeGenerator :
The full-size format can store up to 1914 bytes of message data
(including correction) in up to 32 layers, producing a barcode image
sized no larger than 151 x 151 pixels.
Also at https://help.accusoft.com/BarcodeXpress/v13.2/BxNodeJs/aztec.html you will find this 1914 bytes value. So probably you could assume that anything that is not larger than 1914 bytes should be successfully encoded by CIAztecCodeGenerator, but encoding anything above that size could fail.

Related

Reading byte by byte HEIF/HEIC images XMP metadata

I am trying to build a native byte parser that given an HEIF image it returns back its metadata (mainly width and height of the image).
I am struggling a lot at the moment finding the right documentation and specs to use for parsing such info. I have to do such thing for both XMP and EXIF metadata, but let's focus only on XMP for now.
What I need is the exact byte structure of where to find what. According to the HEIF international standard doc (here):
For image items, XMP metadata shall be stored as an item of item_type value 'mime' and content type'application/rdf+xml'. The body of the item shall be a valid XMP document, in XML form.
Perfect, if I analyse a sample image I can find such marker:
From now on I can't find anywhere how to get the info I need. I would expect something saying "the first 2 bytes are the header, with marker 0xFF 0xCE (just an example), the next 2 bytes are the width, and following 2 bytes the height...etc".
In my case I am going by intuition. My sample image is of dimensions 8736x5856. If in the tool I look for Big-Endian 2 byte integer 8736, I can find it:
And hey, 2 bytes later there is the 5856 height as well:
But again, I arrived here by luck and intuition. I need a proper schema that tells me where to find what in such a way that I can traslate it to code.
What I think you'r seeing is a "mime" and "ispe" mp4 box as HEIF is ISOBMFF based. I would recommend looking at the file using a mp4 capable tool like mp4dump, HexFiend or fq (note: my tool). The "ispe" (Image Spatial Extents) box i probably what you want to read.
fq does no support ispe box yet but you could read it like this:
$ fq 'grep_by(.type=="ispe").data | tobytes | [.[-8:-4], .[-4:] | tonumber]' file.heif
[
8736,
5856
]
So what you need is probably a basic ISOBMFF reader and then look for the "ispe" box and decode it. If you'r only looking for the first of a specific box you can probably ignore that ISOBMFF is a tree structure.

NVIDIA NVENC (Media Foundation) encoded h.264 frames not decoded properly using VideoToolbox

I am facing the same problem as described here when trying to decode a frame on iPad Pro OS v14.3 (I am also using Olivia Stork's example):
25% of the picture data is decoded correctly, the rest of the picture is just green.
The decoded image on iPad Pro OS v14.3 looks like this (the image was converted and saved in the decoder callback as described here, so it's not just a displaying problem).
The original image looks like this.
The image is encoded with NVIDIA NVENC (Media Foundation) on Windows10.
I searched the frame picture data for additional 4-Byte NALU start codes as described in the link, but there are only the three expected ones for SPS, PPS and IDR picture data.
I have another Media Foundation decoder application running on Windows10 which can decode the frames from exactly the same source correctly.
I am struggling for days now finding the cause of the problem.. anyone any ideas?
Thanks in advance. Rob
-
EDIT 2021-01-11:
I figured out that there are actually three additional 3-byte start codes (0x000001) within in the IDR picture data block of NALU type 5.
I tried to replace these start codes with the length of the following data block (big endian), as described here, but with the same result.
I also tried adding Emulation Prevention Bytes (0x000001 => 0x000301) as described here, but that also made no difference.
Maybe I am mislead and these start codes have nothing to do with the issue.. at least they are not just random image data, because they always appear at the same position (index) in the picture data block. Currently I am running out of ideas.. any hint anybody?
-
EDIT 2021-01-14:
I figured out a few more things:
Out of sheer lack of ideas I copied the picture data followed after the last start code at the beginning of the block (right after after the 4-Byte NALU start code).
I had expected - if that would work at all - to see the last quarter of the original image at the top of the decoded image, but to my surprise the decoded image looked like this.
I tried the same with the picture data coming after the second and third start code, and the decoded image looked like this and this:
The image data is decoded correctly and it is even at the correct position (compare to original image).
Even if I strip off all 3-Byte start codes and copy the picture data concatenated after the 4-Byte start code, it's the same result, only 25% of the image is decoded. So the additional 3-Byte start codes are apparently not the problem. There must be some setting somewhere which tells the decoder to only decode 25% of the image. I would tip on the CMVideoFormatDescription, but as far as I can see it looks okay.
I am also wondering how the decoder knows where to display the different picture data blocks. Either there is an offset defined somewhere within the picture data or the xy-position of every pixel is added by the encoder somehow..
I managed to find the cause of the problem: The 3-Byte start codes in the IDE picture data block must be replaced by 4-Byte start codes.
So first replace all 3-Byte start codes by 4-Byte start codes.
Then replace the 4-Byte start codes with the length of the following data block (big endian). The slices should be arranged like this (as mentioned here by 'Blackie'):
[4byte slice1 size][slice1 data][4byte slice2 size][slice2 data]...[4byte slice4 size][slice4 data]
Remember to not include the start code length in slice size.
After changing that, my frame was completely displayed.
By the way:
The information where to display the different picture data blocks is specified in the header data of each NALU (parameter 'first_mb_in_slice').
There is a very good c# example here how to extract the NALU header data. You can almost copy it 1:1.

How to convert hexadecimal data (stored in a string variable) to an integer value

Edit (abstract)
I tried to interpret Char/String data as Byte, 4 bytes at a time. This was because I could only get TComport/TDatapacket to interpret streamed data as String, not as any other data type. I still don't know how to get the Read method and OnRxBuf event handler to work with TComport.
Problem Summary
I'm trying to get data from a mass spectrometer (MS) using some Delphi code. The instrument is connected with a serial cable and follows the RS232 protocol. I am able to send commands and process the text-based outputs from the MS without problems, but I am having trouble with interpreting the data buffer.
Background
From the user manual of this instrument:
"With the exception of the ion current values, the output of the RGA are ASCII character strings terminated by a linefeed + carriage return terminator. Ion signals are represented as integers in units of 10^-16 Amps, and transmitted directly in hex format (four byte integers, 2's complement format, Least Significant Byte first) for maximum data throughput."
I'm not sure whether (1) hex data can be stored properly in a string variable. I'm also not sure how to (2) implement 2's complement in Delphi and (3) the Least Significant Byte first.
Following #David Heffernan 's advice, I went and revised my data types. Attempting to harvest binary data from characters doesn't work, because not all values from 0-255 can be properly represented. You lose data along the way, basically. Especially it your data is represented 4 bytes at a time.
The solution for me was to use the Async Professional component instead of Denjan's Comport lib. It handles datastreams better and has a built-in log that I could use to figure out how to interpret streamed resposes from the instrument. It's also better documented. So, if you're new to serial communications (like I am), rather give that a go.

Verilog code to calculate number of rows and columns from an input image frame

I am having troubles with a verilog module which is a small part of a very big CMOS camera image code.The module takes in clk and reset as inputs and spits out hsync,vsync,pixclk and pixel data.The code reads in an image and saves it to memory and then does a a bunch of if else statements like :
if (row_count<NUM_ROWS-1) && (col_count< NUM_COLS)
begin
vsync <=1;
hsync <=1 ;
pixe_data <= mem[row_count*NUM_ROWS+col_count];
end
else if
......
Till now the image dimensions were hard coded using NUM_COLS and NUM_ROWS but I am trying to change this such that the code counts the rows and columns of the incoming image on the fly. I have tried using $fscanf,$fgets,$Sscanf etc but I am not getting the right results.In fact I am getting no results at all.My simulation gets stuck or it says its out of memory or fd is a null file descriptor.Also when I convert NUM_ROWS and NUM_COLS to be variables I get an error saying illegal operand for constant operation.
I would much appreciate if some could give me some insight into a different method to approach this problem.
My apologies in advance if the information here is insufficient or unclear.
Thanks
SK
The illegal operand for constraint operations is likely due to the dimension for mem. The dimensions needs to be a constant, e.g. reg [DATA_SIZE-1:0] mem [ROW_MAX*COL_MAX-1:0]; You'll need to decide the max image size you will process. If the max dimensions are not 2**N then you will need to implement some from of protection, e.g. signal an error and not process anything, truncate the image, or something else.
I'm not sure how to find the rows and columns of unknown image dimensions without writing custom a PLI. $fscanf can read in the image data and you will most likely want to use "%u" for format component. If image contains information about its dimentions in the file itself, then you could extract information with the $fscanf or $fread.
Other note, from your original code snip-it:
pixe_data <= mem[row_count*NUM_ROWS+col_count];
should be:
pixe_data <= mem[row_count*NUM_COLS+col_count];
Otherwise there is a risk of accessing the same data from different addresses or something out of range.

Reading TIFF files

I need to read and interpret a binary file containing a TIFF image. I know there exist readers for doing this but I want to go the hard way. I found the TIFF format description and need to parse the binary file in small chunks. Assume I was able to read in memory the complete binary file. This means that I have a variable containing one long list of bytes.
I know via the format definition what the meaning is of the different groups of n bytes.
How can one define character variables with different lengths (sometimes 2, sometimes 3, sometimes 4 etc.) so that the variable address points to the right position in the image variable array?
With other words, assume my image is loaded into an array Image containing all bytes of the file.
The first 2 bytes I want to load in a string with length 2 bytes so that I can just link the address pointer to the first position in the Image array and automatically the first 2 bytes are associated with the first character string. A second string of 4 bytes would have another meaning and so I make the address for the second string of 4 bytes point to the 3rd position of the Image array.
Is this feasible in C++? I remember that this was a normal way of working for dynamical memory allocation in Fortran 77 in a simulation code I analysed a long time ago.
Thanks in advance for the hints!
Regards,
Stefan
The C++ language is easily capable of processing TIFF files from a byte array. The idea you have in mind is basically correct, but there a few problems with it. C strings are zero-terminated and the strings which appear in TIFF files are not necessarily zero terminated since their length is specified explicitly. It really is simpler to create a dedicated data structure to hold the TIFF-specific data fields and then parse the binary data into the structure. Your method will immediately run into trouble with the Motorola/Intel byte issue if your machine has the opposite endian-ness.

Resources