Форум программистов, компьютерный форум, киберфорум
Программирование мультимедиа
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/22: Рейтинг темы: голосов - 22, средняя оценка - 4.77
0 / 0 / 0
Регистрация: 14.05.2011
Сообщений: 4
1

Формат PCX. Конвертация в BMP

14.05.2011, 18:12. Показов 4315. Ответов 9
Метки pcx (Все метки)

Author24 — интернет-сервис помощи студентам
Приветствую. Возникла задача для курсового - написать конвертер 256-цветных PCX изображений в 256-цветные BMP. И появились вопросы.
Согласно спецификации на формат (например здесь) - в конце файла располагается палитра (768 байт). Во-первых, во всех 256-цветных PCX-файлах, которые я получал через графические редакторы и конверторы палитра эта напрочь отсутствует, хоть и по всем признакам она должна быть. во-вторых, поскольку изображение трехслойное (NPlanes=3), то фактически на каждый пиксель приходится 3 байта, а не 1 (а BitPerPixel=8) назначение палитры там вобще непонятно.
Вот необходимо как-то раздобыть и конвертировать палитру.

Есть мысль составлять палитру по считанным данным, но лень (все таки на ассемблере пишу). Скорее всего так и делал бы, но вдруг а) окажется не позаданию (в материалах к курсовому прописано, что палитра в конце PCX-файла есть) б) что-то накосячу.

Сталкивался кто-нибудь с такой задачей ?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.05.2011, 18:12
Ответы с готовыми решениями:

Конвертация BMP в свой формат
Стоит задача сделать собственный формат изображения. Собственный формат предполагает создание...

Код конвертации форматов PCX GIF, TIFF в BMP
Доброго времени. Подскажите пожалуйста код конвертации форматов PCX GIF, TIFF в BMP в программной ...

Конвертация bmp в png
есть изображение созданое путём Graphics::TBitmap *Bitmap=new Graphics::TBitmap; надо...

Конвертация из bmp в png
Всем здравствуйте.:senor: Возник вопрос по поводу использования библиотек gdiplus.h. В MSDN есть...

9
6 / 9 / 2
Регистрация: 21.05.2011
Сообщений: 81
27.05.2011, 05:00 2
загрузчик вмп формата на бейсике писал

вмп имеет недокументированные возможности
если я не ошибаюсь

по этим свойствам пришлось дешифратр написать к открывалке картинки

а псх формат простой наверно палитра там стандартная
просто не помню точно этот формат.

Добавлено через 3 минуты
вы сами ответили на свой вопрос
просто это формат экстендед
pcx

там используется труекорольный стиль описания пикселя
поэтому филтр сделате из него получите палитровые 768 байт

Добавлено через 1 минуту
не ленитесь
потрудитесь

без труда на хлеб не найдешь

вообщем вы знаете что делать.

Добавлено через 3 минуты
план такой

1.сортировка \\сколько цветов файле есть?
2.если цветов 256 то делаем палитру
рисуем сохраняем конвертируем файл
нет пишем сообщение файл другого формата
1
0 / 0 / 0
Регистрация: 14.05.2011
Сообщений: 4
27.05.2011, 22:41  [ТС] 3
Спасибо. А программу уже написал этим же и способом. Осталось лаг с выравниванием убрать, но это мелочи.
PCX сложнее BMP будет. В первом пусть и простой, но метод сжатия присутствует и выравнивание более сложное идет.
0
6 / 9 / 2
Регистрация: 21.05.2011
Сообщений: 81
28.05.2011, 08:40 4
1:22 28.05.2011//
/author=velvet1545@mail.ru

бмп2 бмп16 бмп256 бмп16мил
4 разных алгоритма дешифрации цветного потока
про это узнал когда экспериментировал
с реальными файлами из редактора
хэлп по бмп формату внимательно читал
но не нашел схем расшифровки
к 16 и 256 цветному файлам бмп

собственно сам.....

этот хэлп придется переписывать дотошному автору.
чтоб студентов не путать лишний раз

а дат формат лучше всего потомучто проще

но по идее
я даже нарыл в инете описание примитивное опять по jpg
но не сохранил в папке тогда и не распечатал на принтере

