Форум: "Начинающим";
Текущий архив: 2007.09.30;
Скачать: [xml.tar.bz2];
Внизоперации с массивами Найти похожие ветки
← →
antonn © (2007-09-05 17:06) [0]после php уже не понимаю:)
есть динамический массив:const
MaxBTCount = MaxInt div SizeOf(dword);
type
BTElement = dword;
TBTArray = array[0..MaxBTCount-1] of BTElement;
var P: ^TBTArray;
по сути он представляет собой tbitmap (ну для простого понимания чего я хочу:)), каждый элемент dword - 4 байта (RGBA), длина массива width*height*SizeOf(BTElement) (width и height известны всегда, в смысле после заполнения в отдельных переменных)
сейчас к каждому байту в элемента я делаю Byte(fd shr 16) (8/24 и тд).
мне нужно этот амссив уменьшить в 4 раза, т.е. для "кубика" 4*4 для каждого байта находится среднее значение. Получается очень грамоздко:(считаю от размеров уже уменьшенного массива)
for y:=0 to Height-1 do begin
y1:=y*4*Width;
y2:=y1+Width;
y3:=y2+Width;
y4:=y3+Width;
for x:=0 to Width-1 do begin
for i:=0 to 3 do begin
cxi:=x*4+i;
BB:=BB+Byte(P^[ y1+cxi ] shr 16) + Byte(P^[ y2+cxi ] shr 16) + Byte(P^[ y3+cxi ] shr 16) + Byte(P^[ y4+cxi ] shr 16);
(и так для всех 4х байтов)
end;
result_b:=BB div 16;
как можно это оптимизировать? мож кто делал похожее на асме, потому что вот так получается тормозно (даже на обычных tbitmap через scanline быстрее). Можно ли как нибудь элемент типа dword представить в видеTBBR = record
b1,b2,b3,b4:byte;
end;
чтоб не делать каждый раз shr , а сделать один раз BBR:=TBBR(P^[ y1+x*4 ]) а потом только BBR.b1. Как это сделать не понимаю:) И убыстрит ли это прогон по циклу?
← →
antonn © (2007-09-05 17:07) [1]
> сейчас к каждому байту в элемента я делаю Byte(fd shr 16)
> (8/24 и тд).fd:=P^[ y*Width+x ];
байт:=Byte(fd shr 16);
← →
antonn © (2007-09-05 20:02) [2]ап:)
подскажите, как 4 dword лежащих подряд представить в виде одной структуры?
"координаты" первого dword известны.
← →
Dib@zol © (2007-09-05 20:19) [3]type
FourDword = array [1..4] of DWORD;
...
var
InitialDWORD : Pointer;
d4 : FourDword;
...
for i:=1 to 4 do
Move(Pointer(LongInt(InitialDWORD)+4*(i-1)), d4[i], 4);
← →
Dib@zol © (2007-09-05 20:23) [4]Поправлюсь:
Move(Pointer(LongInt(InitialDWORD)+4*(i-1))^, d4[i], 4);
← →
Sapersky (2007-09-05 22:23) [5]Можно ли как нибудь элемент типа dword представить в виде
TBBR = record
b1,b2,b3,b4:byte;
end;
PBBR = ^TBBR;
Var pb : PBBR;
pb := @P[y1+cxi];
pb.b1 := ...
Аналогично - 4 dword.
Могу ещё предложить процедуру уменьшения в 2 раза, точнее, для получения из 2-х 32-битных сканлиний одной. Count - ширина результирующей картинки в пикселях.
procedure xLine_Dec2X_MMX(Src1, Src2, Dst : Pointer; Count : Integer);
// EAX = Src1, EDX = Src2, ECX = Dst
asm
push ebx
mov ebx, ecx // ebx - dst
mov ecx, Count
@quads:
db $0F,$6F,$00 /// movq mm0, [eax]
db $0F,$60,$C8 /// punpcklbw mm1, mm0
db $0F,$71,$D1,$08 /// psrlw mm1, 8
db $0F,$68,$D0 /// punpckhbw mm2, mm0
db $0F,$71,$D2,$08 /// psrlw mm2, 8
db $0F,$6F,$02 /// movq mm0, [edx]
db $0F,$60,$D8 /// punpcklbw mm3, mm0
db $0F,$71,$D3,$08 /// psrlw mm3, 8
db $0F,$68,$E0 /// punpckhbw mm4, mm0
db $0F,$71,$D4,$08 /// psrlw mm4, 8
db $0F,$DD,$D1 /// paddusw mm2, mm1
db $0F,$DD,$E3 /// paddusw mm4, mm3
db $0F,$DD,$E2 /// paddusw mm4, mm2
db $0F,$71,$D4,$02 /// psrlw mm4, 2
db $0F,$67,$EC /// packuswb mm5, mm4
db $0F,$73,$D5,$20 /// psrlq mm5, 32
add eax, 8
db $0F,$7E,$2B /// movd [ebx], mm5
add edx, 8
add ebx, 4
dec ecx
jnz @quads
pop ebx
end;
Подозреваю, что не всё тут оптимально, некоторые сдвиги наверняка можно выкинуть. Но сейчас не хочется возиться.
← →
umbra © (2007-09-06 10:36) [6]
TLongRec(mydword).Bytes[i]
← →
umbra © (2007-09-06 10:37) [7]
LongRec(mydword).Bytes[i]
← →
antonn © (2007-09-06 11:37) [8]да, спасибо:)
с ММХ не разобрался, конечно, дуб в асме:)
← →
antonn © (2007-09-06 11:37) [9]да, спасибо:)
с ММХ не разобрался, конечно, дуб в асме:)
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.09.30;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.048 c