GNU linker - How to fill unused memory space - gcc

Some sections within my program are located at different places in memory and there are some unused memory locations. The following is a part of the object file of my program:
a0000128: 20cf8f93 addi t6,t6,524 # a0000330 <region_1>
a000012c: 000f8067 jr t6
Disassembly of section .fill:
00000000a0000130 <_end-0x800290>:
a0000130: deaa sw a0,124(sp)
a0000132: c0ad beqz s1,a0000194 <_start+0x194>
a0000134: dede sw s7,124(sp)
a0000136: c0ad beqz s1,a0000198 <_start+0x198>
...
Disassembly of section .s_region_1:
00000000a0000330 <region_1>:
a0000330: 00400f97 auipc t6,0x400
a0000334: 00cf8f93 addi t6,t6,12 # a040033c <region_2>
a0000338: 000f8067 jr t6
As shown, instruction at address 0xa000012c jumps to another instruction at address 0xa0000330. Since there are unused memory locations, I used FILL command in linker script. However, corresponding HEX file (generated with objcopy -O verilog) does not include the machine code of region_1. That is, HEX file only includes .text section and the data that is used to pad unused memory region:
13 0F 00 00 9B 0F 10 00 93 9F FF 01 1B 08 F0 FF
13 18 38 03 13 08 18 04 13 18 C8 00 13 08 98 12
73 10 18 30 97 0F 00 00 93 8F CF 20 67 80 0F 00
#A0000130
AA DE AD C0 DE DE AD C0 DE DE AD C0 DE DE AD C0
DE DE AD C0 DE DE AD C0 DE DE AD C0 DE DE AD C0
DE DE AD C0 DE DE AD C0 DE DE AD C0 DE DE AD C0
DE DE AD C0 DE DE AD C0 DE DE AD C0 DE DE AD C0
...
The following is the content of the linker script:
SECTIONS
{
. = 0xA0000000;
.text : { *(.text) }
.fill :
{
FILL(0xDEADC0DE);
BYTE(0xAA);
. = . + 0x1FF;
}
.s_region_1 : { *(s_region_1) }
.bss : { *(.bss) }
_end = .;
}
What is wrong with the linker script above?
This is the memory map I want to generate:
/*************************/
.text
/*************************/
/* EMPTY REGION */
/*************************/
.section_1
/*************************/

I noticed that I have to add "aw" flags within my assembly code when defining the section:
.section ".sregion1","aw"
region_1:
la x31, region_2
jr x31
After adding "aw" flags, the HEX file was generated by objcopy as expected:
#80000000
1B 00 10 00 13 10 F0 01 B7 F0 0F 00 9B 80 70 81
93 90 C0 00 93 80 90 A5 13 01 80 00 93 01 80 00
1B 02 10 00 13 12 F2 01 B7 B2 0F 00 9B 82 12 FB
...
#80400130
97 0F 00 00 93 8F CF 00 67 80 0F 00 97 0F 00 00
93 8F 0F 00 67 80 0F 00
The following is the final version of my linker file:
OUTPUT_ARCH( "riscv" )
ENTRY(_start)
/*
MEMORY {
text (RX): o = 0x80000000, LENGTH = 128M
s_region_1 (RX): o = 0x80400000, LENGTH = 256K
}
*/
SECTIONS
{
. = 0x80000000;
.text :
{
*(.text);
}
. = . + 0x400000;
.sregion1 : { *(.sregion1) }
. = . + 0x400000;
.bss : { *(.bss) }
_end = .;
}

Related

x86_64 assembly instructions changed in link stage of GCC