поэтому так в то время и не написал распаковщик jpg файла
в дат 16mlncolors

щас за пару часов написал вьюер для бмп и jpg
мечта досовская на винде быстрей исполняется

даже любой новичок это сможет
если у него под рукой какойнибудь язык с хорошими библиотеками
1:39 28.05.2011\\
0
6 / 9 / 2
Регистрация: 21.05.2011
Сообщений: 81
28.05.2011, 09:00 5
просмотрщик графических файлов
написан за 2 часа на blitzbasic

в каталог bmppic
добавьте какие надо посмотреть
картинки формата jpg bmp

по умолчанию в папке находятся слоны
вобщем биология ботаника...

их можно также куданибудь переместить
клавишами 1-9 задается скорость смены картинки

правый клик мыши останавливает прогу
левый переключает в режим норесайз и обратно...
Вложения
Тип файла: rar viewerjpg.rar (2.69 Мб, 87 просмотров)
0
6 / 9 / 2
Регистрация: 21.05.2011
Сообщений: 81
28.05.2011, 09:01 6
уточнение:
режим норесайз в стадии разработки...
0
0 / 0 / 0
Регистрация: 14.05.2011
Сообщений: 4
28.05.2011, 14:21  [ТС] 7
А я на енотах все тестирую обычно
Ну на ЯВУ проблем особо нет с отображением картинок..
0
6 / 9 / 2
Регистрация: 21.05.2011
Сообщений: 81
28.05.2011, 14:33 8
14:28 28.05.2011\\

ну это на мышах надо
таковы традиции ученых

но я из любой мухи делаю слонов...

14:28 28.05.2011//
0
Andrew1990.
10.06.2011, 01:04 9
NightWizard, доброго времени суток!
А можно как-нибудь увидеть то, что получилось в итоге?
0 / 0 / 0
Регистрация: 14.05.2011
Сообщений: 4
11.06.2011, 00:51  [ТС] 10
Можно, но есть определенные лаги иногда
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
stk segment stack
db 256 dup ('?')
stk ends
data segment para public 'data'
 
PCXName db 255,255 dup (?) ; буфер для строки, хранящей имя файла
BMPName db 255,255 dup (?) ; буфер для строки, хранящей имя файла
; строки сообщений, которые будут выводиться на экран
Prompt1 db 'PCX File: $'
Prompt2 db 0ah,0dh,'BMP File: $'
OFE db 0ah,0dh,'Open File Error ',0ah,0dh,'$'      
NotPCX db 0ah,0dh,'File Is Not PCX-Image',0ah,0dh,'$'
Not256 db 0ah,0dh,'File Is Not 256-colors PCX',0ah,0dh,'$'
RE db 0ah,0dh,'Read error',0ah,0dh,'$'  
СNСFMsg db 0ah,0dh,'Could Not Create File',0ah,0dh,'$'
; заголовок PCX
Manufacturer db ? ; Постоянный флаг 10 = ZSoft .PCX
Version db ? ; Информация о версии
Encoding db ? ; 1 = PCX кодирование длинными сериями
BitsPerPixel db ? ; кол-во бит на пиксель
WindowXmin dw ? ; верхняя левая граница изображения
WindowYmin dw ? 
WindowXmax dw ? ; правая нижняя граница изображения
WindowYmax dw ?
Hres dw ? ; горизонтальное разрешение
Vres dw ? ; вертикальное разрешение
Colormap db 48 dup (?) ; информация о палитре
Reserved db ? ; зарезервировано
NPlanes db ? ; кол-во цветовых слоев
BytesPerLine dw ? ; кол-во байт на 1 цветовой слой ( ширина + байты для выравнивания)
PaletteInfo dw ? ; как интерпретировать палитру
Filler db 58 dup(?) ; нули
PCXHeaderSize equ $-Manufacturer
; заголовок BMP
bfType db 'BM' ; информация о типе файла
bfSize dd ? ; размер самого файла в байтах
bfReserved1 dw 0 ; нули
bfReserved2 dw 0 ; нули
bfOffBits dd ? ; смещение относительно начала файла на битовый массив растра
BMPHeaderSize equ $-bfType ; размер заголовка
 
 
; BITMAPINFOHEADER
biSize dd BMPInfoHeaderSize ; размер структуры BITMAPINFOHEADER
biWidth dd ? ; ширина изображения
biHeight dd ? ; высота изображения
biPlanes dw 1 ; количество плоскостей
biBitCount dw 8 ; кол-во бит на пиксель
biCompression dd 0 ; тип сжатия
biSizeImage dd ? ; размер изображения в байтах
biXPelsPerMeter dd ? ; горизонтальное разрешение
biYPelsPerMeter dd ? ; вертикльное разрешение
biClrUsed dd 256 ; текущее число цветов графического движка
biClrImportant dd ? ; кол-во важных цветов
BMPInfoHeaderSize equ $-biSize ;размер структуры BITMAPINFOHEADER   
 
 
BMPPallete db 1024 dup(0) ; буфер для палитры BMP
BMPPalleteSize equ 1024 ; фиксированный размер палитры
ColorsCount dw 0 ; переменная для хранения кол-ва цветов в документе
 
