Delphi XE7 TBitBtn Image wrong Displayed at run time - delphi

I have a project developed with Delphi 7 and VCL, that compiles and works with the new Delphi XE7 without any modification, the only issue that I'm experiencing is that the Glyph image of the TBitBtn is wrong displayed(as you can see the color and the position are not the same) at run time despite is well displayed at design time .
Design Time :
RunTime :
What can cause the problem ?
NOTE
With the old Delphi 7 I don't have this issue : the image is correctly displayed both at design and run time .
Following the first 3 lines of the Glyph data in the dfm :
Glyph.Data = {
36050000424D3605000000000000360400002800000010000000100000000100
080000000000000100000000000000000000000100000000000000164900001C
4D0000275700003C7100003D6E00004483000046760000467B0000548C00005B
...
that it is the same in Delphi 7 and Delphi XE7.
If I click on the Glyph property of TBitBtn I can see the image(the wrong one) in the dialog and if I confirm with OK, the IDE changes the Glyph property in the DFM files in this way(diff output) :
Glyph.Data = {
- 36340000424D3638000000000000360800002800000040000000400000000100
- 1800000000000030000000000000000000000001000000000000724242007B47
- 47007D4849007E4C4B00804C4C0081524F008155500083535200845754008458
- 56008459590085525200855B5700875D58008B6260008B6361008B6362008C65
- 63008C6664008D615C008D6665008D6766008E5A5A008F696800906B6A00916C
- 6B00935F5F00936F6E0094616100946F6F00957170009773730097747400986A
- 6600997777009C7B7B009E7D7D009F6B6B00A06C6C00A1818100A26E6E00A37B
- 7400A3817600A4707000A6727200A67C7600A6867A00A7737300A7877B00A983
- 7B00AA8E8E00AB8C7F00AC8A7F00AC8F8F00AE918300AE939300AF959500B190
- 8400B1958700B2999900B37F7F00B49B9B00B79F9F00B8848400B89FA000BA86
- 8600BB878700BBA5A500BC888800BE8A8A00C08B8B00C18D8D00C1A89700C2AD
- AD00C38F8F00C4A69800C5919100C7929200C8939300C9949400CA959500CB95
- 9600CB969600CCA79D00CDA49D00CF999A00CFBBA700D09D9C00D0BCA700D0BC
- A800D0BDA900D19C9C00D1BDA900D29F9E00D39E9E00D3AAA300D49F9F00D4B2
- A700D4C1AC00D4C1AD00D4C2AD00D4C5C500D6ABA500D6C8C800D7ADA700D7C5
- B000D8AFA800D8C7B000D8C7B100D8CACB00D9B1A900D9BEAE00DAB2AA00DAB3
- AA00DAB3AB00DACAB300DACECE00DBA6A600DBB4AB00DBB4AC00DBB5AC00DBB6
- AC00DBC1B000DBCBB400DBCCB400DCB6AC00DCB6AD00DCCCB400DDB7AE00DDB8
- AE00DDCDB600DEADAB00DEBAAF00DEBBB000DED4D400DFBCB100DFBDB100DFBD
- B200DFBEB200DFD0B900E0ADAC00E0B4AE00E0BDB200E0BEB200E0BFB300E0D2
- BA00E1ADAD00E1C0B400E1C1B400E1D1BA00E2BAB200E2C3B500E3C4B600E3C5
- B700E3C7B700E4C5B700E4C7B700E4C7B800E4C8B800E4C9B900E5C9B900E5CA
- B900E5CABA00E5CBBA00E6CCBC00E6DDDD00E7CEBD00E7D7C000E8B8B500E8B9
- B600E8BAB600E8C3B900E8CFBD00E8CFBE00E8D0BE00E8D0BF00E8D1BF00E9C7
- BB00E9D1BF00E9D2BF00E9D2C000E9D3C000EAC7BC00EBD5C200ECB9B800ECCE
- BF00ECD4C200ECD7C300ECD8C300ECD8C400ECD9C400ECE6E600EDD9C400EDD9
- C500EDDAC500EDDBC500EED3C300EEDBC700EEDCC700EEDDC800EFCCC100EFDD
- C800F0BEBC00F0DFC900F0E0CA00F0E1CA00F0E1CB00F1E1CB00F1E2CB00F1E2
- CC00F1E3CC00F1EDED00F2C4C100F2C9C200F2DDCA00F2E3CC00F2E4CC00F2E4
- CD00F2E5CD00F2EDEE00F3E5CD00F3E5CE00F3E6CE00F3EFEF00F4F0F000F4F0
- F100F5E5CF00F5F2F200F6EBD200F6ECD300F6F3F400F7ECD300F7EDD300F7ED
- D400F7EED400F8EDD400F8EED400F8EED500F8EFD500F8F0D500F8F6F600F9EF
- D500F9F0D600F9F1D600F9F1D700F9F7F700FAF2D700FAF8F800FAF9F900FBF4
- D900FBF9F900FBFAFA00FCFBFB00FDFDFD00FEFEFE00FFFFFF00FFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFCFCD3C5C5C7B5B5D7CBCBE4DC
- DCEFEAEAF7F5F5FDFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ 36300000424D3634000000000000360400002800000040000000400000000100
+ 1800000000000030000000000000000000000001000000000000FFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
## -469,7 +403,43 ## object Form1: TForm1
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
- FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF}
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000}
At this link there is the complete DFM file that present the problem .