I'm compiling a program using the sqlite3 libary in Linux(centos7_64). As the user has an old CPU, I set the -march=nehalem flag in GCC (-march=nehalem -mtune=nehalem -m64 -O3). I find I can't limit the assembly instructions to nehalem, some BMI operations still exist in the final binary.
Follow the output step by step, I find the problem comes from the linker (ld).
libsqlite3.a:
632c2: 66 41 83 4f 26 01 orw $0x1,0x26(%r15)
632c8: 0f b6 84 24 80 00 00 movzbl 0x80(%rsp),%eax
632cf: 00
632d0: c1 e0 08 shl $0x8,%eax
632d3: 89 c2 mov %eax,%edx
632d5: 0f b6 84 24 81 00 00 movzbl 0x81(%rsp),%eax
632dc: 00
632dd: c1 e0 10 shl $0x10,%eax
632e0: 09 d0 or %edx,%eax
632e2: 8d 90 00 fe ff ff lea -0x200(%rax),%edx
632e8: 41 89 47 30 mov %eax,0x30(%r15)
632ec: 81 fa 00 fe 00 00 cmp $0xfe00,%edx
632f2: 0f 87 d1 05 00 00 ja 638c9 <sqlite3BtreeOpen+0xb29>
632f8: 8d 50 ff lea -0x1(%rax),%edx
632fb: 85 c2 test %eax,%edx
632fd: 0f 85 c6 05 00 00 jne 638c9 <sqlite3BtreeOpen+0xb29>
However, in the final binary:
9499f2: 66 41 83 4f 26 01 orw $0x1,0x26(%r15)
9499f8: 0f b6 84 24 80 00 00 movzbl 0x80(%rsp),%eax
9499ff: 00
949a00: 0f b6 94 24 81 00 00 movzbl 0x81(%rsp),%edx
949a07: 00
949a08: c1 e0 08 shl $0x8,%eax
949a0b: 89 c1 mov %eax,%ecx
949a0d: 89 d0 mov %edx,%eax
949a0f: c1 e0 10 shl $0x10,%eax
949a12: 09 c8 or %ecx,%eax
949a14: 8d 90 00 fe ff ff lea -0x200(%rax),%edx
949a1a: 41 89 47 30 mov %eax,0x30(%r15)
949a1e: 81 fa 00 fe 00 00 cmp $0xfe00,%edx
949a24: 0f 87 cf 05 00 00 ja 949ff9 <sqlite3BtreeOpen+0xb09>
949a2a: c4 e2 78 f3 c8 blsr %eax,%eax
949a2f: 85 c0 test %eax,%eax
949a31: 0f 85 c2 05 00 00 jne 949ff9 <sqlite3BtreeOpen+0xb09>
Notice the last few lines, the linker changed the lea to blsr, which is unexpected.
Thus, why will this happen. Will the linker (ld) optimize the code further? How to limit the instrutions for the linker to use?
Many thanks for the comments. I have found the problem, as Peter Cordes said in the comment, I linked to another set of sqlite library. I installed too many sets of GCC compiler environment, and each compiler has its own sqlite in its default library path. My project was managed by cmake, it remembered all previous GCC settings...
Steps to discover:
add -v flag to gcc commands.
copy the ld commands out, and add flag "--print-map -Map=demo.map", run the full ld command again.
search the library name (sqlite here) in demo.map, I clearly find another set of sqlite library has been linked. Realise how stupid I am...
Update: I have a new problem: if the library.a is compiled with an advanced CPU instruction, how to downgrade it in link stage, seems those instructions will be copied into binary without checking the -march flags in GCC.

Usage of instruction pxor before SSE instruction cvtsi2ss