AdditiveBytes db 0 ; кол-во байт для выравнивания в PCX
 
PCXDescr dw ? ; дескриптор файла PCX
BMPDescr dw ? ; дескриптор файла BMP
 
ArraySize dw ? ; переменная для хранения кол-ва байт в запакованном растре PCX
CurByte dw 0 ; переменная, хранит номер следующего байта в растре bmp
 
; переменные для хранения текущих значений составляющих R, G и B
CurR db ?
CurG db ?
CurB db ?
PackedArray db 60000 dup (?) ; буфер, в который считается запакованный растр PCX
data ends
 
; сегмент для хранения распакованного растра PCX
MemoryBuf segment para public 'data'
    db 65535 dup (?)
MemoryBuf ends
; сегмент для хранения растра BMP
Bitmap segment para public 'data'
    db 65535 dup (0)
Bitmap ends
 
code segment para public 'code'
main proc
    assume cs:code,ds:data,ss:stk,es:MemoryBuf
    mov ax,data
    mov ds,ax
    mov ax,MemoryBuf
    mov es,ax
    
    jmp Start ; переходим на начало программы
 
; сообщения об ошибках
FileNotFound: ; если файл не найден
    mov ah,09
    mov dx, offset OFE
    int 21h
    jmp ExitProg
 
ReadErr: ; если ошибка чтения из файла
    ;call CloseFile
    mov ah,09
    lea dx,RE
    int 21h
    jmp ExitProg
 
 
 
 
 