It appears to be a mismatch between NumGlyphs property and actual number of Glyphs in the image.
I can not explain why you don't have the problem in Delphi 7, but I can create the same effect in XE7 with e.g. a 64x64 TBitBtn, a 256 pixel wide image, that has four glyphs (64 pixels wide each), if I set NumGlyphs := 3.
In design time, the first glyph is shown. The calculation of pixels per glyph (256 div 3) would give a width of 85 pixels. But that doesn't matter since we are seeing the first glyph, beginning from first pixel.
In runtime it seems the button is in disabled (Enabled=false) state, and thus it shows the second glyph, but because of wrong value in NumGlyphs it shows the pixels starting with left 85 forward, thus cutting 21 pixels from left and bleeding those 21 pixels from the third glyph into view.
You can compare the beginning of the Glyph.Data in the .dfm files (in D7 and XE7) with the following break up
Glyph.Data = {
36C00000424D36C0000000000000360000002800000000010000400000000100
18000000000000C00000C40E0000C40E00000000000000000000F0F0F0F0F0F0
F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0
...
interpreted as
offs 36C00000 file size = 0x0000C036 = 49206
0000 424D 'BM' signature
0002 36C00000 file size
0006 0000 reserved 2 bytes
0008 0000 reserved 2 bytes
000A 36000000 pixel array offset = 0x36 = 54
000E 28000000 BITMAPINFOHEADER size 0x28 = 40
0012 00010000 bitmap width 0x0100 = 256
0016 40000000 bitmap height 0x0040 = 64
001A 0100 num of color planes = 1
001C 1800 num of bits per pixel = 24
001E 00000000 compression method (0 = none)
0022 00C00000 raw bitmap data size 49152 = 256 x 64 x 3 bytes
0026 C40E0000 horizontal resolution (pix per meter) 3780/m
002A C40E0000 vertical resolution (pix per meter) 3780/m
002E 00000000 num of colors in color palette or 0 for default 2^n
0032 00000000 num of important colors used, or 0 for every color is important
pixel array follows
0036 F0F0F0F0F0F0
003C F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0
Delphi adds its own size in front of the actual .bmp file. Offset is from the 'BM' signature
Edit after additional data
The three lines that are the same in D7 and XE7 interpreted:
Glyph.Data = {
36050000 File size 1334
424D 'BM'
36050000 file size 1334
0000
0000
36040000 1078 pix arr offset
28000000 40 header size
10000000 16 bmp width
10000000 16 bmp height
0100 1 color planes
0800 8 bits per pix
00000000 no compression
00010000 256 raw bitmap data size
00000000 0 horiz pix per meter
00000000 0 vert ppm
00010000 256 colors in palette
00000000 all colors important
00164900001C ....
Doesn't really fit the image you posted, which is 64 x 64 within the thin gray border and has 1628 unique colors.
But what really puzzles me is the change when you click the Glyph property. According the diff listing the three first replaced (-) lines don't match the above three lines at all. Break up follows:
{
36340000 13366
424D 'BM'
36380000 14390
0000
0000
36080000 2102 pix arr offset
28000000 40 header size
40000000 64 width
40000000 64 height
0100
1800
00000000
00300000 12288 raw bmp data size
00000000
00000000
00010000 256 colors in palette
00000000
724242007B47 ...}
Now, this matches the size (64 x 64) but not number of colors. Anyway the rest is corrupt and useless data. Go figure. The only solution I can think of is to replace the image.
Since I already had your posted image in my editor, I made a triple image (normal, disabled, pressed) 192 x 64 and tested in D7 as well as in XE7 and works fine for me.
Here, since your original is lost, as a friendly seasons gift :-)

I decided to enter another answer instead of editing the previous, because the first answer was given by the information available at that time, and although not the correct one, may serve a purpose. In the following is an answer I believe is the correct one.
The short answer
Most of the images had partly corrupt headers. The reason might be in the original images, conversion from other image formats or in Delphi7, but I couldn't set aside enough time to debug the code. If I had the time I would look at TBitmap.ReadDIB and TBitmap.Changed. The error surfaces in Delphi XE7 (possibly also in earlier version) because some changes have been made in above mentioned methods.
The cure is to redraw the images in a decent image editor.
The longer answer
I came to the corrupt images conclusion by investigating Glyph.Data of a couple of TBitBtn controls in the .dfm file. Those that seem to be wrong have similar errors in the bitmap headers. Let's look at one of them:
ToolButton1: TBitBtn
Glyph.Data = {
36340000424D3638000000000000360800002800000040000000400000000100
1800000000000030000000000000000000000001000000000000724242007B47
...}
Glyph.BitmapSize = 13366
bmfh.bfType = BM
bmfh.bfSize = 14390
bmfh.bfReserved1 = 0
bmfh.bfReserved2 = 0
bmfh.bfOffBits = 2102
bmih.biSize = 40
bmih.biWidth = 64
bmih.biHeight = 64
bmih.biPlanes = 1
bmih.biBitCount = 24
bmih.biCompression = 0
bmih.biSizeImage = 12288
bmih.biXPelsPerMeter = 0
bmih.biYPelsPerMeter = 0
bmih.biClrUsed = 256
bmih.biClrImportant = 0
The structure of the whole Glyph.Data is
Glyph.BitmapSize (size 4 bytes), managed by Delphi
BITMAPFILEHEADER (size 14 bytes)
BITMAPINFOHEADER (size 40 bytes)
bmiColors array (size, when used, should be biClrUsed * SizeOf(TRGBQuad) or 1024 in this case)
bmBits (pixel values, either indexes to bmiColors or direct RGB(A) color values)
The problems are:
Glypf.BitmapSize is 13366 but bmpfh.bfSize reports it to be 14390, a difference of 1024 bytes.
Offset of pixel array is reported to be 2102. Subtracting size of bmfh (14) and bmih (40) leaves 2048 bytes for the colortable, bmiColors. Should be 1024.
The actual image data in the .dfm is 1024 bytes for the color table, bmiColors. When the image is read in XE7 the erroneous bfOffBits offsets the beginning of the pixel data and thus we see the shift in the image and its colors.
When the image is 'reloaded' by opening the image editor the error is repeted with already erroneous data and the image and color shifts are exaggerated.
As said above, the cure is to redraw the images. One could of course also attempt to change the .dfm files directly.

Related

Object does not exist in the pdf file structure

%PDF-1.5
...
10737 0 obj
<</MarkInfo<</Marked true>>/Metadata 161 0 R/PageLayout/OneColumn/Pages 10732 0 R/StructTreeRoot 206 0 R/Type/Catalog>>
endobj
10738 0 obj
<</Contents[10740 0 R 10741 0 R 10747 0 R 10748 0 R 10749 0 R 10750 0 R 10751 0 R 10752 0 R]/CropBox[0.0 0.0 516.0 728.64]/MediaBox[0.0 0.0 516.0 728.64]/Parent 10733 0 R/Resources<</ColorSpace<</CS0 10771 0 R/CS1 10772 0 R>>/ExtGState<</GS0 10773 0 R>>/Font<</C2_0 10778 0 R/C2_1 10783 0 R/C2_2 10788 0 R/C2_3 10793 0 R/C2_4 10798 0 R/TT0 10800 0 R/TT1 10802 0 R/TT2 10804 0 R/TT3 10806 0 R/TT4 10808 0 R>>/XObject<</Im0 10769 0 R>>>>/Rotate 0/StructParents 0/Tabs/S/Type/Page>>
endobj
10739 0 obj
<</Filter/FlateDecode/First 410/Length 3756/N 38/Type/ObjStm>>stream
10771 0 10772 21 10773 42 10774 138 10775 190 10776 442 10777 741 10778 752 10779 869 10780 921 10781 1190 10782 2050 10783 2061 10784 2192 10785 2244 10786 2504 10787 3456 10788 3467 10789 3587 10790 3639 10791 3903 10792 6058 10793 6069 10794 6196 10795 6248 10796 6507 10797 8153 10798 8164 10799 8284 10800 8496 10801 9662 10802 9894 10803 11072 10804 11325 10805 11779 10806 11985 10807 13147 10808 13395
[/ICCBased 10753 0 R][/ICCBased 10754 0 R]
<</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>>
<</Ordering(Identity)/Registry(Adobe)/Supplement 0>><</Ascent 858/CIDSet 10757 0 R/CapHeight 719/Descent -148/Flags 4/FontBBox[-16 -148 1008 858]/FontFamily(\xfe\xff\x00H\x00Y\xc9\x11\xac\xe0\xb5\x15)/FontFile2 10758 0 R/FontName/YDRADB+H2gtrM/FontStretch/Normal/FontWeight 400/ItalicAngle 0/StemV 60/Type/FontDescriptor/XHeight 520>>
...
endstream
endobj
...
No. - Type
10732 - Pages
206 - StructTreeRoot
10771, 10772, 10773, 10778 ... - Font
Many indirect objects including 10732, 206, 10771 and 10772 do not exist in the pdf file.
But I think I found objects 10771~10808 in object 10739 stream.
Q1. Why are there no object 10732(Pages) and 206(StructTreeRoot) in the pdf file?
Q2. Why are indirect objects in stream?
I would be grateful if you would suggest any explanations or resources for reference.
Starting with version 1.5 PDF supports so called object streams, i.e. stream objects which contain other non-stream objects.
Your object 10739 is such an object stream as you can see in its Type ObjStm.
This allows those other objects to be compressed. In particular structure tree objects which otherwise can substantially increase the size of a PDF, can be compressed fairly well, reducing their impact on the document size.
For details please study the PDF specification, section 7.5.7 – Object Streams, in either the current PDF specification ISO 32000-2 or its predecessor ISO 32000-1.
Adobe has shared a copy of ISO 32000-1 on their web site which merely has its ISO page headers replaced. Simply google for "PDF32000_2008"; currently it is located at https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf but as far as I know this isn't a permalink.

Decode UDP message with LUA

I'm relatively new to lua and programming in general (self taught), so please be gentle!
Anyway, I wrote a lua script to read a UDP message from a game. The structure of the message is:
DATAxXXXXaaaaBBBBccccDDDDeeeeFFFFggggHHHH
DATAx = 4 letter ID and x = control character
XXXX = integer shows the group of the data (groups are known)
aaaa...HHHHH = 8 single-precision floating point numbers
The last ones is those numbers I need to decode.
If I print the message as received, it's something like:
DATA*{V???A?A?...etc.
Using string.byte(), I'm getting a stream of bytes like this (I have "formatted" the bytes to reflect the structure above.
68 65 84 65/42/20 0 0 0/237 222 28 66/189 59 182 65/107 42 41 65/33 173 79 63/0 0 128 63/146 41 41 65/0 0 30 66/0 0 184 65
The first 5 bytes are of course the DATA*. The next 4 are the 20th group of data. The next bytes, the ones I need to decode, and are equal to those values:
237 222 28 66 = 39.218
189 59 182 65 = 22.779
107 42 41 65 = 10.573
33 173 79 63 = 0.8114
0 0 128 63 = 1.0000
146 41 41 65 = 10.573
0 0 30 66 = 39.500
0 0 184 65 = 23.000
I've found C# code that does the decode with BitConverter.ToSingle(), but I haven't found any like this for Lua.
Any idea?
What Lua version do you have?
This code works in Lua 5.3
local str = "DATA*\20\0\0\0\237\222\28\66\189\59\182\65..."
-- Read two float values starting from position 10 in the string
print(string.unpack("<ff", str, 10)) --> 39.217700958252 22.779169082642 18
-- 18 (third returned value) is the next position in the string
For Lua 5.1 you have to write special function (or steal it from François Perrad's git repo )
local function binary_to_float(str, pos)
local b1, b2, b3, b4 = str:byte(pos, pos+3)
local sign = b4 > 0x7F and -1 or 1
local expo = (b4 % 0x80) * 2 + math.floor(b3 / 0x80)
local mant = ((b3 % 0x80) * 0x100 + b2) * 0x100 + b1
local n
if mant + expo == 0 then
n = sign * 0.0
elseif expo == 0xFF then
n = (mant == 0 and sign or 0) / 0
else
n = sign * (1 + mant / 0x800000) * 2.0^(expo - 0x7F)
end
return n
end
local str = "DATA*\20\0\0\0\237\222\28\66\189\59\182\65..."
print(binary_to_float(str, 10)) --> 39.217700958252
print(binary_to_float(str, 14)) --> 22.779169082642
It’s little-endian byte-order of IEEE-754 single-precision binary:
E.g., 0 0 128 63 is:
00111111 10000000 00000000 00000000
(63) (128) (0) (0)
Why that equals 1 requires that you understand the very basics of IEEE-754 representation, namely its use of an exponent and mantissa. See here to start.
See #Egor‘s answer above for how to use string.unpack() in Lua 5.3 and one possible implementation you could use in earlier versions.

Getting a 2D histogram of a grayscale image in Julia

Using the Images package, I can open up a color image, convert it to Gray scale and then :
using Images
img_gld = imread("...path to some color jpg...")
img_gld_gs = convert(Image{Gray},img_gld)
#change from floats to Array of values between 0 and 255:
img_gld_gs = reinterpret(Uint8,data(img_gld_gs))
Now I've got a 1920X1080 array of Uint8's:
julia> img_gld_gs
1920x1080 Array{Uint8,2}
Now I want to get a histogram of the 2D array of Uint8 values:
julia> hist(img_gld_gs)
(0.0:50.0:300.0,
6x1080 Array{Int64,2}:
1302 1288 1293 1302 1297 1300 1257 1234 … 12 13 13 12 13 15 14
618 632 627 618 623 620 663 686 189 187 187 188 185 183 183
0 0 0 0 0 0 0 0 9 9 8 7 8 7 7
0 0 0 0 0 0 0 0 10 12 9 7 13 7 9
0 0 0 0 0 0 0 0 1238 1230 1236 1235 1230 1240 1234
0 0 0 0 0 0 0 0 … 462 469 467 471 471 468 473)
But, instead of 6x1080, I'd like 256 slots in the histogram to show total number of times each value has appeared. I tried:
julia> hist(img_gld_gs,256)
But that gives:
(2.0:1.0:252.0,
250x1080 Array{Int64,2}:
So instead of a 256x1080 Array, it's 250x1080. Is there any way to force it to have 256 bins (without resorting to writing my own hist function)? I want to be able to compare different images and I want the histogram for each image to have the same number of bins.
Assuming you want a histogram for the entire image (rather than one per row), you might want
hist(vec(img_gld_gs), -1:255)
which first converts the image to a 1-dimensional vector. (You can also use img_gld_gs[:], but that copies the data.)
Also note the range here: the hist function uses a left-open interval, so it will omit counting zeros unless you use something smaller than 0.
hist also accepts a vector (or range) as an optional argument that specifies the edge boundaries, so
hist(img_gld_gs, 0:256)
should work.

Golang append memory allocation VS. STL push_back memory allocation

I compared the Go append function and the STL vector.push_back and found that different memory allocation strategy which confused me. The code is as follow:
// CPP STL code
void getAlloc() {
vector<double> arr;
int s = 9999999;
int precap = arr.capacity();
for (int i=0; i<s; i++) {
if (precap < i) {
arr.push_back(rand() % 12580 * 1.0);
precap = arr.capacity();
printf("%d %p\n", precap, &arr[0]);
} else {
arr.push_back(rand() % 12580 * 1.0);
}
}
printf("\n");
return;
}
// Golang code
func getAlloc() {
arr := []float64{}
size := 9999999
pre := cap(arr)
for i:=0; i<size; i++ {
if pre < i {
arr = append(arr, rand.NormFloat64())
pre = cap(arr)
log.Printf("%d %p\n", pre, &arr)
} else {
arr = append(arr, rand.NormFloat64())
}
}
return;
}
But the memory address is invarient to the increment of size expanding, this really confused me.
By the way, the memory allocation strategy is different in this two implemetation (STL VS. Go), I mean the expanding size. Is there any advantage or disadvantage? Here is the simplified output of code above[size and first element address]:
Golang CPP STL
2 0xc0800386c0 2 004B19C0
4 0xc0800386c0 4 004AE9B8
8 0xc0800386c0 6 004B29E0
16 0xc0800386c0 9 004B2A18
32 0xc0800386c0 13 004B2A68
64 0xc0800386c0 19 004B2AD8
128 0xc0800386c0 28 004B29E0
256 0xc0800386c0 42 004B2AC8
512 0xc0800386c0 63 004B2C20
1024 0xc0800386c0 94 004B2E20
1280 0xc0800386c0 141 004B3118
1600 0xc0800386c0 211 004B29E0
2000 0xc0800386c0 316 004B3080
2500 0xc0800386c0 474 004B3A68
3125 0xc0800386c0 711 004B5FD0
3906 0xc0800386c0 1066 004B7610
4882 0xc0800386c0 1599 004B9768
6102 0xc0800386c0 2398 004BC968
7627 0xc0800386c0 3597 004C1460
9533 0xc0800386c0 5395 004B5FD0
11916 0xc0800386c0 8092 004C0870
14895 0xc0800386c0 12138 004D0558
18618 0xc0800386c0 18207 004E80B0
23272 0xc0800386c0 27310 0050B9B0
29090 0xc0800386c0 40965 004B5FD0
36362 0xc0800386c0 61447 00590048
45452 0xc0800386c0 92170 003B0020
56815 0xc0800386c0 138255 00690020
71018 0xc0800386c0 207382 007A0020
....
UPDATE:
See comments for Golang memory allocation strategy.
For STL, the strategy depends on the implementation. See this post for further information.
Your Go and C++ code fragments are not equivalent. In the C++ function, you are printing the address of the first element in the vector, while in the Go example you are printing the address of the slice itself.
Like a C++ std::vector, a Go slice is a small data type that holds a pointer to an underlying array that holds the data. That data structure has the same address throughout the function. If you want the address of the first element in the slice, you can use the same syntax as in C++: &arr[0].
You're getting the pointer to the slice header, not the actual backing array. You can think of the slice header as a struct like
type SliceHeader struct {
len,cap int
backingArray unsafe.Pointer
}
When you append and the backing array is reallocated, the pointer backingArray will likely be changed (not necessarily, but probably). However, the location of the struct holding the length, cap, and pointer to the backing array doesn't change -- it's still on the stack right where you declared it. Try printing &arr[0] instead of &arr and you should see behavior closer to what you expect.
This is pretty much the same behavior as std::vector, incidentally. Think of a slice as closer to a vector than a magic dynamic array.

Can I write reverse div operator?

I have a mathematical equation and How can I find the it's reverse ?
My equation:
var
x,y:integer;
begin
//example x=1234;
x-(x div 100):=y
end;
after the code I konw "y" how can I find the "x"?(1234)
In general, you can't. Since div does integer division, there are potentially many inputs that can/will produce the same result. Starting from that result, and of those inputs is an equally likely possibility as the original input. For example:
175 div 7 = 25
176 div 7 = 25
177 div 7 = 25
178 div 7 = 25
179 div 7 = 25
180 div 7 = 25
181 div 7 = 25
Starting from 25, any of those numbers from 175 to 181 would be an equally viable answer.

Resources