Extract image type from NSData or encoded image - ios

Background
I have a function where a user can upload and send over an image from my ios to my rails app and it works for .jpg files. I would like to make it work for all image types. All I need to do is send over the image type in the API POST.
So far the user uploads the image and its an NSData, then I encoded into a image.base64EncodedStringWithOptions and put it into a JSON and send it over. This works for .jpg's.
Question
How do I get the image's type from the NSData or the encoded string of an image?
Examples
Here is the NSData of a very small .png that the user might try to upload.
<89504e47 0d0a1a0a 0000000d 49484452 0000000a 0000000a 08060000 008d32cf bd000000 01735247 4200aece 1ce90000 00097048 59730000 16250000 16250149 5224f000 00001c69 444f5400 00000200 00000000 00000500 00002800 00000500 00000500 00005ec1 07ed5500 00002a49 44415428 1562f88f 04181818 fea36398 34038c01 a2d11581 f8308060 11ab109b 691826e2 5284ac10 000000ff ff232a1e 6b000000 27494441 5463f80f 040c0c0c 3831481e 0418c004 0e856015 5002a742 644560c3 c0041613 c9560800 782fe719 4293f838 00000000 49454e44 ae426082>
Here is output of
strBase64:String = image.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
print(strBase64)
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAA\r\nAAlwSFlzAAAWJQAAFiUBSVIk8AAAABxpRE9UAAAAAgAAAAAAAAAFAAAAKAAAAAUA\r\nAAAFAAAAXsEH7VUAAAAqSURBVCgVYviPBBgYGP6jY5g0A4wBotEVgfgwgGARqxCb\r\naRgm4lKErBAAAAD//yMqHmsAAAAnSURBVGP4DwQMDAw4MUgeBBjABA6FYBVQAqdC\r\nZEVgw8AEFhPJVggAeC/nGUKT+DgAAAAASUVORK5CYII=

You should check your Base 64 encoded string for magic numbers in files.
https://en.m.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files
For example for PNG:
PNG image files begin with an 8-byte signature which identifies the file as a PNG file and allows detection of common file transfer problems: \211 P N G \r \n \032 \n (89 50 4E 47 0D 0A 1A 0A).
For JPEG:
JPEG image files begin with FF D8 and end with FF D9. JPEG/JFIF files contain the ASCII code for "JFIF" (4A 46 49 46) as a null terminated string. JPEG/Exif files contain the ASCII code for "Exif" (45 78 69 66) also as a null terminated string, followed by more metadata about the file.
So parse your string, detect matching of any magic number, map magic number to image file type.

Related

Printing NV logo with Star SP700 (ESC-POS)

I'm Trying to print The logo stored in my printer.
\x1B\x1C\x70\x00\x1
this is the code i'm executing.
But I still cant see the logo when I print.
What am I missing?
im using c++ btw
Printer SP700 Star printer
According to the specification, the 4th byte is a value in the range 0x01 to 0xFF instead of 0x00.
Dot Impact Printer STAR Command Specifications Rev. 1.91
Page 56, section 3-48
ASCII ESC FS p n m
Hexadecimal 1B 1C 70 n m
n: Logo Specification
n Function
1 to 255 Specified logo number
this work for me : \x1B\x1C\x70\x01\x00

How to hardcode a MP4 stream file with iOS VideoToolbox and FFMPEG?

Guys!
I have found a demo in github that is :-VideoToolboxDemo. And I also found a question in stackoverflow how-to-use-videotoolbox-to-decompress-h-264-video-stream which someone has implemented in github:https:/ /github.com/lileilei1119/VTDemo
But there is a different between they in finding SPS and PPS.
The VideoToolboxDemo is:
uint8_t *data = pCodecCtx -> extradata;
int size = pCodecCtx -> extradata_size;
it uses extradata of pCodecCtx from FFMPEG to find start code like 0x00 00 01(or 0x00 00 00 01)
but the introduction in stackoverflow is:
[_h264Decoder decodeFrame:packet.data withSize:packet.size];
use data of packet?
I have try these two ways, but I still can't find start code of SPS and PPS. Does anyone know why? Is there something wrong in my file?
My mp4 file is http:/ /7u2m53.com1.z0.glb.clouddn.com/201601131107187320.mp4
Videotoolbox does not use annex b, hence does not produce a start code. Read more here. Possible Locations for Sequence/Picture Parameter Set(s) for H.264 Stream

Incorrect values from reading image EXIF Orientation on iOS?

