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=> |