Subversion Repositories Kolibri OS

Rev

Rev 4994 | Rev 5002 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4994 IgorA 1
format MS COFF
2
public EXPORTS
3
section '.flat' code readable align 16
4
 
5
include '../../../../macros.inc'
6
include '../../../../proc32.inc'
7
 
8
 
9
 
10
;---------
11
offs_m_or_i    equ 8 ;смещение параметра 'MM' или 'II' (Motorola, Intel)
12
offs_tag_count equ 16 ;смещение количества тегов
13
offs_tag_0     equ 18 ;смещение 0-го тега
14
tag_size       equ 12 ;размер структуры тега
15
;форматы данных
16
tag_format_ui1b  equ  1 ;unsigned integer 1 byte
17
tag_format_text  equ  2 ;ascii string
18
tag_format_ui2b  equ  3 ;unsigned integer 2 byte
19
tag_format_ui4b  equ  4 ;unsigned integer 4 byte
4995 IgorA 20
tag_format_urb   equ  5 ;unsigned integer 4/4 byte
4994 IgorA 21
tag_format_si1b  equ  6 ;signed integer 1 byte
22
tag_format_undef equ  7 ;undefined
23
tag_format_si2b  equ  8 ;signed integer 2 byte
24
tag_format_si4b  equ  9 ;signed integer 4 byte
4995 IgorA 25
tag_format_srb   equ 10 ;signed integer 4/4 byte
4994 IgorA 26
tag_format_f4b	 equ 11 ;float 4 byte
27
tag_format_f8b	 equ 12 ;float 8 byte
28
 
29
align 4
30
txt_dp db ': ',0
4995 IgorA 31
txt_div db '/',0
4994 IgorA 32
 
33
;
34
align 4
35
exif_tag_numbers:
36
 
37
db 0x01,0x0e,'Image description',0
38
db 0x01,0x0f,'Manufacturer of digicam',0
39
db 0x01,0x10,'Model',0
40
db 0x01,0x12,'Orientation',0
41
db 0x01,0x1a,'X resolution',0
42
db 0x01,0x1b,'Y resolution',0
43
db 0x01,0x28,'Resolution unit',0
44
db 0x01,0x31,'Software',0
45
db 0x01,0x32,'Date time',0
46
db 0x01,0x3e,'White point',0
47
db 0x01,0x3f,'Primary chromaticities',0
48
db 0x02,0x11,'YCbCrCoefficients',0
49
db 0x02,0x13,'YCbCrPositioning',0
50
db 0x02,0x14,'Reference black white',0
51
db 0x82,0x98,'Copyright',0
52
db 0x87,0x69,'Exif offset',0
53
 
54
db 0x88,0x25,'GPS Info',0
55
 
4995 IgorA 56
db 0xa4,0x01,'Custom rendered',0
57
db 0xa4,0x02,'Exposure mode',0
58
db 0xa4,0x03,'White balance',0
59
db 0xa4,0x04,'Digital zoom ratio',0
60
db 0xa4,0x05,'Focal length in 35mm format',0
61
db 0xa4,0x06,'Scene capture type',0
62
db 0xa4,0x07,'Gain control',0
63
db 0xa4,0x08,'Contrast',0
64
db 0xa4,0x09,'Saturation',0
65
db 0xa4,0x0a,'Sharpness',0
66
db 0xa4,0x0b,'Device setting description',0
67
db 0xa4,0x0c,'Subject distance range',0
68
db 0xa4,0x20,'Image unique ID',0
69
db 0xa4,0x30,'Owner name',0
70
db 0xa4,0x31,'Serial number',0
71
db 0xa4,0x32,'Lens info',0
72
db 0xa4,0x33,'Lens make',0
73
db 0xa4,0x34,'Lens model',0
74
db 0xa4,0x35,'Lens serial number',0
75
db 0xa4,0x80,'GDAL metadata',0
76
db 0xa4,0x81,'GDAL no data',0
77
db 0xa5,0x00,'Gamma',0
78
db 0xaf,0xc0,'Expand software',0
79
db 0xaf,0xc1,'Expand lens',0
80
db 0xaf,0xc2,'Expand film',0
81
db 0xaf,0xc3,'Expand filterLens',0
82
db 0xaf,0xc4,'Expand scanner',0
83
db 0xaf,0xc5,'Expand flash lamp',0
84
 
85
db 0xea,0x1c,'Padding',0
4994 IgorA 86
dw 0
87
 
88
 
89
;input:
90
; bof - указатель на начало файла
91
; app1 - указатель для заполнения exif.app1
92
;output:
93
; app1 - указатель на начало exif.app1 (или 0 если не найдено или формат файла не поддерживается)
94
align 4
95
proc exif_get_app1 uses eax ebx edi, bof:dword, app1:dword
96
	mov eax,[bof]
97
	mov edi,[app1]
98
 
99
	;файл в формате jpg?
100
	cmp word[eax],0xd8ff
101
	jne .no_exif
102
	add eax,2
103
 
104
	;файл содержит exif.app0?
105
	cmp word[eax],0xe0ff