I am using Exif information to have a correct rotation for an image captured from mobile camera.
In Android version the possible values are 1,3,6,8, and 9.
In iOS, I am using the same code, but getting invalid values like 393216, 196608, 524288, 65536 etc..
I don't understand why there is such a difference ?
Short answer:
For iOS you need to read those bytes in reverse order for correct value. Plus you are incorrectly reading 24-bits (3 bytes) instead of just 16-bits (2 bytes). Or maybe you are extracting 2 bytes but somehow your bytes are getting an extra "zero" byte added at the end??
You could try having an OR check inside an If statement thats checks both Endian type equivalents. Since where Android = 3 would become iOS = 768, you can try:
if (orient_val == 3 || orient_val == 768)
{ /* do whatever you do here */ }
PS: 1==256 2==512 3==768 4==1024 5==1280 6==1536 7==1792 8==2048, 9==2304
long version:
Android processors typically read bytes as Little Endian. Apple processors read bytes as Big Endian. Basically one type is read right-to-left, the other, is left-to-right. Where Android has ABCD that becomes in iOS as DCBA.
Some pointers:
Your 3 as (2 bytes) in Lil' E is written 00+03... but in
Big E it's written 03+00.
Problem is, if you dont adapt and just read that 03 00 as though it's still LE then you get 768.
Worst still, somehow you are reading it as 03 00 00 which gives you
that 196608.
Another is 06 00 00 giving you 393216 instead of reading 60 00 for 1536.
Fix your code to drop the extra 00 byte at the end.
You were lucky on Android cos I suspect it wants 4 bytes instead of 2 bytes. So that 00 00 06 was being read as 00 00 00 06 and since x000006 and x00000006 mean the same thing=6.
Anyways to fix this normally you could just tell AS3 to consider your Jpeg bytes as Big Endian but that would now fix iOS but then break it on Android.
A quick easy solution is to check if the number you got is bigger than 1 digit, if it is then you assume app is running on iOS and try reverse-ordering to see if now the result is 1 digit. So..
Note: option B shown in code is risky because if you have wrong numbers anyway you'll get a wrong result. You know computers.. "bad input = bad output; do Next();"
import flash.utils.ByteArray;
var Orientation_num:uint = 0;
var jpeg_bytes:ByteArray = new ByteArray(); //holds entire JPEG data as bytes
var bytes_val:ByteArray = new ByteArray(); //holds byte values as needed
Orientation_num = 2048; //Example: Detected big number that should be 8.
if (Orientation_num > 8 ) //since 8 is maximum of orientation types
{
trace ("Orientation_num is too big : Attempting fix..");
//## A: CORRECT.. Either read directly from JPEG bytes
//jpeg_bytes.position = (XX) - 1; //where XX is start of EXIF orientation (2 bytes)
//bytes_val = jpeg_bytes.readShort(); //extracts the 2 bytes
//## B: RISKY.. Or use the already detected big number anyway
bytes_val.writeShort(Orientation_num);
//Flip the bytes : Make x50 x00 become x00 x50
var tempNum_ba : ByteArray = new ByteArray(); //temporary number as bytes
tempNum_ba[0] = bytes_val[1];
tempNum_ba[1] = bytes_val[0];
//tempNum_ba.position = 0; //reset pos before checking
Orientation_num = tempNum_ba.readShort(); //pos also MOVES forward by 2 bytes
trace ("Orientation_num (FIXED) : " + Orientation_num);
}

How can i get the length of an IDR slice in H264 stream

Please guide me to resolve this issue.
I have parsed the h264 video stream and identified the frames[I/P/B]. I have followed the below steps.
• NAL Units start code: 00 00 01 X Y
• X = IDR Picture NAL Units (25, 45, 65)
• Y = Non IDR Picture NAL Units (01, 21, 41, 61) ; 01 = b-frames, 41 = p-frames
Now my question is how to know the length of individual frames so that i can write each frames to a file. Please give some help.
Regards,
Spk
Ok, so your source is an annex-b formated elementary stream. Basically every NALu begins with a start code (2 or more 0x00 bytes followed by a 0x01 byte). The next byte contains the type (the first 5 bits). The rest is payload. The NALU ends when the next start code in encountered, or you reach the end of the stream. So, to get the length, you must look for the next start code and subtract.
You will likely find this post useful. Possible Locations for Sequence/Picture Parameter Set(s) for H.264 Stream

Lua: writing hexadecimal values as a binary file

I have several hex-values that I try to write to a file. It seems that Lua doesn't support that out of the box, since they are all treated as strings instead of values. I figured I would have to break up a longer hex-value, for example AABBCC into AA, BB, CC and use string.char() on all of their decimal values consecutively to get the job done.
Is there a built in function that allows me to write such values directly without converting them first? I used escape characters such as "0xAA" and "\xAA", but those didn't work out.
Edit: Let me give you an example. I'm looking at a test file in a hex editor:
00000000 00 00 00 00 00 00 ......
And I want to write to it in the following fashion with the string "AABBCC":
00000000 AA BB CC 00 00 00 ......
What I get though with the escape characters is:
00000000 41 41 42 42 43 43 AABBCC
I use the following functions to convert between a hex string and a "raw binary":
function string.fromhex(str)
return (str:gsub('..', function (cc)
return string.char(tonumber(cc, 16))
end))
end
function string.tohex(str)
return (str:gsub('.', function (c)
return string.format('%02X', string.byte(c))
end))
end
They can be used as follows:
("Hello world!"):tohex() --> 48656C6C6F20776F726C6421
("48656C6C6F20776F726C6421"):fromhex() --> Hello world!
So you have a string like this:
value = 'AABBCC'
And you want to print it (or turn it into a string) like this?
'101010101011101111001100'
How about this?
function hex2bin(str)
local map = {
['0'] = '0000'
['1'] = '0001'
['2'] = '0010'
-- etc. up to 'F'
}
return str:gsub('[0-9A-F]', map)
end
Note that it leaves untouched any characters which could not be interpreted as hex.
There is so such function because it's that easy to write one.
function writeHex(str,fh)
for byte in str:gmatch'%x%x' do
fh:write(string.char(tonumber(byte,16)))
end
end
This just plainly writes the values to the file pointed to by the fh filehandle.

Resources