I am currently writing various implementations of a color to black/white image converter. I would like to do a :
Simple C++ implementation
Self made ASM implementation
Self made ASM implementation with AVX vector instructions.
The goal is to benchmark each one of these and analyse the performance improvement I get.
The following snippet of code is the C++ implementation. It only treats a single portion of the image, because I also want to do multithreaded computing.
void CBwConverter::run(const CImg<uint8_t> &src, CImg<uint8_t> &dst, uint32_t pixel, size_t size) const {
const uint8_t *rC = src.data(0,pixel,0,0);
const uint8_t *gC = src.data(0,pixel,0,1);
const uint8_t *bC = src.data(0,pixel,0,2);
uint8_t *mC = dst.data(0,pixel,0,0);
for(size_t c = 0; c < size; c++, rC++, gC++, bC++, mC++) {
*mC = (uint8_t)(0.299f*(*rC) + 0.587f*(*gC) + 0.114f*(*bC));
}
}
Now, before starting the ASM version, I had my C++ code compiled and disassembled just to see how it looks like. After compiling with gcc -std=c++11 -g -O2 -c CBwConverter.cc, I obtained the following output with objdump -d CBwConvert.o :
0000000000000000 <_ZNK12CBwConverter3runERKN12cimg_library4CImgIhEERS2_jm>:
0: 53 push %rbx
1: 8b 3e mov (%rsi),%edi
3: 89 c8 mov %ecx,%eax
5: 44 8b 56 04 mov 0x4(%rsi),%r10d
9: 44 8b 5e 08 mov 0x8(%rsi),%r11d
d: 89 c9 mov %ecx,%ecx
f: 48 8b 5e 18 mov 0x18(%rsi),%rbx
13: 0f af c7 imul %edi,%eax
16: 4c 0f af d7 imul %rdi,%r10
1a: 4b 8d 34 1b lea (%r11,%r11,1),%rsi
1e: 4c 8d 0c 03 lea (%rbx,%rax,1),%r9
22: 4c 89 d7 mov %r10,%rdi
25: 49 0f af fb imul %r11,%rdi
29: 4c 0f af d6 imul %rsi,%r10
2d: 48 01 c7 add %rax,%rdi
30: 4c 01 d0 add %r10,%rax
33: 48 01 df add %rbx,%rdi
36: 48 8d 34 03 lea (%rbx,%rax,1),%rsi
3a: 8b 02 mov (%rdx),%eax
3c: 48 0f af c8 imul %rax,%rcx
40: 48 03 4a 18 add 0x18(%rdx),%rcx
44: 4d 85 c0 test %r8,%r8
47: 74 6b je b4 <_ZNK12CBwConverter3runERKN12cimg_library4CImgIhEERS2_jm+0xb4>
49: 31 d2 xor %edx,%edx
4b: f3 0f 10 25 00 00 00 movss 0x0(%rip),%xmm4 # 53 <_ZNK12CBwConverter3runERKN12cimg_library4CImgIhEERS2_jm+0x53>
52: 00
53: f3 0f 10 1d 00 00 00 movss 0x0(%rip),%xmm3 # 5b <_ZNK12CBwConverter3runERKN12cimg_library4CImgIhEERS2_jm+0x5b>
5a: 00
5b: f3 0f 10 15 00 00 00 movss 0x0(%rip),%xmm2 # 63 <_ZNK12CBwConverter3runERKN12cimg_library4CImgIhEERS2_jm+0x63>
62: 00
63: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
68: 41 0f b6 04 11 movzbl (%r9,%rdx,1),%eax
6d: 66 0f ef c0 pxor %xmm0,%xmm0
71: f3 0f 2a c0 cvtsi2ss %eax,%xmm0
75: 0f b6 04 17 movzbl (%rdi,%rdx,1),%eax
79: 0f 28 c8 movaps %xmm0,%xmm1
7c: 66 0f ef c0 pxor %xmm0,%xmm0
80: f3 0f 59 cc mulss %xmm4,%xmm1
84: f3 0f 2a c0 cvtsi2ss %eax,%xmm0
88: 0f b6 04 16 movzbl (%rsi,%rdx,1),%eax
8c: f3 0f 59 c3 mulss %xmm3,%xmm0
90: f3 0f 58 c1 addss %xmm1,%xmm0
94: 66 0f ef c9 pxor %xmm1,%xmm1
98: f3 0f 2a c8 cvtsi2ss %eax,%xmm1
9c: f3 0f 59 ca mulss %xmm2,%xmm1
a0: f3 0f 58 c1 addss %xmm1,%xmm0
a4: f3 0f 2c c0 cvttss2si %xmm0,%eax
a8: 88 04 11 mov %al,(%rcx,%rdx,1)
ab: 48 83 c2 01 add $0x1,%rdx
af: 49 39 d0 cmp %rdx,%r8
b2: 75 b4 jne 68 <_ZNK12CBwConverter3runERKN12cimg_library4CImgIhEERS2_jm+0x68>
b4: 5b pop %rbx
b5: c3 retq
I can already tell that the for-loop start at 68 and ends at b2.
Something bothers me in the disassembled program. Why does the compiler decide to set registers %xmm0 and %xmm1 to 0, typically at 6d with instruction pxor ? These registers are overwritten just after with instruction cvtsi2ss which loads an integer and converts it to a single-precision number and then finally stores it into them. Why set them to 0 when they are overwritten just after ? If the compiler does it, am I supposed to do the same when writing my own asm version ?

