I am trying to calculate CRC-6 GSM but the result is wrong ($16).
For '123456789' it should return $13 according to
https://reveng.sourceforge.io/crc-catalogue/all.htm#crc.cat.crc-6-gsm
var Table: array[0..255] of Byte = (
$3F, $10, $0E, $21, $32, $1D, $03, $2C,
$25, $0A, $14, $3B, $28, $07, $19, $36,
$0B, $24, $3A, $15, $06, $29, $37, $18,
$11, $3E, $20, $0F, $1C, $33, $2D, $02,
$38, $17, $09, $26, $35, $1A, $04, $2B,
$22, $0D, $13, $3C, $2F, $00, $1E, $31,
$0C, $23, $3D, $12, $01, $2E, $30, $1F,
$16, $39, $27, $08, $1B, $34, $2A, $05,
$31, $1E, $00, $2F, $3C, $13, $0D, $22,
$2B, $04, $1A, $35, $26, $09, $17, $38,
$05, $2A, $34, $1B, $08, $27, $39, $16,
$1F, $30, $2E, $01, $12, $3D, $23, $0C,
$36, $19, $07, $28, $3B, $14, $0A, $25,
$2C, $03, $1D, $32, $21, $0E, $10, $3F,
$02, $2D, $33, $1C, $0F, $20, $3E, $11,
$18, $37, $29, $06, $15, $3A, $24, $0B,
$23, $0C, $12, $3D, $2E, $01, $1F, $30,
$39, $16, $08, $27, $34, $1B, $05, $2A,
$17, $38, $26, $09, $1A, $35, $2B, $04,
$0D, $22, $3C, $13, $00, $2F, $31, $1E,
$24, $0B, $15, $3A, $29, $06, $18, $37,
$3E, $11, $0F, $20, $33, $1C, $02, $2D,
$10, $3F, $21, $0E, $1D, $32, $2C, $03,
$0A, $25, $3B, $14, $07, $28, $36, $19,
$2D, $02, $1C, $33, $20, $0F, $11, $3E,
$37, $18, $06, $29, $3A, $15, $0B, $24,
$19, $36, $28, $07, $14, $3B, $25, $0A,
$03, $2C, $32, $1D, $0E, $21, $3F, $10,
$2A, $05, $1B, $34, $27, $08, $16, $39,
$30, $1F, $01, $2E, $3D, $12, $0C, $23,
$1E, $31, $2F, $00, $13, $3C, $22, $0D,
$04, $2B, $35, $1A, $09, $26, $38, $17
);
function GSM_Update(Msg: PByte; Length: Integer): Byte;
var i: Integer;
H: Byte;
begin
H := $00;
for i:=0 to Length-1 do begin
H := Table[H xor Msg^]; //I believe this line might be wrong but don't know how to change it
Inc(Msg);
end;
Result := H xor $3F;
end;
Invoking is quite simple:
var Msg: AnsiString;
...
GSM_Update(#Msg[1], Length(Msg));
or
var Msg: array of AnsiChar;
Len: Integer;
...
SetLength(Msg, Len);
GSM_Update(#Msg[0], Len);
I'm not certain about the Pascal operators and syntax, but for the table in your code, that line needs to be:
H := (not Table[(H shl 2) xor Msg^]) and $3F;
This could be simplified and sped up by using a more appropriate table. I would replace each byte in the table by its one's complement shifted left by two bits. I.e. $00, $bc, $c4, $78, ... Then that line would be what you currently have:
H := Table[H xor Msg^];
and the last line would need to be changed to:
Result := (H shr 2) xor $3F;
Related
I want to create a table for CRC-6/CDMA2000-A. I tried for various CRC-8 and this algo below works fine but for CRC-6 I get arrays which don't work for me.
Either the array is wrong or the function I use to calculate CRC-6 with the array.
const POLYNOMIAL = $27;
BitsCRC = 6;
var Table: array[0..255] of Byte;
i: Integer;
j: Integer;
temp: Byte;
S: String;
Mask: Byte;
begin
mask := (1 shl (BitsCRC - 1));
for i:=0 to 255 do Table[i] := i ;
for i:=0 to 255 do begin
for j:=7 downto 0 do begin
temp := Table[i] and Mask;
if (temp <> 0) then begin
Table[i] := Table[i] shl 1;
Table[i] := Table[i] xor POLYNOMIAL;
end
else begin
Table[i] := Table[i] shl 1;
end;
end;
end;
S := '';
for i:=0 to 255 do begin
S := S + '$' + IntToHex(Table[i], 2) +', ';
if i mod 16 = 15 then begin
Memo1.Lines.Add(s);
S := '';
end;
end;
I get this array from the code above:
$00, $F5, $CD, $38, $9A, $6F, $57, $A2, $34, $C1, $F9, $0C, $AE, $5B, $63, $96,
$4F, $BA, $82, $77, $D5, $20, $18, $ED, $7B, $8E, $B6, $43, $E1, $14, $2C, $D9,
$9E, $6B, $53, $A6, $04, $F1, $C9, $3C, $AA, $5F, $67, $92, $30, $C5, $FD, $08,
$D1, $24, $1C, $E9, $4B, $BE, $86, $73, $E5, $10, $28, $DD, $7F, $8A, $B2, $47,
$00, $F5, $CD, $38, $9A, $6F, $57, $A2, $34, $C1, $F9, $0C, $AE, $5B, $63, $96,
$4F, $BA, $82, $77, $D5, $20, $18, $ED, $7B, $8E, $B6, $43, $E1, $14, $2C, $D9,
$9E, $6B, $53, $A6, $04, $F1, $C9, $3C, $AA, $5F, $67, $92, $30, $C5, $FD, $08,
$D1, $24, $1C, $E9, $4B, $BE, $86, $73, $E5, $10, $28, $DD, $7F, $8A, $B2, $47,
$00, $F5, $CD, $38, $9A, $6F, $57, $A2, $34, $C1, $F9, $0C, $AE, $5B, $63, $96,
$4F, $BA, $82, $77, $D5, $20, $18, $ED, $7B, $8E, $B6, $43, $E1, $14, $2C, $D9,
$9E, $6B, $53, $A6, $04, $F1, $C9, $3C, $AA, $5F, $67, $92, $30, $C5, $FD, $08,
$D1, $24, $1C, $E9, $4B, $BE, $86, $73, $E5, $10, $28, $DD, $7F, $8A, $B2, $47,
$00, $F5, $CD, $38, $9A, $6F, $57, $A2, $34, $C1, $F9, $0C, $AE, $5B, $63, $96,
$4F, $BA, $82, $77, $D5, $20, $18, $ED, $7B, $8E, $B6, $43, $E1, $14, $2C, $D9,
$9E, $6B, $53, $A6, $04, $F1, $C9, $3C, $AA, $5F, $67, $92, $30, $C5, $FD, $08,
$D1, $24, $1C, $E9, $4B, $BE, $86, $73, $E5, $10, $28, $DD, $7F, $8A, $B2, $47
I try to generate CRC-6 like this:
procedure crc6_update(var CRC: Byte; Str: String);
var i: Integer;
begin
for i:=1 to Length(Str) do
CRC := CRC_Table[(CRC shl 2) xor ord(Str[i]) ] ;
end;
CRC := $3f;
crc6_update(CRC, '123456789');
Caption := IntToHex(CRC, 2);
There are a few problems. You are shifting junk up into the top two bits of the table entries, but then not getting rid of them with an and. More importantly, you are ignoring the top two bits, bits 6 and 7, of each initial table entry (i) with your mask, which is looking at bit 5.
To do this correctly, you need to compute the CRC in the top six bits of the byte (i) being processed. You mask bit 7 instead of bit 5, and you shift the polynomial up two bits to match that. If you are doing this in a byte, then that will take care of the junk being shifted up, since it falls off of the top of the byte.
You want:
Mask := 1 shl 7;
and:
Table[i] := Table[i] xor (POLYNOMIAL shl 2);
Now the CRCs in your table are actually where you'd want them to be anyway, which is in the top six bits of each byte. Then you don't need to do the CRC shl 2 for every single byte you compute. Instead that line in your calculation becomes:
CRC := CRC_Table[CRC xor ord(Str[i])];
Then after your loop you need to shift the CRC down two to return the CRC in the low six bits:
CRC := CRC shr 2;
and the initial value needs to be shifted up two:
CRC := $fc;
This will give the correct answer for that test vector, which is $0D.
I am not clear on why you have three loops with an array for your table generation. It seems like it would be simpler to do it like this, with one loop and no array (not tested -- I don't know Pascal/Delphi):
var
i: Integer;
j: Integer;
crc: Byte;
S: String;
begin
S := '';
for i := 0 to 255 do begin
crc := i;
for j := 0 to 7 do
if ((crc and $80) <> 0) then
crc := (crc shl 1) xor $9c
else
crc := crc shl 1;
S := S + '$' + IntToHex(crc, 2) + ', ';
if i mod 16 = 15 then begin
Memo1.Lines.Add(S);
S := '';
end;
end;
end.
After reading this excellent article about custom accessors in Swift, I refactored from NSDecimalNumber to use the new Decimal type. I have a fairly complex model and things have been working fine for several days, but I now see an EXC_BAD_ACCESS crash if I save the managed object context while a required (non-optional) property is nil, baseAmount in my case. When using NSDecimalNumber directly, before the refactor, saving the object would fail, but it wouldn't crash.
Not sure if this is important, but I'm saving the context using Magical Record's function: NSManagedObjectContext.mr_default().mr_saveToPersistentStoreAndWait()
Any ideas on how I can modify the baseAmount accessors to achieve the same failed-save behavior that Core Data provides so that it doesn't crash?
Here is the relevant part of my NSManagedObject subclass, followed by the stack trace:
extension DFTransaction {
#NSManaged private var primitiveBaseAmount: NSDecimalNumber
var baseAmount: Decimal {
get {
willAccessValue(forKey: "baseAmount")
defer { didAccessValue(forKey: "baseAmount") }
return primitiveBaseAmount.decimalValue
}
set {
willChangeValue(forKey: "baseAmount")
defer { didChangeValue(forKey: "baseAmount") }
primitiveBaseAmount = NSDecimalNumber(decimal: newValue)
}
}
}
[appname]`#objc DFTransaction.baseAmount.getter:
0x100343cd0 <+0>: stp x29, x30, [sp, #-16]!
0x100343cd4 <+4>: mov x29, sp
0x100343cd8 <+8>: sub sp, sp, #96 ; =96
0x100343cdc <+12>: stur x0, [x29, #-32]
0x100343ce0 <+16>: stur x8, [x29, #-40]
0x100343ce4 <+20>: bl 0x10051ca64 ; symbol stub for: objc_retain
0x100343ce8 <+24>: sub x8, x29, #24 ; =24
0x100343cec <+28>: ldur x30, [x29, #-32]
0x100343cf0 <+32>: str x0, [sp, #48]
0x100343cf4 <+36>: mov x0, x30
0x100343cf8 <+40>: bl 0x100343da4 ; [appname].DFTransaction.baseAmount.getter : __C.Decimal at DFTransaction.swift:64
0x100343cfc <+44>: ldur w9, [x29, #-24]
0x100343d00 <+48>: ldurh w10, [x29, #-20]
0x100343d04 <+52>: ldurh w11, [x29, #-18]
0x100343d08 <+56>: ldurh w12, [x29, #-16]
0x100343d0c <+60>: ldurh w13, [x29, #-14]
0x100343d10 <+64>: ldurh w14, [x29, #-12]
0x100343d14 <+68>: ldurh w15, [x29, #-10]
0x100343d18 <+72>: ldurh w16, [x29, #-8]
0x100343d1c <+76>: ldurh w17, [x29, #-6]
0x100343d20 <+80>: ldur x0, [x29, #-32]
0x100343d24 <+84>: str w9, [sp, #44]
0x100343d28 <+88>: str w10, [sp, #40]
0x100343d2c <+92>: str w11, [sp, #36]
0x100343d30 <+96>: str w12, [sp, #32]
0x100343d34 <+100>: str w13, [sp, #28]
0x100343d38 <+104>: str w14, [sp, #24]
0x100343d3c <+108>: str w15, [sp, #20]
0x100343d40 <+112>: str w16, [sp, #16]
0x100343d44 <+116>: str w17, [sp, #12]
0x100343d48 <+120>: bl 0x10051ca58 ; symbol stub for: objc_release
0x100343d4c <+124>: ldr w9, [sp, #44]
0x100343d50 <+128>: ldur x8, [x29, #-40]
-> 0x100343d54 <+132>: str w9, [x8] //EXC_BAD_ACCESS
0x100343d58 <+136>: ldr w10, [sp, #40]
0x100343d5c <+140>: strh w10, [x8, #4]
0x100343d60 <+144>: ldr w11, [sp, #36]
0x100343d64 <+148>: strh w11, [x8, #6]
0x100343d68 <+152>: ldr w12, [sp, #32]
0x100343d6c <+156>: strh w12, [x8, #8]
0x100343d70 <+160>: ldr w13, [sp, #28]
0x100343d74 <+164>: strh w13, [x8, #10]
0x100343d78 <+168>: ldr w14, [sp, #24]
0x100343d7c <+172>: strh w14, [x8, #12]
0x100343d80 <+176>: ldr w15, [sp, #20]
0x100343d84 <+180>: strh w15, [x8, #14]
0x100343d88 <+184>: ldr w16, [sp, #16]
0x100343d8c <+188>: strh w16, [x8, #16]
0x100343d90 <+192>: ldr w17, [sp, #12]
0x100343d94 <+196>: strh w17, [x8, #18]
0x100343d98 <+200>: mov sp, x29
0x100343d9c <+204>: ldp x29, x30, [sp], #16
0x100343da0 <+208>: ret
In the article I mention that "Primitive accessors are always nullable Objective-C reference types". This is a truth that's not affected by the isOptional setting, as you've been finding with those crashes.
As such, the primitive accessor must be declared like so:
#NSManaged private var primitiveBaseAmount: NSDecimalNumber?
With that out of the way, you've declared the baseAmount accessor to be Decimal (non-optional), so your custom get implementation must do something non-crashy when it encounters a null primitive value, like return primitiveBaseAmount?.decimalValue ?? 0.
So when I launch my app, I'll sometimes get an EXC_BREAKPOINT or EXC_BAD_ACCESS that points to a line within a function that's not being called. After writing some new, unrelated code, I can get these crashes without fail. And when I undo that code, I can sometimes rid of the error.But that code isn't at all related, and I'm not sure why I'm getting these errors in functions that aren't even being called.
I have a UIWindow with a custom VideoPlayer class that I'm returning upon launch. And the failing function is in that class, although it never gets called. Here's how I'm doing it:
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
let player = VideoPlayer(frame:UIScreen.mainScreen().bounds)
var window: UIWindow? {
set {
}
get {
return player
}
}
}
Stack trace:
libswiftCore.dylib`function signature specialization <Arg[0] = Exploded, Arg[1] = Exploded, Arg[2] = Dead, Arg[3] = Dead> of Swift._fatalErrorMessage (Swift.StaticString, Swift.StaticString, Swift.StaticString, Swift.UInt) -> ():
0x1007cc740 <+0>: stp x29, x30, [sp, #-16]!
0x1007cc744 <+4>: mov x29, sp
0x1007cc748 <+8>: sub sp, sp, #16
0x1007cc74c <+12>: and w8, w2, #0x1
0x1007cc750 <+16>: tbnz w8, #0, 0x1007cc770 ; <+48>
0x1007cc754 <+20>: tbnz x1, #63, 0x1007cc7b4 ; <+116>
0x1007cc758 <+24>: add x1, x0, x1
0x1007cc75c <+28>: mov x2, x3
0x1007cc760 <+32>: mov x3, x4
0x1007cc764 <+36>: mov x4, x5
0x1007cc768 <+40>: bl 0x10080edd0 ; function signature specialization <Arg[0] = Exploded, Arg[1] = Exploded> of Swift.(_fatalErrorMessage (Swift.StaticString, Swift.StaticString, Swift.StaticString, Swift.UInt) -> ()).(closure #2)
-> 0x1007cc76c <+44>: brk #0x1
0x1007cc770 <+48>: str xzr, [sp, #8]
0x1007cc774 <+52>: cmp x0, w0, uxtw
0x1007cc778 <+56>: b.ne 0x1007cc94c ; <+524>
0x1007cc77c <+60>: lsr w8, w0, #11
0x1007cc780 <+64>: cmp w8, #26
0x1007cc784 <+68>: b.hi 0x1007cc7d8 ; <+152>
0x1007cc788 <+72>: cmp w0, #128
0x1007cc78c <+76>: b.lo 0x1007cc808 ; <+200>
0x1007cc790 <+80>: orr w8, wzr, #0x80
0x1007cc794 <+84>: bfxil x8, x0, #0, #6
0x1007cc798 <+88>: cmp w0, #2048
0x1007cc79c <+92>: b.hs 0x1007cc83c ; <+252>
0x1007cc7a0 <+96>: movz x10, #0
0x1007cc7a4 <+100>: movz x11, #0
0x1007cc7a8 <+104>: lsr w9, w0, #6
0x1007cc7ac <+108>: orr w9, w9, #0xffffffc0
0x1007cc7b0 <+112>: b 0x1007cc86c ; <+300>
0x1007cc7b4 <+116>: adr x0, #808224 ; "fatal error"
0x1007cc7b8 <+120>: nop
0x1007cc7bc <+124>: adr x3, #808724 ; "UnsafeBufferPointer with negative count"
0x1007cc7c0 <+128>: nop
0x1007cc7c4 <+132>: movz w1, #0xb
0x1007cc7c8 <+136>: orr w2, wzr, #0x2
0x1007cc7cc <+140>: movz w4, #0x27
0x1007cc7d0 <+144>: orr w5, wzr, #0x2
0x1007cc7d4 <+148>: bl 0x1007cc740 ; <+0>
0x1007cc7d8 <+152>: cmp w0, #14, lsl #12
0x1007cc7dc <+156>: b.lo 0x1007cc818 ; <+216>
0x1007cc7e0 <+160>: cmp w0, #272, lsl #12
0x1007cc7e4 <+164>: b.hs 0x1007cc900 ; <+448>
0x1007cc7e8 <+168>: orr w8, wzr, #0x80
0x1007cc7ec <+172>: bfxil x8, x0, #0, #6
0x1007cc7f0 <+176>: orr w9, wzr, #0xffffff80
0x1007cc7f4 <+180>: bfxil w9, w0, #6, #6
0x1007cc7f8 <+184>: lsr w10, w0, #16
0x1007cc7fc <+188>: cbnz w10, 0x1007cc924 ; <+484>
0x1007cc800 <+192>: lsr w10, w0, #12
0x1007cc804 <+196>: b 0x1007cc848 ; <+264>
0x1007cc808 <+200>: movz x9, #0
0x1007cc80c <+204>: movz x11, #0
0x1007cc810 <+208>: mov x8, x0
0x1007cc814 <+212>: b 0x1007cc89c ; <+348>
0x1007cc818 <+216>: adr x0, #808124 ; "fatal error"
0x1007cc81c <+220>: nop
0x1007cc820 <+224>: adr x3, #811328 ; "high- and low-surrogate code points are not valid Unicode scalar values"
0x1007cc824 <+228>: nop
0x1007cc828 <+232>: movz w1, #0xb
0x1007cc82c <+236>: orr w2, wzr, #0x2
0x1007cc830 <+240>: movz w4, #0x47
0x1007cc834 <+244>: orr w5, wzr, #0x2
0x1007cc838 <+248>: bl 0x1007cc740 ; <+0>
0x1007cc83c <+252>: lsr w10, w0, #12
0x1007cc840 <+256>: orr w9, wzr, #0xffffff80
0x1007cc844 <+260>: bfxil w9, w0, #6, #6
0x1007cc848 <+264>: movz x12, #0
0x1007cc84c <+268>: movz x11, #0
0x1007cc850 <+272>: orr w10, w10, #0xffffffe0
0x1007cc854 <+276>: and x10, x10, #0xff
0x1007cc858 <+280>: lsl x13, x12, #3
0x1007cc85c <+284>: lsl x10, x10, x13
0x1007cc860 <+288>: orr x11, x10, x11
0x1007cc864 <+292>: str x11, [sp, #8]
0x1007cc868 <+296>: add x10, x12, #1
0x1007cc86c <+300>: orr w12, wzr, #0x8
0x1007cc870 <+304>: umulh x12, x10, x12
0x1007cc874 <+308>: cmp xzr, x12
0x1007cc878 <+312>: b.ne 0x1007cc94c ; <+524>
0x1007cc87c <+316>: lsl x12, x10, #3
0x1007cc880 <+320>: cmp x12, #63
0x1007cc884 <+324>: b.hi 0x1007cc8dc ; <+412>
0x1007cc888 <+328>: and x9, x9, #0xff
0x1007cc88c <+332>: lsl x9, x9, x12
0x1007cc890 <+336>: orr x11, x9, x11
0x1007cc894 <+340>: str x11, [sp, #8]
0x1007cc898 <+344>: add x9, x10, #1
0x1007cc89c <+348>: orr w10, wzr, #0x8
0x1007cc8a0 <+352>: umulh x10, x9, x10
0x1007cc8a4 <+356>: cmp xzr, x10
0x1007cc8a8 <+360>: b.ne 0x1007cc94c ; <+524>
0x1007cc8ac <+364>: lsl x10, x9, #3
0x1007cc8b0 <+368>: cmp x10, #64
0x1007cc8b4 <+372>: b.hs 0x1007cc8dc ; <+412>
0x1007cc8b8 <+376>: and x8, x8, #0xff
0x1007cc8bc <+380>: lsl x8, x8, x10
0x1007cc8c0 <+384>: orr x8, x8, x11
0x1007cc8c4 <+388>: str x8, [sp, #8]
0x1007cc8c8 <+392>: add x8, sp, #8
0x1007cc8cc <+396>: add x8, x9, x8
0x1007cc8d0 <+400>: add x1, x8, #1
0x1007cc8d4 <+404>: add x0, sp, #8
0x1007cc8d8 <+408>: b 0x1007cc75c ; <+28>
0x1007cc8dc <+412>: adr x0, #807928 ; "fatal error"
0x1007cc8e0 <+416>: nop
0x1007cc8e4 <+420>: adr x3, #808332 ; "shift amount is larger than type size in bits"
0x1007cc8e8 <+424>: nop
0x1007cc8ec <+428>: movz w1, #0xb
0x1007cc8f0 <+432>: orr w2, wzr, #0x2
0x1007cc8f4 <+436>: movz w4, #0x2d
0x1007cc8f8 <+440>: orr w5, wzr, #0x2
0x1007cc8fc <+444>: bl 0x1007cc740 ; <+0>
0x1007cc900 <+448>: adr x0, #807892 ; "fatal error"
0x1007cc904 <+452>: nop
0x1007cc908 <+456>: adr x3, #811176 ; "value is outside of Unicode codespace"
0x1007cc90c <+460>: nop
0x1007cc910 <+464>: movz w1, #0xb
0x1007cc914 <+468>: orr w2, wzr, #0x2
0x1007cc918 <+472>: movz w4, #0x25
0x1007cc91c <+476>: orr w5, wzr, #0x2
0x1007cc920 <+480>: bl 0x1007cc740 ; <+0>
0x1007cc924 <+484>: lsr w10, w0, #18
0x1007cc928 <+488>: orr w11, w10, #0xf0
0x1007cc92c <+492>: cmp w11, w11, uxtb
0x1007cc930 <+496>: b.ne 0x1007cc94c ; <+524>
0x1007cc934 <+500>: orr w10, wzr, #0xffffff80
0x1007cc938 <+504>: bfxil w10, w0, #12, #6
0x1007cc93c <+508>: and x11, x11, #0xff
0x1007cc940 <+512>: str x11, [sp, #8]
0x1007cc944 <+516>: orr w12, wzr, #0x1
0x1007cc948 <+520>: b 0x1007cc854 ; <+276>
0x1007cc94c <+524>: brk #0x1
Why is a line within a function that's not being called causing a crash?
So im trying to make an app for a school project in Swift. (im completely new to this language) The app should allow you to tilt your device, and by doing so making a square drop to the bottom of the screen. This is what ip using right now:
func gravityUpdated(){
if let data = motionManager.deviceMotion {
let gravity = data.gravity
Zwaartekracht.gravityDirection = CGVectorMake(CGFloat(gravity.x), CGFloat(gravity.y))
}
}
gravityUpdated()
When i run it on my iPhone 6, the build is successful, but then i get to see this: (sorry for long post):
libswiftCore.dylib`function signature specialization <Arg[0] = Exploded, Arg[1] = Exploded, Arg[2] = Dead, Arg[3] = Dead> of Swift._fatalErrorMessage (Swift.StaticString, Swift.StaticString, Swift.StaticString, Swift.UInt) -> ():
0x100171448 <+0>: stp x29, x30, [sp, #-16]!
0x10017144c <+4>: mov x29, sp
0x100171450 <+8>: sub sp, sp, #16
0x100171454 <+12>: and w8, w2, #0x1
0x100171458 <+16>: tbnz w8, #0, 0x100171478 ; <+48>
0x10017145c <+20>: tbnz x1, #63, 0x100171568 ; <+288>
0x100171460 <+24>: add x1, x0, x1
0x100171464 <+28>: mov x2, x3
0x100171468 <+32>: mov x3, x4
0x10017146c <+36>: mov x4, x5
0x100171470 <+40>: bl 0x1001a1334 ; function signature specialization <Arg[0] = Exploded, Arg[1] = Exploded> of Swift.(_fatalErrorMessage (Swift.StaticString, Swift.StaticString, Swift.StaticString, Swift.UInt) -> ()).(closure #2)
-> 0x100171474 <+44>: brk #0x1
0x100171478 <+48>: str xzr, [sp, #8]
0x10017147c <+52>: cmp x0, w0, uxtw
0x100171480 <+56>: b.ne 0x100171620 ; <+472>
0x100171484 <+60>: lsr w8, w0, #11
0x100171488 <+64>: cmp w8, #27
0x10017148c <+68>: b.ne 0x1001714b4 ; <+108>
0x100171490 <+72>: adr x0, #584602 ; "fatal error"
0x100171494 <+76>: nop
0x100171498 <+80>: adr x3, #586600 ; "high- and low-surrogate code points are not valid Unicode scalar values"
0x10017149c <+84>: nop
0x1001714a0 <+88>: movz w1, #0xb
0x1001714a4 <+92>: orr w2, wzr, #0x2
0x1001714a8 <+96>: movz w4, #0x47
0x1001714ac <+100>: orr w5, wzr, #0x2
0x1001714b0 <+104>: bl 0x100171448 ; <+0>
0x1001714b4 <+108>: lsr w10, w0, #16
0x1001714b8 <+112>: cmp w10, #16
0x1001714bc <+116>: b.hi 0x1001714ec ; <+164>
0x1001714c0 <+120>: cmp w0, #128
0x1001714c4 <+124>: b.lo 0x100171510 ; <+200>
0x1001714c8 <+128>: orr w8, wzr, #0x80
0x1001714cc <+132>: bfxil x8, x0, #0, #6
0x1001714d0 <+136>: cmp w0, #2047
0x1001714d4 <+140>: b.hi 0x10017158c ; <+324>
0x1001714d8 <+144>: movz x11, #0
0x1001714dc <+148>: movz x10, #0
0x1001714e0 <+152>: lsr w9, w0, #6
0x1001714e4 <+156>: orr w9, w9, #0xffffffc0
0x1001714e8 <+160>: b 0x1001715e8 ; <+416>
0x1001714ec <+164>: adr x0, #584510 ; "fatal error"
0x1001714f0 <+168>: nop
0x1001714f4 <+172>: adr x3, #586588 ; "value is outside of Unicode codespace"
0x1001714f8 <+176>: nop
0x1001714fc <+180>: movz w1, #0xb
0x100171500 <+184>: orr w2, wzr, #0x2
0x100171504 <+188>: movz w4, #0x25
0x100171508 <+192>: orr w5, wzr, #0x2
0x10017150c <+196>: bl 0x100171448 ; <+0>
0x100171510 <+200>: movz x10, #0
0x100171514 <+204>: movz x9, #0
0x100171518 <+208>: mov x8, x0
0x10017151c <+212>: orr w11, wzr, #0x8
0x100171520 <+216>: umulh x11, x9, x11
0x100171524 <+220>: cmp xzr, x11
0x100171528 <+224>: cset w11, ne
0x10017152c <+228>: tbnz w11, #0, 0x100171620 ; <+472>
0x100171530 <+232>: lsl x11, x9, #3
0x100171534 <+236>: cmp x11, #63
0x100171538 <+240>: b.hi 0x100171624 ; <+476>
0x10017153c <+244>: and x8, x8, #0xff
0x100171540 <+248>: lsl x8, x8, x11
0x100171544 <+252>: orr x8, x8, x10
0x100171548 <+256>: str x8, [sp, #8]
0x10017154c <+260>: cmn x9, #2
0x100171550 <+264>: b.le 0x100171568 ; <+288>
0x100171554 <+268>: add x8, sp, #8
0x100171558 <+272>: add x8, x9, x8
0x10017155c <+276>: add x1, x8, #1
0x100171560 <+280>: add x0, sp, #8
0x100171564 <+284>: b 0x100171464 ; <+28>
0x100171568 <+288>: adr x0, #584386 ; "fatal error"
0x10017156c <+292>: nop
0x100171570 <+296>: adr x3, #584656 ; "UnsafeBufferPointer with negative count"
0x100171574 <+300>: nop
0x100171578 <+304>: movz w1, #0xb
0x10017157c <+308>: orr w2, wzr, #0x2
0x100171580 <+312>: movz w4, #0x27
0x100171584 <+316>: orr w5, wzr, #0x2
0x100171588 <+320>: bl 0x100171448 ; <+0>
0x10017158c <+324>: orr w9, wzr, #0xffffff80
0x100171590 <+328>: bfxil w9, w0, #6, #6
0x100171594 <+332>: cbnz w10, 0x1001715ac ; <+356>
0x100171598 <+336>: movz x11, #0
0x10017159c <+340>: movz x12, #0
0x1001715a0 <+344>: lsr w10, w0, #12
0x1001715a4 <+348>: orr w10, w10, #0xffffffe0
0x1001715a8 <+352>: b 0x1001715d0 ; <+392>
0x1001715ac <+356>: lsr w10, w0, #18
0x1001715b0 <+360>: orr w11, w10, #0xf0
0x1001715b4 <+364>: cmp w11, w11, uxtb
0x1001715b8 <+368>: b.ne 0x100171620 ; <+472>
0x1001715bc <+372>: orr w10, wzr, #0xffffff80
0x1001715c0 <+376>: bfxil w10, w0, #12, #6
0x1001715c4 <+380>: and x12, x11, #0xff
0x1001715c8 <+384>: str x12, [sp, #8]
0x1001715cc <+388>: orr w11, wzr, #0x1
0x1001715d0 <+392>: and x10, x10, #0xff
0x1001715d4 <+396>: lsl x13, x11, #3
0x1001715d8 <+400>: lsl x10, x10, x13
0x1001715dc <+404>: orr x10, x10, x12
0x1001715e0 <+408>: str x10, [sp, #8]
0x1001715e4 <+412>: add x11, x11, #1
0x1001715e8 <+416>: orr w12, wzr, #0x8
0x1001715ec <+420>: umulh x12, x11, x12
0x1001715f0 <+424>: cmp xzr, x12
0x1001715f4 <+428>: cset w12, ne
0x1001715f8 <+432>: tbnz w12, #0, 0x100171620 ; <+472>
0x1001715fc <+436>: lsl x12, x11, #3
0x100171600 <+440>: cmp x12, #64
0x100171604 <+444>: b.hs 0x100171624 ; <+476>
0x100171608 <+448>: and x9, x9, #0xff
0x10017160c <+452>: lsl x9, x9, x12
0x100171610 <+456>: orr x10, x9, x10
0x100171614 <+460>: str x10, [sp, #8]
0x100171618 <+464>: add x9, x11, #1
0x10017161c <+468>: tbz x9, #63, 0x10017151c ; <+212>
0x100171620 <+472>: brk #0x1
0x100171624 <+476>: adr x0, #584198 ; "fatal error"
0x100171628 <+480>: nop
0x10017162c <+484>: adr x3, #584228 ; "shift amount is larger than type size in bits"
0x100171630 <+488>: nop
0x100171634 <+492>: movz w1, #0xb
0x100171638 <+496>: orr w2, wzr, #0x2
0x10017163c <+500>: movz w4, #0x2d
0x100171640 <+504>: orr w5, wzr, #0x2
0x100171644 <+508>: bl 0x100171448 ; <+0>
on the bottom it also states: fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
i dont have a single clue how this can happen
anyone can help? thanks!
Got it working by using this code:
func gravityUpdated(motion: CMDeviceMotion!, error: NSError!) {
let grav : CMAcceleration = motion.gravity;
let x = CGFloat(grav.x);
let y = CGFloat(grav.y);
var p = CGPointMake(x,y)
// Have to correct for orientation.
var orientation = UIApplication.sharedApplication().statusBarOrientation;
if(orientation == UIInterfaceOrientation.LandscapeLeft) {
var t = p.x
p.x = 0 - p.y
p.y = t
} else if (orientation == UIInterfaceOrientation.LandscapeRight) {
var t = p.x
p.x = p.y
p.y = 0 - t
} else if (orientation == UIInterfaceOrientation.PortraitUpsideDown) {
p.x *= -1
p.y *= -1
}
var v = CGVectorMake(p.x, 0 - p.y);
gravity.gravityDirection = v;
animator.addBehavior(gravity)
}
A newly created bitmap seems to have a (white) background by default. At least, a query on the Pixels property confirms. But why is that background color not used as the transparent color when Transparent is set true?
Consider this simple test code:
procedure TForm1.Button1Click(Sender: TObject);
var
Bmp: TBitmap;
begin
Bmp := TBitmap.Create;
try
Bmp.Width := 100;
Bmp.Height := 100;
Bmp.Transparent := True;
Canvas.Draw(0, 0, Bmp); // A white block is drawn
Bmp.Canvas.Brush.Color := Bmp.Canvas.Pixels[0, 99]; // = 'clWhite'
Bmp.Canvas.FillRect(Rect(0, 0, 100, 100));
Canvas.Draw(0, 100, Bmp); // "Nothing" is drawn
finally
Bmp.Free;
end;
end;
For some reason, the entire bitmap surface has to be painted before it can appear transparent, which sounds kind of odd.
The following variations are tried to eliminate the call to FillRect, all with the same outcome (no transparancy):
Only setting Brush.Color,
Brush.Handle := CreateSolidBrush(clWhite),
PixelFormat := pf32Bit,
IgnorePalette := True,
TransparantColor := clWhite,
TransparantMode := tmFixed,
Canvas.Pixels[0, 99] := clWhite which makes only thát pixel transparent,
Modified := True.
So, the wish is to paint only a portion of a newly created bitmap and get the remaining surface transparent.
Using: Delphi 7, Win 7/64.
Just set TransparentColor and Canvas.Brush.Color before setting dimensions of the bitmap.
I really needed to be able to create a completely transparent (and otherwise empty/blank) TBitmap of an arbitrary size in 32bit RGBA format. Many times. Lazarus is able to load such a bitmap into TBitmap and after it's loaded, you can manipulate it with scanline and what not using RGBA format. But it just doesn't work when you create TBitmap yourself. Pixel format seems to be completely ignored. So what I did is so out-of-the box, and simple, that it's almost AMUZING (!). But it is practical, works super nice, and is completely independent of LCL and any 3rd party libraries. Even does not depend on Graphics unit, becasue it generates the actual 32bit RGBA BMP file (I generate it to TMemoryStream, you can generate differently). Then once you have it, elsewhere in your code you can just load it using TBitmap.LoadFrom source or TPicture.LoadFrom source.
The background story
I initially wanted to generate properly formatted BMP file following the format as described here: http://www.fileformat.info/format/bmp/egff.htm
But there were few variants of BMP format, and I was not clear on which one I was supposed to follow. So I decided to go with a reverse engineering approach, but the format description helped me later on. I used a graphical editor (I used GIMP) to create an empty 1x1 pixel 32 RGBA BMP file, and called it alpha1p.bmp, it only contained transparency nothing else.
Then I resized the canvas to 10x10 pixels, and saved as alpha10p.bmp file.
Then I compared the two files:
compating two bmp files in vbindiff on Ubuntu
So I found out that the only differences were the added pixels (every one was 4 bytes all zeros RGBA), and few other bytes in the header. Because of the format documentation at the linked I shared, I figured out that these were: FileSize (in bytes), BitmapWidth (in pixels), BitmapHeight (in pixels) and BitmapDataSize (in bytes). The last one was BitmapWidth*BitmapHeight*4, because each pixel in RGBA is 4 bytes. So now, I could just generate that entire sequence of bytes as seen inside alpha1p.bmp files, minus 4 bytes from the end (the 1st of the BitmapData), then add 4 bytes (all zeroes) of RGBA data for each pixel of the BMP I want to generate, then come back to the initial sequence and update the variable parts: FileSize, width, height and BMP data size. And it works flawlessly! I just had to add test for BigEndian and would swap word and dword numbers before writting. That would become issue on ARM platforms working in BigEndian.
The code
const
C_BLANK_ALPHA_BMP32_PREFIX : array[0..137]of byte
= ($42, $4D, $00, $00, $00, $00, $00, $00, $00, $00, $8A, $00, $00, $00, $7C, $00,
$00, $00, $0A, $00, $00, $00, $0A, $00, $00, $00, $01, $00, $20, $00, $03, $00,
$00, $00, $90, $01, $00, $00, $13, $0B, $00, $00, $13, $0B, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $FF, $00, $00, $FF, $00, $00, $FF,
$00, $00, $FF, $00, $00, $00, $42, $47, $52, $73, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $02, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00 );
(...)
Function RenderEmptyAlphaBitmap(AWidth,AHeight: integer): TMemoryStream;
var
buf : array[1..4096]of byte;
i,p : int64;
w : word;
dw : dword;
BE : Boolean;
begin
buf[low(buf)] := $00; //this is jyst to prevent compiler warning about not initializing buf variable
Result := TMemoryStream.Create;
if(AWidth <1)then AWidth := 1;
if(AHeight<1)then AHeight := 1;
//Write File Header:
Result.Write(C_BLANK_ALPHA_BMP32_PREFIX, SizeOf(C_BLANK_ALPHA_BMP32_PREFIX));
//Now start writing the pixels:
FillChar(buf[Low(buf)],Length(buf),$00);
p := Result.Position;
Result.Size := Result.Size+int64(AWidth)*int64(AHeight)*4;
Result.Position := p;
i := int64(AWidth)*int64(AHeight)*4; //4 because RGBA has 4 bytes
while(i>0)do
begin
if(i>Length(buf))
then w := Length(buf)
else w := i;
Result.Write(buf[Low(buf)], w);
dec(i,w);
end;
//Go back to the original header and update FileSize, Width, Height, and offset fields:
BE := IsBigEndian;
Result.Position := 2; dw := Result.Size;
if BE then SwapEndian(dw); Result.Write(dw, SizeOf(dw));
Result.Position := 18; dw := AWidth;
if BE then SwapEndian(dw); Result.Write(dw, SizeOf(dw));
Result.Position := 22; dw := AHeight;
if BE then SwapEndian(dw); Result.Write(dw, SizeOf(dw));
Result.Position := 34; dw := AWidth*AHeight*4;
if BE then SwapEndian(dw); Result.Write(dw, SizeOf(dw));
//Done:
Result.Position := 0;
end;
Notice how C_BLANK_ALPHA_BMP32_PREFIX constant is basically the copy of byte sequence from my sample alpha1p.bmp file, minus last 4 bytes, which were the RGBA pixel. :D
Also, I am using IsBigEndian function which goes like this:
Function IsBigEndian: Boolean;
type
Q = record case Boolean of
True : (i: Integer);
False : (p: array[1..4] of Byte);
end;
var
x : ^Q;
begin
New(x);
x^.i := 5;
Result := (x^.p[4]=5);
Dispose(x);
end;
This is copied from Lazarus Wiki: http://wiki.freepascal.org/Writing_portable_code_regarding_the_processor_architecture you can skip this part if you don't deal with BigEndian platforms, or you can use a compilers IFDEF directive. The thing is that if you use {$IFDEF ENDIAN_BIG} then it is what compiler things is the case, whereas the function actually tests the system. This is explained in the linked wiki.
Sample usage
Procedure TForm1.Button1Click(Sender: TObject);
var
MS : TMemoryStream;
begin
MS := RenderEmptyAlphaBitmap(Image1.Width, Image1.Height);
try
if Assigned(MS)then Image1.Picture.LoadFromStream(MS);
//you can also MS.SaveToFile('my_file.bmp'); if you want
finally
FreeAndNil(MS);
end;
end;
This will draw a Red square and the rest is transparent.
procedure TForm1.btnDrawClick(Sender: TObject);
var
Bmp: TBitmap;
begin
Bmp := TBitmap.Create;
try
Bmp.Width := 100;
Bmp.Height := 100;
Bmp.Transparent := TRUE;
Bmp.TransparentColor := clWhite;
Bmp.Canvas.Brush.Color := clWhite;
Bmp.Canvas.FillRect(Rect(0, 0, Bmp.Width, Bmp.Height));
Bmp.Canvas.Brush.Color := clRed;
Bmp.Canvas.FillRect(Rect(42, 42, 20, 20));
Canvas.Draw(12, 12, Bmp);
finally
Bmp.Free;
end;
end;