106
	jne @f
107
		add eax,2
108
		movzx ebx,word[eax]
109
		ror bx,8 ;всегда ли так надо?
110
		add eax,ebx
111
	@@:
112
 
113
	;файл содержит exif.app1?
114
	cmp word[eax],0xe1ff
115
	jne .no_exif
116
 
117
	add eax,2
118
	mov [edi],eax
119
 
120
	jmp @f
121
	.no_exif:
122
		mov dword[edi],0
123
	@@:
124
	ret
125
endp
126
 
127
;input:
128
; app1 - указатель на начало exif.app1
129
; num - порядковый номер тега (начинается с 1)
130
; txt - указатель на текст, куда будет записано значение
131
; t_max - максимальный размер текста
132
align 4
133
proc exif_get_app1_tag, app1:dword, num:dword, txt:dword, t_max:dword
134
pushad
135
	mov eax,[app1]
136
	mov edi,[txt]
137
	mov ecx,[num]
138
 
139
	xor edx,edx
140
	cmp eax,edx
141
	je .end_f ;если не найден указатель на начало exif.app1
142
	cmp ecx,edx
143
	jle .end_f ;если порядковый номер тега <= 0
144
 
145
	mov byte[edi],0
146
	cmp word[eax+offs_m_or_i],'II'
147
	je @f
148
		inc edx ;if 'MM' edx=1
149
	@@:
150
 
151
	;проверяем число тегов
152
	movzx ebx,word[eax+offs_tag_count]
153
	bt edx,0
154
	jnc @f
155
		ror bx,8
156
	@@:
157
	cmp ecx,ebx
158
	jg .end_f ;если номер тега больше чем их есть в файле
159
 
160
	;переходим на заданный тег
161
	dec ecx
162
	imul ecx,tag_size
163
	add eax,offs_tag_0
164
	add eax,ecx
165
 
166
	;читаем назначение тега
167
	push exif_tag_numbers
168
	pop esi
169
	.next_tag:
170
	mov bx,word[esi]
171
	cmp bx,0
172
	je .tag_unknown ;тег не опознан
173
	bt edx,0
174
	jc @f
175
		ror bx,8
176
	@@:
177
	cmp word[eax],bx
178
	je .found
179
	inc esi
180
	@@:
181
		inc esi
182
		cmp byte[esi],0
183
		jne @b
184
	inc esi
185
	jmp .next_tag
186
	.found:
187
 
188
	;копируем строку
189
	add esi,2
190
	stdcall str_n_cat,edi,esi,[t_max]
191
 
4995 IgorA 192
	jmp @f
193
	.tag_unknown:
194
		mov dword[edi],'???'
195
		mov byte[edi+3],0
196
	@@:
197
 
4994 IgorA 198
	;читаем информацию в теге
199
	mov bx,tag_format_text
200
	bt edx,0
201
	jnc @f
202
		ror bx,8
203
	@@:
204
	cmp word[eax+2],bx
205
	jne .tag_02
206
		stdcall str_n_cat,edi,txt_dp,[t_max]
4995 IgorA 207
		call get_tag_data_size ;проверяем длинну строки
4994 IgorA 208
		cmp ebx,4
209
		jg @f
210
			;если строка помещается в 4 символа
211
			mov esi,eax
212
			add esi,8
213
			stdcall str_n_cat,edi,esi,[t_max]
214
			jmp .end_f
215
		;если строка не помещается в 4 символа
216
		@@:
217
		mov esi,dword[eax+8]
218
		bt edx,0
219
		jnc @f
220
			ror si,8
221
			ror esi,16
222
			ror si,8
223
		@@:
224
		add esi,offs_m_or_i
225
		add esi,[app1]
226
		stdcall str_n_cat,edi,esi,[t_max]
4995 IgorA 227
		jmp .end_f
4994 IgorA 228
	.tag_02:
229
 
4995 IgorA 230
	mov bx,tag_format_ui2b
231
	bt edx,0
232
	jnc @f
233
		ror bx,8
234
	@@:
235
	cmp word[eax+2],bx
236
	jne .tag_03
237
		stdcall str_n_cat,edi,txt_dp,[t_max]
238
		call get_tag_data_size
239
		cmp ebx,1
240
		jg .over4b_03
241
			;если одно 2 байтовое число
242
			movzx ebx,word[eax+8]
243
			bt edx,0
244
			jnc @f
245
				ror bx,8
246
			@@:
247
			stdcall str_len,edi
248
			add edi,eax
249
			mov eax,ebx
250
			call convert_int_to_str ;[t_max]
251
		.over4b_03:
252
			;...
253
		jmp .end_f
254
	.tag_03:
255
 
256
	mov bx,tag_format_ui4b
257
	bt edx,0
258
	jnc @f
259
		ror bx,8
260
	@@:
261
	cmp word[eax+2],bx
262
	jne .tag_04
263
		stdcall str_n_cat,edi,txt_dp,[t_max]
264
		call get_tag_data_size
265
		cmp ebx,1
266
		jg .over4b_04
267
			;если одно 4 байтовое число