Start:
    
    ; ввод строки имени исходного PCX-файла
    push offset PCXName
    push offset Prompt1
    call GetFileName ; введем строку и приведем ее к требуемому виду
    
    ; ввод строки имени выходного BMP-файла
    push offset BMPName
    push offset Prompt2
    call GetFileName ; введем строку и приведем ее к требуемому виду
    
    ; Откроем файл
    lea dx,PCXName
    mov ah,3dh ; ф-ия для открытия файла
    xor al,al ; режим - чтение
    add dx,2 ; перейдем на начало строки
    int 21h; открыть файл
    jc FileNotFound ; если ошибка, то сообщим об этом
    
    mov PCXDescr,ax ; сохраним дескриптор открытого файла
    mov bx,ax
    
    ; Читаем заголовок
    mov ah,3fh; ф-ия для чтения из файла
    lea dx,Manufacturer ; адрес на начала буфера
    mov cx,PCXHeaderSize; размер заголовка
    int 21h  
    jc ReadErr
    
    ; проверка соответствия файла формату PCX
    CheckPCX:
    
    ; проверка записи о формате 
    mov ah,Manufacturer
    cmp ah,10
    je PCXVersionCheck ; если все верно, то дальше проверяем
    push word ptr PCXDescr ; если нет, то закрываем файл, печатаем сообщение об ошибке и выходим из программы
    call Close
    mov ah,09
    lea dx,NotPCX
    int 21h
    jmp ExitProg
    
    ; проверка соотвтетствия версии формата
    PCXVersionCheck:
    mov ah,Version
    cmp ah,5
    je PCXBitPixelCheck ;если все верно, то дальше проверяем
    push word ptr PCXDescr ; если нет, то закрываем файл, печатаем сообщение об ошибке и выходим из программы
    call Close
    mov ah,09
    lea dx,NotPCX
    int 21h
    jmp ExitProg
    
    ; проверка кол-ва бит на пиксель (должно быть 8 для 256 цветов)
    PCXBitPixelCheck:
    mov ah,BitsPerPixel
    cmp ah,8
    je CheckNplanes ;если все верно, то проверяем NPlanes
    push word ptr PCXDescr  ; если нет, то закрываем файл, печатаем сообщение об ошибке и выходим из программы
    call Close
    mov ah,09
    lea dx,Not256
    int 21h
    jmp ExitProg
    ; проверка кол-ва цветовых линий
    ; должны быть 3 - R, G и B
    CheckNPlanes:
    mov ah,NPlanes
    cmp ah,3
    je CompleteCheck ;если все верно, то формат проверен
    push word ptr PCXDescr  ; если нет, то закрываем файл, печатаем сообщение об ошибке и выходим из программы
    call Close
    mov ah,09
    lea dx,Not256
    int 21h
    jmp ExitProg
    CompleteCheck:
    ; формирование размеров изображения, которые будут указаны в BMP
    mov ax,WindowXmax
    sub ax,WindowXmin
    inc ax ; в ax - ширина изображения
    mov word ptr biWidth,ax ; сохраним в biWidth
    mov ax, WindowYmax
    sub ax,WindowYmin
    inc ax ; в ax - высота изображения
    mov word ptr biHeight,ax ; сохраним в biHeight
    
    ; сформируем biSizeImage = biHeight * biWidth
    mov dx,word ptr biWidth
    mul dx
    mov word ptr biSizeImage,ax
    mov word ptr biSizeImage+2,dx
    
    ; запишем в структуру BMP (в памяти) информацию о разрешении изображения
    mov ax,Hres
    mov word ptr biXPelsPerMeter,ax
    mov ax,Vres
    mov word ptr biYPelsPerMeter,ax
    
    ; сформируем BfOffBits - смещение на начало растра
    mov ax, BMPHeaderSize ; размер заголовка
    add ax,BMPInfoHeaderSize ; + размер информационной структуры
    add ax,1024 ; + размер палитры
    mov word ptr BfOffBits,ax ; сохраним
    
    ; выичислима кол-во дополнящих байт для строки BMP
    mov ax,word ptr biWidth ; в ax - ширина изображения
    ; умножим ее на 3 и разделим на 4 (см. пояснительную записку)
    mov bl,4 
    mov cl,3
    mul cl
    div bl
    mov AdditiveBytes,ah ; сохраним остаток
    
    
    
    
    ; Создадим / откроем выходной BMP-файл
    lea dx,BMPName
    mov ah,3ch ; ф-ия для создания файла
    mov cx,0 ; режим записи
    add dx,2; перейдем на начало строки
    int 21h; открыли файл
    jnc SkipNotCreateMessage ; если нет ошибок, то обрабатываем файл
    push word ptr PCXDescr  ; если ошибка открытия то закрываем файл, печатаем сообщение об ошибке и выходим из программы
    call Close
    mov ah,09
    lea dx,СNСFMsg
    int 21h
    jmp ExitProg
    
    
    SkipNotCreateMessage:
    
    mov BMPDescr,ax ; сохраним дескриптор файла в переменную
    mov bx,ax
    ; запишем заголовок BMP
    lea dx,bfType
    mov ah,40h ; ф-ия DOS для записи в файл
    mov cx,BMPHeaderSize
    int 21h
    
    ; запишем также информационную структуру
    mov cx,BMPInfoHeaderSize
    lea dx,biSize
    mov ah,40h
    mov bx,BMPDescr
    int 21h
    
    
    ; считаем запакованный растр из PCX файла в буфер PackedArray
    mov ah,3fh
    mov bx,PCXDescr
    lea dx,PackedArray
    mov cx,60000
    int 21h
    mov cx,ax ; количество считанных байт ложим в сx (для организации цикла)
    mov ArraySize,cx ; и записываем в переменную
    
    ;!!!!!!!!!!! дешифрование растра PCX !!!!!!!!!!!!!!!!
    
    lea si,PackedArray ; si указывает на считанный растр
    xor di,di ; di=0 - нулевое смещение в сегменте MemoryBuf
    UnPack:
            mov al,[si] ; загружаем в al байт растра
            cmp al,10111111b ; является ли данный байт эталонным ? (не счетчиком)
            jb Etalon ; если да, то на Etalon
            ; если это счетчик, то вычленяем количество повторений
            shl al,2 
            shr al,2
            inc si ; переходим к следующему байту
            
            dec cx ; cx сразу уменьшим
            mov ah,[si] ; а ah згрузим этот байт растра
            ; цикл повторения байта ah раз
            CycleWrite:
            mov es:[di],ah ; запишем его в сегмент, выделенный для расшифровки
            inc di ; увеличим индекс
        
            dec al ; уменьшим счетчик повторений
            jnz CycleWrite ; если еще не нужное количество раз повторили байт, то пишем еще 
            
            inc si ; выставляем указатель на след. байт
            jmp Next ; переход к следующей итерации
            ; Для эталонного байта
            Etalon:
            mov es:[di],al ; пишем его в буферный сегмент
            inc di ;  увеличим индекс
            
            inc si ; переходим к следующему байту
            
            Next:
            
        loop Unpack
    
    
    
    
 
 
    ; !!!!!!!  обработка расшифрованного растра !!!!!!!
    
    ; вычислим кол-во байт, дополненных к строке развертки до выравнивания.
    mov cx,word ptr biWidth ; в cx - ширина изображения
    mov ax,word ptr BytesPerLine ; в ax - кол-во байт на линию
        sub ax,cx ; найдем разницу
    mov di,ax ; в di кол-во лишних байт
    mov cx,word ptr biHeight ; в cx - высота
    xor si,si ; si=0
    ; будем в цикле перебирать все строки
    ForHeight:
    push cx ; сохраним счетчик строк, чтоб не испортить
    mov cx,word ptr biWidth ; в cx - снова ширина
    mov ax,cx ; запишем ее в ax
    add ax,di ; добавим число байт для выравнивания
    xor bx,bx ; bx=0
    
    ; в цикле будем перебирать все пиксели по ширине. раздельно по разверткам R, G и B.
    ForWidth:
    
    ; строки развертки хранятся в порядке R,G,B
    mov dl,es:[si+bx] ; в dl пишем значение R текущего пикселя
    mov CurR,dl ; сохраняем
    add si,ax ; переходим к линии G 
    mov dl,es:[si+bx] ; в dl пишем значение R текущего пикселя
    mov CurG,dl ; сохраняем
    add si,ax; переходим к линии B 
    mov dl,es:[si+bx] ; в dl пишем значение R текущего пикселя
    mov CurB,dl ; сохраняем
    sub si,ax
    sub si,ax ; верунли si на начало линии R
    inc bx   ; увеличили счетчик обработанных пикселей
    call SetPallete ; вызываем процедуру обработки пикселя
    loop ForWidth
    
    ; переход к следующей строке
    add si,ax
    add si,ax
    add si,bx
    add si,di
    mov al,AdditiveBytes ; в al - кол-во дополнояющих строку байт
    xor ah,ah ; ah=0
    ; увеличиваем счетчик байтов в BMP-растре
    mov cx,CurByte
    add cx,ax
    mov CurByte,cx
    pop cx ; восстанавливаем счетчик строк
    loop ForHeight
    
    ; проверка адекватности кол-ва цветов
    mov ax,ColorsCount
    cmp ax,256 ; усли цветов меньше чем 256,
    jng SkipColorError ; то работаем дальше, иначе отрабатываем ошиьку
    ; закроем файлы, выведем сообщение и выйдем
    push word ptr PCXDescr  
    call Close
    push word ptr BMPDescr  
    call Close
    mov ah,09
    lea dx,Not256
    int 21h
    jmp ExitProg
    
    SkipColorError:
    
    ; запишем в BMP палитру
    mov cx,BMPPalleteSize
    lea dx,BMPPallete
    mov ah,40h
    mov bx,BMPDescr
    int 21h
    ; строки изображения в сегменте Bitmap хранятся в обычном порядке, а в BMP - в перевернутом, поэтому необходимо
    ; записать строки изображения в обратном порядке
    
    mov cx,word ptr biHeight ; в cx - высота (кол-во строк фактически)
    mov bx,BMPDescr ; рабоатем с BMP-файлом
    WriteStrings:
    push cx ; сохраним cx
    mov cx,word ptr biWidth ; теперь в cx - ширина изображения
    add cl,AdditiveBytes ; в cl - кол-во байт для выравнивания
    mov ax,CurByte ; в ax - индекс текущего байта в сегменте
    sub ax,cx ; вычитаем из него размер строки. теперь указывает индекс на начало строки
    mov CurByte,ax ; сохраним
    mov dx,CurByte ; запишем в dx для записи в файл
    mov ax,Bitmap ; в ax - адрес сегмента Bitmap
    mov ds,ax ; теперь сегмент данных по умолчанию - Bitmap, поскольку dx - это смещение относительно ds
    mov ah,40h
    int 21h ; записали строку
    ; восстанавливаем сегментный регистр ds
    mov ax,data
    mov ds,ax
    pop cx ; восстанавливаем cx
    loop WriteStrings
    
    ; для BMP файла, мы еще не указали размер bfSize в заголовке
    ; вычислим его на основе уже сформированного файла
    mov ah,42h ; ф-ия для перемещения укзателя по файлу
    mov al,2 ; относительно конца файла
    xor cx,cx
    xor dx,dx
    int 21h
    ; теперь в dx:ax -длина файла
    mov word ptr bfSize,ax
    mov word ptr bfSize+2,dx
    ; теперь перейдем в начало файла
    mov ah,42h ; ф-ия для перемещения укзателя по файлу
    mov al,0 ; относительно начала айла
    xor cx,cx
    xor dx,dx
    int 21h
    ; и заново запишем заголовок
    lea dx,bfType
    mov ah,40h ; ф-ия DOS для записи в файл
    mov cx,BMPHeaderSize
    int 21h
    ; закрываем входной и выходной файлы
    
    push BMPDescr
    call Close
    
    push PCXDescr
    call Close
    
    ;
    
    
    
    ExitProg:
    mov ah,00 ; ф-ия для ожидания нажатия клавиши
    int 16h ; ждем пока юзер не нажмет любую клавишу, а затем выходим
    
    mov ax,4C00h ; выходим
    int 21h
    
    main endp
    
    
 
    ; в стеке - адрес ссобщения, буфер строки
    ; выход: в bx дескриптор файла
    GetFileName proc
    pop di ; в di - адрес возврата
    pop dx ; в dx - адрес сообщения
    ; вывод строки для ввода имени файла
    mov ah,09
    int 21h ; выводим строку
    pop dx; в dx - адрес (смещение) на буфер для ввода строки
    ; ввод имени
    mov ah,0ah ; 0ah - ф-ия для буферизированного ввода строки с клавиатуры
    int 21h
    ; формирование строки имени файла
    mov bx,dx ; в [bx] лежит размер буфера  для ввода
    inc bx ; в [bx] - количество байт в строке
    mov al,[bx] ; в al - кол-во записанных байт
    add bl,al ; теперь bx указвает на последний записанный байт в строке
    inc bl  ; bx указывает на след. после последнего байт
    mov [bx],0 ; и помещаем туда ноль (необходимо для DOS)
    push di ; кладем в стек адрес возрврата
    ret
    GetFileName endp
    
    ; Функция для закрытия файла
    ; ВХОД: на вершине стека - дескриптор файла
