kolibrios/programs/develop/libraries/exif/trunk/exif.asm

418 lines
8.7 KiB
NASM
Raw Normal View History

format MS COFF
public EXPORTS
section '.flat' code readable align 16
include '../../../../macros.inc'
include '../../../../proc32.inc'
;---------
offs_m_or_i equ 8 ;ᬥ饭<E1ACA5><E9A5AD> <20><><EFBFBD><E0A0AC><EFBFBD><EFBFBD> 'MM' <20><><EFBFBD> 'II' (Motorola, Intel)
offs_tag_count equ 16 ;ᬥ饭<E1ACA5><E9A5AD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⢠ ⥣<><E2A5A3>
offs_tag_0 equ 18 ;ᬥ饭<E1ACA5><E9A5AD> 0-<2D><><>
tag_size equ 12 ;ࠧ<><E0A0A7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><>
;<3B><><EFBFBD><E0ACA0> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tag_format_ui1b equ 1 ;unsigned integer 1 byte
tag_format_text equ 2 ;ascii string
tag_format_ui2b equ 3 ;unsigned integer 2 byte
tag_format_ui4b equ 4 ;unsigned integer 4 byte
tag_format_urb equ 5 ;unsigned integer 4/4 byte
tag_format_si1b equ 6 ;signed integer 1 byte
tag_format_undef equ 7 ;undefined
tag_format_si2b equ 8 ;signed integer 2 byte
tag_format_si4b equ 9 ;signed integer 4 byte
tag_format_srb equ 10 ;signed integer 4/4 byte
tag_format_f4b equ 11 ;float 4 byte
tag_format_f8b equ 12 ;float 8 byte
align 4
txt_dp db ': ',0
txt_div db '/',0
;
align 4
exif_tag_numbers:
db 0x01,0x0e,'Image description',0
db 0x01,0x0f,'Manufacturer of digicam',0
db 0x01,0x10,'Model',0
db 0x01,0x12,'Orientation',0
db 0x01,0x1a,'X resolution',0
db 0x01,0x1b,'Y resolution',0
db 0x01,0x28,'Resolution unit',0
db 0x01,0x31,'Software',0
db 0x01,0x32,'Date time',0
db 0x01,0x3e,'White point',0
db 0x01,0x3f,'Primary chromaticities',0
db 0x02,0x11,'YCbCrCoefficients',0
db 0x02,0x13,'YCbCrPositioning',0
db 0x02,0x14,'Reference black white',0
db 0x82,0x98,'Copyright',0
db 0x87,0x69,'Exif offset',0
db 0x88,0x25,'GPS Info',0
db 0xa4,0x01,'Custom rendered',0
db 0xa4,0x02,'Exposure mode',0
db 0xa4,0x03,'White balance',0
db 0xa4,0x04,'Digital zoom ratio',0
db 0xa4,0x05,'Focal length in 35mm format',0
db 0xa4,0x06,'Scene capture type',0
db 0xa4,0x07,'Gain control',0
db 0xa4,0x08,'Contrast',0
db 0xa4,0x09,'Saturation',0
db 0xa4,0x0a,'Sharpness',0
db 0xa4,0x0b,'Device setting description',0
db 0xa4,0x0c,'Subject distance range',0
db 0xa4,0x20,'Image unique ID',0
db 0xa4,0x30,'Owner name',0
db 0xa4,0x31,'Serial number',0
db 0xa4,0x32,'Lens info',0
db 0xa4,0x33,'Lens make',0
db 0xa4,0x34,'Lens model',0
db 0xa4,0x35,'Lens serial number',0
db 0xa4,0x80,'GDAL metadata',0
db 0xa4,0x81,'GDAL no data',0
db 0xa5,0x00,'Gamma',0
db 0xaf,0xc0,'Expand software',0
db 0xaf,0xc1,'Expand lens',0
db 0xaf,0xc2,'Expand film',0
db 0xaf,0xc3,'Expand filterLens',0
db 0xaf,0xc4,'Expand scanner',0
db 0xaf,0xc5,'Expand flash lamp',0
db 0xea,0x1c,'Padding',0
dw 0
;input:
; bof - 㪠<><E3AAA0><EFBFBD> <20><> <20><><EFBFBD><><E4A0A9>
; app1 - 㪠<><E3AAA0><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> exif.app1
;output:
; app1 - 㪠<><E3AAA0><EFBFBD> <20><> <20><><EFBFBD> exif.app1 (<28><><EFBFBD> 0 <20><20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><><E4A0A9> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E0A6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
align 4
proc exif_get_app1 uses eax ebx edi, bof:dword, app1:dword
mov eax,[bof]
mov edi,[app1]
;䠩<> <20> <20><><EFBFBD><E0ACA0> jpg?
cmp word[eax],0xd8ff
jne .no_exif
add eax,2
;䠩<><><EFBFBD> exif.app0?
cmp word[eax],0xe0ff
jne @f
add eax,2
movzx ebx,word[eax]
ror bx,8 ;<3B><EFBFBD><E1A5A3> <20><><20><><EFBFBD><EFBFBD>?
add eax,ebx
@@:
;䠩<><><EFBFBD> exif.app1?
cmp word[eax],0xe1ff
jne .no_exif
add eax,2
mov [edi],eax
jmp @f
.no_exif:
mov dword[edi],0
@@:
ret
endp
;input:
; app1 - 㪠<><E3AAA0><EFBFBD> <20><> <20><><EFBFBD> exif.app1
; num - <20><><EFBFBD><EFBFBD><EFA4AA><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><> (<28><><EFBFBD><E7A8AD><EFBFBD><EFBFBD><EFBFBD> <20> 1)
; txt - 㪠<><E3AAA0><EFBFBD> <20><><><E2A5AA>, <20><20><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E7A5AD>
; t_max - <20><><EFBFBD><EFBFBD><E1A8AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E0A0A7><EFBFBD><><E2A5AA><EFBFBD>
align 4
proc exif_get_app1_tag, app1:dword, num:dword, txt:dword, t_max:dword
pushad
mov eax,[app1]
mov edi,[txt]
mov ecx,[num]
xor edx,edx
cmp eax,edx
je .end_f ;<3B><20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E3AAA0><EFBFBD> <20><> <20><><EFBFBD> exif.app1
cmp ecx,edx
jle .end_f ;<3B><20><><EFBFBD><EFBFBD><EFA4AA><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><> <= 0
mov byte[edi],0
cmp word[eax+offs_m_or_i],'II'
je @f
inc edx ;if 'MM' edx=1
@@:
;<3B><EFBFBD><E0AEA2><20><>᫮ ⥣<><E2A5A3>
movzx ebx,word[eax+offs_tag_count]
bt edx,0
jnc @f
ror bx,8
@@:
cmp ecx,ebx
jg .end_f ;<3B><20><><EFBFBD><EFBFBD><EFBFBD><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><20><> <20><><EFBFBD><EFBFBD> <20><><E4A0A9>
;<3B><><EFBFBD><EFBFBD><EFBFBD><E5AEA4> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
dec ecx
imul ecx,tag_size
add eax,offs_tag_0
add eax,ecx
;<3B><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E7A5AD><>
push exif_tag_numbers
pop esi
.next_tag:
mov bx,word[esi]
cmp bx,0
je .tag_unknown ;⥣ <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bt edx,0
jc @f
ror bx,8
@@:
cmp word[eax],bx
je .found
inc esi
@@:
inc esi
cmp byte[esi],0
jne @b
inc esi
jmp .next_tag
.found:
;<3B><><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD>
add esi,2
stdcall str_n_cat,edi,esi,[t_max]
jmp @f
.tag_unknown:
mov dword[edi],'???'
mov byte[edi+3],0
@@:
;<3B><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><E0ACA0><EFBFBD> <20><>
mov bx,tag_format_text
bt edx,0
jnc @f
ror bx,8
@@:
cmp word[eax+2],bx
jne .tag_02
stdcall str_n_cat,edi,txt_dp,[t_max]
call get_tag_data_size ;<3B><EFBFBD><E0AEA2><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
cmp ebx,4
jg @f
;<3B><20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><E9A0A5><EFBFBD> <20> 4 ᨬ<><E1A8AC><EFBFBD><EFBFBD>
mov esi,eax
add esi,8
stdcall str_n_cat,edi,esi,[t_max]
jmp .end_f
;<3B><20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><E9A0A5><EFBFBD> <20> 4 ᨬ<><E1A8AC><EFBFBD><EFBFBD>
@@:
mov esi,dword[eax+8]
bt edx,0
jnc @f
ror si,8
ror esi,16
ror si,8
@@:
add esi,offs_m_or_i
add esi,[app1]
stdcall str_n_cat,edi,esi,[t_max]
jmp .end_f
.tag_02:
mov bx,tag_format_ui2b
bt edx,0
jnc @f
ror bx,8
@@:
cmp word[eax+2],bx
jne .tag_03
stdcall str_n_cat,edi,txt_dp,[t_max]
call get_tag_data_size
cmp ebx,1
jg .over4b_03
;<3B><20><><EFBFBD><EFBFBD> 2 <20><><EFBFBD><EFBFBD><E2AEA2> <20><>
movzx ebx,word[eax+8]
bt edx,0
jnc @f
ror bx,8
@@:
stdcall str_len,edi
add edi,eax
mov eax,ebx
call convert_int_to_str ;[t_max]
.over4b_03:
;...
jmp .end_f
.tag_03:
mov bx,tag_format_ui4b
bt edx,0
jnc @f
ror bx,8
@@:
cmp word[eax+2],bx
jne .tag_04
stdcall str_n_cat,edi,txt_dp,[t_max]
call get_tag_data_size
cmp ebx,1
jg .over4b_04
;<3B><20><><EFBFBD><EFBFBD> 4 <20><><EFBFBD><EFBFBD><E2AEA2> <20><>
mov ebx,dword[eax+8]
bt edx,0
jnc @f
ror bx,8
ror ebx,16
ror bx,8
@@:
stdcall str_len,edi
add edi,eax
mov eax,ebx
call convert_int_to_str ;[t_max]
.over4b_04:
;...
jmp .end_f
.tag_04:
mov bx,tag_format_urb
bt edx,0
jnc @f
ror bx,8
@@:
cmp word[eax+2],bx
jne .tag_05
stdcall str_n_cat,edi,txt_dp,[t_max]
;call get_tag_data_size
;cmp ebx,1
;jg .over4b_05
mov ebx,dword[eax+8]
bt edx,0
jnc @f
ror bx,8
ror ebx,16
ror bx,8
@@:
stdcall str_len,edi
add edi,eax
add ebx,offs_m_or_i
add ebx,[app1]
mov eax,[ebx]
bt edx,0
jnc @f
ror ax,8
ror eax,16
ror ax,8
@@:
call convert_int_to_str ;<3B><EFBFBD><E2A0A2> 1-<2D> <20><>
stdcall str_n_cat,edi,txt_div,[t_max] ;<3B><EFBFBD><E2A0A2> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
stdcall str_len,edi
add edi,eax
mov eax,[ebx+4]
bt edx,0
jnc @f
ror ax,8
ror eax,16
ror ax,8
@@:
call convert_int_to_str ;<3B><EFBFBD><E2A0A2> 2-<2D> <20><>
;.over4b_05:
;...
;jmp .end_f
.tag_05:
.end_f:
popad
ret
endp
;input:
; eax - tag pointer
; edx - 1 if 'MM', 0 if 'II'
;output:
; ebx - data size
align 4
get_tag_data_size:
mov ebx,dword[eax+4]
bt edx,0
jnc @f
ror bx,8
ror ebx,16
ror bx,8
@@:
ret
align 4
proc str_n_cat uses eax ecx edi esi, str1:dword, str2:dword, n:dword
mov esi,dword[str2]
mov ecx,dword[n]
mov edi,dword[str1]
stdcall str_len,edi
add edi,eax
cld
repne movsb
mov byte[edi],0
ret
endp
;output:
; eax = strlen
align 4
proc str_len, str1:dword
mov eax,[str1]
@@:
cmp byte[eax],0
je @f
inc eax
jmp @b
@@:
sub eax,[str1]
ret
endp
;input:
; eax = value
; edi = string buffer
;output:
align 4
convert_int_to_str:
pushad
mov dword[edi+1],0
mov dword[edi+5],0
call .str
popad
ret
align 4
.str:
mov ecx,0x0a ;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E1ABA5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E0A5A3><EFBFBD><EFBFBD><EFBFBD> ebx,eax,ecx,edx <20><EFBFBD><E5AEA4><EFBFBD> <20><><EFBFBD><E0A0AC><EFBFBD><EFBFBD> eax - <20><>
;<3B><><EFBFBD><EFBFBD><E0A5A2> <20><><20> ASCII <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ecx=<3D><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E1ABA5> edi <20><><EFBFBD><EFBFBD><EFBFBD> <20><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBA2A0>, <20><EFBFBD> <20><><EFBFBD>, <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><E0A5AC><EFBFBD><EFBFBD><EFBFBD>
cmp eax,ecx ;<3B><EFBFBD><E0A0A2><EFBFBD><EFBFBD> <20><20> eax <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><20> ecx <20><> <20><><EFBFBD><E0A5A9> <20><> @@-1 <20>.<2E>. <20><> pop eax
jb @f
xor edx,edx ;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> edx
div ecx ;ࠧ<><E0A0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><20> edx
push edx ;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20>
;dec edi ;ᬥ饭<E1ACA5><E9A5AD> <20><><EFBFBD><EFBFBD><EFBFBD><E5AEA4><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
call .str ;<3B><><EFBFBD><E0A5A9> <20><><><> <20>.<2E>. <20><EFBFBD><EBA7A2><EFBFBD><><> <20><20><><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20> eax <20><> <20><EFBFBD><E2A0AD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><20> ecx
pop eax
@@: ;cmp al,10 ;<3B><EFBFBD><E0AEA2><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><E7A5AD> <20> al 祬 10 (<28><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E1ABA5> 10 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD>))
or al,0x30 ;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD> <20><><EFBFBD><EFBFBD>
stosb ;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><><E0A5A3><EFBFBD><EFBFBD><EFBFBD> al <20> <20><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> es:edi
ret ;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><20>.<2E>. <20><><EFBFBD><EFBFBD> <20> <20><EFBFBD> <20><EFBFBD><E0A0AD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>-<2D><> <20><EFBFBD><EBA7AE><EFBFBD> <20><> <20>⮫쪮 ࠧ <20><> <20> <20><EFBFBD> <20><><EFBFBD><EFBFBD><EBA2A0><EFBFBD><EFBFBD>
align 16
EXPORTS:
dd sz_exif_get_app1, exif_get_app1
dd sz_exif_get_app1_tag, exif_get_app1_tag
dd 0,0
sz_exif_get_app1 db 'exif_get_app1',0
sz_exif_get_app1_tag db 'exif_get_app1_tag',0