268
			mov ebx,dword[eax+8]
269
			bt edx,0
270
			jnc @f
271
				ror bx,8
272
				ror ebx,16
273
				ror bx,8
274
			@@:
275
			stdcall str_len,edi
276
			add edi,eax
277
			mov eax,ebx
278
			call convert_int_to_str ;[t_max]
279
		.over4b_04:
280
			;...
281
		jmp .end_f
282
	.tag_04:
283
 
284
	mov bx,tag_format_urb
285
	bt edx,0
286
	jnc @f
287
		ror bx,8
288
	@@:
289
	cmp word[eax+2],bx
290
	jne .tag_05
291
		stdcall str_n_cat,edi,txt_dp,[t_max]
292
		;call get_tag_data_size
293
		;cmp ebx,1
294
		;jg .over4b_05
295
			mov ebx,dword[eax+8]
296
			bt edx,0
297
			jnc @f
298
				ror bx,8
299
				ror ebx,16
300
				ror bx,8
301
			@@:
302
			stdcall str_len,edi
303
			add edi,eax
304
			add ebx,offs_m_or_i
305
			add ebx,[app1]
306
			mov eax,[ebx]
307
			bt edx,0
308
			jnc @f
309
				ror ax,8
310
				ror eax,16
311
				ror ax,8
312
			@@:
313
			call convert_int_to_str ;ставим 1-е число
314
			stdcall str_n_cat,edi,txt_div,[t_max] ;ставим знак деления
315
			stdcall str_len,edi
316
			add edi,eax
317
			mov eax,[ebx+4]
318
			bt edx,0
319
			jnc @f
320
				ror ax,8
321
				ror eax,16
322
				ror ax,8
323
			@@:
324
			call convert_int_to_str ;ставим 2-е число
325
		;.over4b_05:
326
			;...
327
		;jmp .end_f
328
	.tag_05:
329
 
4994 IgorA 330
	.end_f:
331
popad
332
	ret
333
endp
334
 
4995 IgorA 335
;input:
336
; eax - tag pointer
337
; edx - 1 if 'MM', 0 if 'II'
338
;output:
339
; ebx - data size
4994 IgorA 340
align 4
4995 IgorA 341
get_tag_data_size:
342
	mov ebx,dword[eax+4]
343
	bt edx,0
344
	jnc @f
345
		ror bx,8
346
		ror ebx,16
347
		ror bx,8
348
	@@:
4994 IgorA 349
	ret
350
 
351
align 4
352
proc str_n_cat uses eax ecx edi esi, str1:dword, str2:dword, n:dword
353
	mov esi,dword[str2]
354
	mov ecx,dword[n]
355
	mov edi,dword[str1]
356
	stdcall str_len,edi
357
	add edi,eax
358
	cld
359
	repne movsb
360
	mov byte[edi],0
361
	ret
362
endp
363
 
364
;output:
365
; eax = strlen
366
align 4
367
proc str_len, str1:dword
368
	mov eax,[str1]
369
	@@:
370
		cmp byte[eax],0
371
		je @f
372
		inc eax
373
		jmp @b
374
	@@:
375
	sub eax,[str1]
376
	ret
377
endp
378
 
4995 IgorA 379
;input:
380
; eax = value
381
; edi = string buffer
382
;output:
383
align 4
384
convert_int_to_str:
385
	pushad
386
		mov dword[edi+1],0
387
		mov dword[edi+5],0
388
		call .str
389
	popad
390
	ret
391
 
392
align 4
393
.str:
394
	mov ecx,0x0a ;задается система счисления изменяются регистры ebx,eax,ecx,edx входные параметры eax - число
395
    ;преревод числа в ASCII строку взодные данные ecx=система счисленя edi адрес куда записывать, будем строку, причем конец переменной
396
	cmp eax,ecx  ;сравнить если в eax меньше чем в ecx то перейти на @@-1 т.е. на pop eax
397
	jb @f
398
		xor edx,edx  ;очистить edx
399
		div ecx      ;разделить - остаток в edx
400
		push edx     ;положить в стек
401
		;dec edi             ;смещение необходимое для записи с конца строки
402
		call .str ;перейти на саму себя т.е. вызвать саму себя и так до того момента пока в eax не станет меньше чем в ecx
403
		pop eax
404
	@@: ;cmp al,10 ;проверить не меньше ли значение в al чем 10 (для системы счисленя 10 данная команда - лишная))
405
	or al,0x30  ;данная команда короче  чем две выше
406
	stosb	    ;записать элемент из регистра al в ячеку памяти es:edi
407
	ret	      ;вернуться чень интересный ход т.к. пока в стеке храниться кол-во вызовов то столько раз мы и будем вызываться
408
 
409
 
410
 
4994 IgorA 411
align 16
412
EXPORTS:
413
	dd sz_exif_get_app1, exif_get_app1
414
	dd sz_exif_get_app1_tag, exif_get_app1_tag
415
	dd 0,0
416
	sz_exif_get_app1 db 'exif_get_app1',0
417
	sz_exif_get_app1_tag db 'exif_get_app1_tag',0