Close proc 
 
    mov ah,3eh ; 3eh - ф-ия для закрытия файла
    pop cx ; в cx - адрес возврата
    pop bx ; берем из стека дескриптор файла
    int 21h 
    push cx ; снова в на вершине стека адрес возврата
ret
Close endp
; Ф-ия для поиска цвета в палитре
; Вход: -
; выход: в dx индекс цвета или 0ffffh если цвета CurR,CurG,CurB в палитре нет
FindColorIndex proc
    push cx ; сохраним cx и si в стеке
    push si
    lea bx,BMPPallete ; bx указывает на палитру
    mov cx,ColorsCount ; в cx - кол-во цветов в палитре
    xor si,si ; si=0
    xor di,di ; di=0
    mov dx,0ffffh ; по умолчанию - цвет в палитре не найден, если не докажется обратное
; будем в цикле перебирать все цвета палитры
    Find:
        mov al,[bx+si] ; в al - занчение состоавляющей B текущего цвета
        cmp al,CurB ; сравниваем с искомым
        jne NextColor ; если цвета не идентичны то переходим к проверке следующего цвета
        mov al,[bx+si+1]; в al - занчение состоавляющей G текущего цвета
        cmp al,CurG ; сравниваем с искомым
        jne NextColor ; если цвета не идентичны то переходим к проверке следующего цвета
        mov al,[bx+si+2]; в al - занчение состоавляющей R текущего цвета
        cmp al,CurR ; сравниваем с искомым
        jne NextColor ; если цвета не идентичны то переходим к проверке следующего цвета
        mov dx,di ; если все проверки прошли успешно, то искомый цвет найдем и в dx помещаем его индекс
        
    NextColor:
        inc di ; переходим к следующему цвету
        add si,4 ; в si - смещение на начала следующей записи RGBQ
    loop Find
    pop si ; восстановим регистры
    pop cx