Visual Leak Detector reporting strange leaks in CRT module of VC++

I've just now installed Visual Leak Detector (2.3) on Windows 8. I tested it with blank CRT program (in Visual Studio 2012) that does nothing.
#include <vld.h>
int main(int argc, char** argv)
{
return 0;
}
When I run it VLD reports strange leaks in vc++ crt module:
Visual Leak Detector Version 2.3 installed.
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 31 at 0x0000000052C07530: 70 bytes ----------
Call Stack:
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\stdenvp.c (127): my_application.exe!_setenvp + 0x27 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (223): my_application.exe!__tmainCRTStartup + 0x5 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (164): my_application.exe!mainCRTStartup
0x00000000FAF8167E (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x1A bytes
0x00000000FD8CC3F1 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x21 bytes
Data:
20 B5 C0 52 50 00 00 00 50 92 C0 52 50 00 00 00 ...RP... P..RP...
20 91 DD E1 F6 07 00 00 7E 00 00 00 02 00 00 00 ........ ~.......
12 00 00 00 00 00 00 00 1F 00 00 00 FD FD FD FD ........ ........
50 52 4F 43 45 53 53 4F 52 5F 4C 45 56 45 4C 3D PROCESSO R_LEVEL=
36 00 FD FD FD FD 6....... ........
---------- Block 40 at 0x0000000052C075D0: 72 bytes ----------
Call Stack:
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\stdenvp.c (127): my_application.exe!_setenvp + 0x27 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (223): my_application.exe!__tmainCRTStartup + 0x5 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (164): my_application.exe!mainCRTStartup
0x00000000FAF8167E (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x1A bytes
0x00000000FD8CC3F1 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x21 bytes
Data:
F0 94 C0 52 50 00 00 00 20 76 C0 52 50 00 00 00 ...RP... .v.RP...
20 91 DD E1 F6 07 00 00 7E 00 00 00 02 00 00 00 ........ ~.......
14 00 00 00 00 00 00 00 28 00 00 00 FD FD FD FD ........ (.......
53 45 53 53 49 4F 4E 4E 41 4D 45 3D 43 6F 6E 73 SESSIONN AME=Cons
6F 6C 65 00 FD FD FD FD ole..... ........
---------- Block 41 at 0x0000000052C07620: 67 bytes ----------
Call Stack:
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\stdenvp.c (127): my_application.exe!_setenvp + 0x27 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (223): my_application.exe!__tmainCRTStartup + 0x5 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (164): my_application.exe!mainCRTStartup
0x00000000FAF8167E (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x1A bytes
0x00000000FD8CC3F1 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x21 bytes
Data:
D0 75 C0 52 50 00 00 00 D0 96 C0 52 50 00 00 00 .u.RP... ...RP...
20 91 DD E1 F6 07 00 00 7E 00 00 00 02 00 00 00 ........ ~.......
0F 00 00 00 00 00 00 00 29 00 00 00 FD FD FD FD ........ ).......
53 79 73 74 65 6D 44 72 69 76 65 3D 43 3A 00 FD SystemDr ive=C:..
FD FD FD ........ ........
---------- Block 43 at 0x0000000052C07670: 65 bytes ----------
Call Stack:
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\stdenvp.c (127): my_application.exe!_setenvp + 0x27 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (223): my_application.exe!__tmainCRTStartup + 0x5 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (164): my_application.exe!mainCRTStartup
0x00000000FAF8167E (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x1A bytes
0x00000000FD8CC3F1 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x21 bytes
Data:
D0 96 C0 52 50 00 00 00 C0 76 C0 52 50 00 00 00 ...RP... .v.RP...
20 91 DD E1 F6 07 00 00 7E 00 00 00 02 00 00 00 ........ ~.......
0D 00 00 00 00 00 00 00 2B 00 00 00 FD FD FD FD ........ +.......
54 45 4D 50 3D 46 3A 5C 54 45 4D 50 00 FD FD FD TEMP=F:\ TEMP....
FD ........ ........
Visual Leak Detector detected 48 memory leaks (6044 bytes).
Largest number used: 15094 bytes.
Total allocations: 25276 bytes.
Visual Leak Detector is now exiting.
There are not much details about this on net however in this msdn forum a comment says:
That's not really a 'leak' so much as 'preparing your environment for
execution'. It's making a writable copy of the process's environment
for programs which expect it, and they will be released when the
process exits. You can safely ignore the report.
However, I want to suppress these lines from appearing it to report (If they genuinely are not leaks)
Has anyone experienced this and know how to sort out?
Easiest solution apparently is to add StartDisabled=yes in the vld.ini file and then explicitly enable it from the first line of main() . Sure, you'll also miss "memory leaks" from your global objects but that's usually equally harmless.
I found this was bug in VLD 2.3. Details of bug are here. I just downloaded v2.4rc2 (vld-2.4rc2-setup.exe) and this issue not seems appearing anymore. (I had downloaded v2.3 because it has been marked stable)

Compile code to raw binary

I'm trying to compile my code into raw binary and as suggested by other SO posts (like this and this) I tried objdump:
$ gcc -c foo.c
$ objcopy -O binary foo.o foo.bin
Then I tried to make sure if this is valid:
$ objdump -d foo.o
foo.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: 89 7d fc mov %edi,-0x4(%rbp)
b: 48 89 75 f0 mov %rsi,-0x10(%rbp)
f: bf 00 00 00 00 mov $0x0,%edi
14: b8 00 00 00 00 mov $0x0,%eax
19: e8 00 00 00 00 callq 1e <main+0x1e>
1e: b8 00 00 00 00 mov $0x0,%eax
23: c9 leaveq
24: c3 ret
$ hexdump -C foo.bin
00000000 14 00 00 00 00 00 00 00 01 7a 52 00 01 78 10 01 |.........zR..x..|
00000010 1b 0c 07 08 90 01 00 00 1c 00 00 00 1c 00 00 00 |................|
00000020 00 00 00 00 25 00 00 00 00 41 0e 10 86 02 43 0d |....%....A....C.|
00000030 06 60 0c 07 08 00 00 00 |.`......|
00000038
Evidently something is wrong. I checked this with the results of a gcc cross-compilation, with much the same obviously incorrect results.
You can pass -j .text to objcopy.

Trying to extract pixel values from a given PNG image

Trying to understand PNG format.
Consider this PNG Image:
The Image is taken from here
In Hex Editor , it looks like this:
89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 00 80 00 00 00 44 08 02 00 00 00
C6 25 AA 3E 00 00 00 C2 49 44 41 54 78 5E ED D4 81 06 C3 30 14 40 D1 B7 34 DD FF FF 6F
B3 74 56 EA 89 12 6C 28 73 E2 AA 34 49 03 87 D6 FE D8 7B 89 BB 52 8D 3B 87 FE 01 00 80
00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 04 00 80 00 00 10 00 00 02 00 40
00 00 08 00 00 01 00 20 00 00 00 D4 5E 6A 64 4B 94 F5 98 7C D1 F4 92 5C 5C 3E CF 9C 3F
73 71 58 5F AF 8B 79 5B EE 96 B6 47 EB F1 EA D1 CE B6 E3 75 3B E6 B9 95 8D C7 CE 03 39
C9 AF C6 33 93 7B 66 37 CF AB BF F9 C9 2F 08 80 00 00 10 00 00 02 00 40 00 00 08 00 00
01 00 20 00 00 04 00 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 8C 37 DB
68 03 20 FB ED 96 65 00 00 00 00 49 45 4E 44 AE 42 60 82
Equivalent characters:
‰PNG........IHDR...€...D.....Æ%ª>...ÂIDATx^íÔ..Ã0.#Ñ·4Ýÿÿo³tVê‰.l(sâª4I.‡ÖþØ{‰
»R.;‡þ..€.......#....... ....€.......#....... ...Ô^jdK”õ˜|Ñô’\\>Ïœ?sqX_¯
‹y[î–¶GëñêÑζãu;湕.ÇÎ.9ɯÆ3“{f7Ï«¿ùÉ/.€.......#....... ....€.......#....... ..Œ7Ûh.
ûí–e....IEND®B`‚
The same is shown in following Screenshot of the HEX Editor:
I am trying to reverse engineer this image to extract the header part and the RGB pixel values. I read about the PNG and also here , and so far I have noted the following about this Image:
The IHDR chunk must appear FIRST. It contains:
Width: 4 bytes
Height: 4 bytes
Bit depth: 1 byte
Color type: 1 byte
Compression method: 1 byte
Filter method: 1 byte
Interlace method: 1 byte
Below I am starting reading the HEX Data in sequence:
1- First 8-bytes: This is the 8-Byte signature
89 50 4E 47 0D 0A 1A 0A
Equivalently this is : %PNG as can be seen in HEX Editor
A valid PNG image must contain an IHDR chunk, one or more IDAT chunks, and an IEND chunk.
2- Chunk: Length
00 00 00 0D
3-Chunk: Chunk Type
49 48 44 52
Which is IHDR.
http://www.w3.org/TR/PNG-Chunks.html
4- Chunk: Width of the Image (in Decimal 128)
00 00 00 80
5- Chunk: Height of the image (in Decimal 68)
00 00 00 44
6- Chunk: BIT DEPTH (1 byte )
08
7- Chunk: Color Type
02
8- Compression method
00
9- Filter method:
00
10- Interlace method:
00
11- What is the following data?
C6 25 AA 3E 00 00 00 C2
12-- IDAT
49 44 41 54
13- What is this data (after IDAT):
78 5E ED D4 81 06 C3 30 14 40 D1 B7 34 DD FF FF 6F B3 74 56 EA 89 12 6C 28 73 E2 AA 34 49 03 87 D6 FE D8 7B 89 BB 52 8D 3B 87 FE 01 00 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 04 00 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 00 D4 5E 6A 64 4B 94 F5 98 7C D1 F4 92 5C 5C 3E CF 9C 3F 73 71 58 5F AF 8B 79 5B EE 96 B6 47 EB F1 EA D1 CE B6 E3 75 3B E6 B9 95 8D C7 CE 03 39 C9 AF C6 33 93 7B 66 37 CF AB BF F9 C9 2F 08 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 04 00 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 8C 37 DB 68 03 20 FB ED 96 65 00 00 00 00
14- IEND:
49 45 4E 44
15- Last 4 bytes
AE 42 60 82
What are these ?
Can some help me understand, points 11, 13 and 15 above? And where are the Pixel values? The Image is having (128 x 68 pixels)
Purpose of knowing these details:
Once I know these details, I will generate my own 16 bit PNG image. I already have pixel values, so my job would be to introduce headers etc.
I dont know if there is software that can perform this job.
UPDATE
I understand now because of compression, I would not be able to locate the pixel values.
I got the idea that I can write a file in OpenCV and save it as png. Well now my direct question is: I have a binary file having gray-scale 16 bit-pixel values. Can I write this in OpenCV as 16 bit PNG ?
Although it might be interesting to learn about what PNG Images actually are, and how the image is actually represented in the file, you don't need to know this to generate a PNG file.
Note that PNG uses lossless compression, which means you won't get two bytes per pixel.
You can generate your image in a program and output it in PNG format using many of the libraries that there are out there.
For example, you can make your image in OpenCV and then output it with imWrite. One of the parameters can make it output to a PNG.
If you have the gray-scale 16-bit pixel values, then you can put them into a Mat.
Then convert that to an IplImage: Converting cv::Mat to IplImage*
Then you can output it to a file.
Just for completeness (eboix's answer is right on the spot)
11- What is the following data?
C6 25 AA 3E 00 00 00 C2
Each chunk ends with a CRC (4 bytes), and starts with 4 bytes that tell its length.
So, C6 25 AA 3E is the CRC of the previous chunk (IHDR) and 00 00 00 C2 (194) is the length of the following (IDAT) chunk.
In the same way, the last 4 bytes is the CRC of the IEND chunk.
I did not look too carefully but from looking at the structure...
Q11.
C6 25 AA 3E = CRC32
00 00 00 C2 = Size of next chunk
Q13.
check the png spec's you referred to earlier that looks like the IDAT chunk you allready know the compression applied to it!
Q15.
AE 42 60 82 = CRC32

Resources