ret
FindColorIndex endp
 
; ф-ия для обработки пикселя. 
SetPallete proc
    ; сохраним регистры, которые не стоит портить
    push ax
    push bx
    push si
    push di
    push dx
 
    lea si,BMPPallete ; si указывает на палитру
    mov bx,ColorsCount ; в bx - кол-во цветов
    test bx,bx ; если bx=0
    jz NullColors; то цветов нет и это будет первый
    call FindColorIndex ; если не первый, то ищем не было ли данного цвета CurR, CurB, CurG в палитре
    cmp dx,0ffffh ; если уже был,
    jne SkipAddColor ; то не добавляем
    AddColor:
; добавление цвета в палитру
    mov ax,ColorsCount ; в ax - кол-во цветов в палите
    mov bl,4
    mul bl ; умножаем на 4, чтобы получить смещение относительно начале палитры (каждый цвет 4мя байтами кодируется)
    mov bx,ax ; в bx будет лежать это смещение
    NullColors: ; если первый цвет, то все что было выше нам не нужно
; в BMP данные хранятся в порядке BGRQ, где Q - 00 всегда. в таком порядке их и записываем:
    mov al,CurB ; в al составляюущая B
    mov [si+bx],al
    mov al,CurG ;в al составляюущая G
    mov [si+bx+1],al
    mov al,CurR ; в al составляюущая Q
    mov [si+bx+2],al
    mov [si+bx+3],0
    mov dx,ColorsCount ; в dx  индекс данного цвета в палитре
    inc ColorsCount ; увеличиваем кол-во цветов
 
; запишем теперь пиксел (а именно порядковый номер цвета в палитре) в растр
    SkipAddColor:
    push es ; сохранием зн-ие сегментного регистра es
    mov ax,Bitmap ; в ax - адрес сегмента Bitmap
    mov es,ax ; теперь es на него указывает
    mov si,CurByte ; si указывает на текущий байт растра
    mov es:[si],dl ; записываем зн-ие индекса палитры
    inc CurByte ; и увеличиваем указатель
 
; восстановим es и необходимые регистры из стека
    pop es
    pop dx
    pop di
    pop si
    pop bx
    pop ax
ret
SetPallete endp 
code ends
 
 
 
end main
Добавлено через 13 минут
И ограничения - размер закодированного растра pcx не более 60000 байт, расшифрованного - не более размера сегмента (64 Кб). Это так, грубо.
0
11.06.2011, 00:51
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.06.2011, 00:51
Помогаю со студенческими работами здесь

Конвертация из jpg в bmp и обратно
И так, ребят, мне срочно нужна помощь! нужно при помощи MS Visual C++ переконвертировать jpg в bmp...

Конвертация bmp изображения в матрицу
повстречал статью на СоХабре https://sohabr.net/habr/post/195344/ - Конвертация bmp изображения в...

Конвертация bmp изображения в матрицу
StreamWriter steamWriter = new StreamWriter("c:\1.txt"); for (int y = 0; y < bmp.Height; y++) {...

Конвертация *.BMP в 3 файла *.ТХТ
Народ помогите. Нужен код на VB для конвертации файла формата BMP, ну то бишь изображения, в три...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru