Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2014.07.06;
Скачать: CL | DM;

Вниз

Оптимизация кода   Найти похожие ветки 

 
Sha ©   (2013-07-02 14:39) [120]

Обрабатывать цвет по определению надо триплетами, читать-писать для скорости надо двойными словами.
Из-за этого небольшого противоречия возникают некоторые сложности с пониманием алгоритма )

Давай посмотрим это на простом примере. Пусть в памяти m последовательно лежат 4 байта. Надо первый из них увеличить на 1, второй умножить на 2, третий разделить на 3, четвертый оставить без изменений. Читать и писать переменную m разрешается только 1 раз.
Решение:

i:=m;
m:=(i  + 1) and $FF
  or i and $7F00 shl 1
  or i shr 16 and $FF div 3 shl 16
  or i and $FF000000;


 
Jeer ©   (2013-07-02 17:05) [121]

Приятно, когда мастера общаются in self и это правильно:)


 
Jeer ©   (2013-07-02 17:08) [122]

P.S.
Что-то это мне напомнило "Радио? Это очень просто!" Айсберга.
Кстати, на самом деле, замечательный методический прием.


 
Sha ©   (2013-07-02 17:41) [123]

> Вова   (02.07.13 13:25) [115]

че-то ты притих )

i shr 24 and $F0 - ставим нулевой байт второго триплета на нулевое место и оставляем в нем только 4 старших бита в старшем нибле,

j shr 4 and $F0F - ставим старший нибл первого байта второго триплета на место младшего нибла нулевого байта,
а старший нибл второго байта второго триплета на место младшего нибла первого байта,

or-им их между собой - получаем индекс для второго триплета в нашей таблице.

проще пареной репы )




> если у shl приоритет такой же как у or то вообще какая то херня

ну с приоритетами ты уж разберись, даже неудобно как-то, ты программист или где?
2+2*2=?

or j - первых 4 байта у которых значащими остались только первые 4 бита в последнем байте, накладываются на вторые 4 байта, получается вообще непонятно что )
j shr 4 - 4 правых бита от j удаляются. получается 4 байта с пустыми 4 битами в начале, и с какой то непонятной лажей (получившейся в результате or j) в самых правых 4 битах, а потом вообще ппц объединение с 111100001111, это ж полтора байта, как оно вообще накладывается (( на 4 байта! Обнуляются первые 4 бита правого байта? сдается мне что это не так, т.к почему тогда не 0F? ( но что за хрень это тогда?

В общем, к данному моменту кода у меня в голове полная каша не позволяющая идти дальше. Напоминает школу ) "В результате тривиальных вычислений получаем....." что получаем, откуда непонятно ( и как результат 10 впустую потраченных лет.

i := ColorMap[i and $F0 or i shr 12 and $F0F]; ну это понятно, см. выше ((

p[0] := i or T shl 24; - объединение 2х абракадабр, если у shl приоритет такой же как у or то вообще какая то херня, выкинули 3 байта остался 1 Оо

Все что я нашел об этом, это надписи о том, что в интернете куча статей об этом, видимо не такая уж и куча....Дайте ссылку хоть на одну! то что "1111000" or "00001111" = "11111111" это я вроде понял, только вот это никак не помогает понять, что в этом коде написано.


 
Sha ©   (2013-07-02 17:43) [124]

После 2+2*2=? не читай.
Это копипаста твоего поста


 
Rouse_ ©   (2013-07-02 21:13) [125]

Фига, Сань, у тебя конструкции:
or i shr 16 and $FF div 3 shl 16
Я понимаю, запятые там можно понапропускать, все равно читабельно будет - но зачем скобки то игнорировать на таких операциях? :)
Ни разу ж не читабельно :)


 
Sha ©   (2013-07-02 21:17) [126]

нормально читаю, с удовольствием:

  or читается как +
  and, shr, shl читаются как *

в чем проблема-то?
не понимаю )


 
Rouse_ ©   (2013-07-02 21:22) [127]

Ну я раза три перечитал сей код, дабы осмыслить :)

Оть так-же гораздо удобней:

or (((i shr 16) and $FF) div 3) shl 16


 
Sha ©   (2013-07-02 21:26) [128]

Саш, ну ты мысленно сделай замену как в [126].
Стал бы ты тогда ставить скобки?
Согласись, они бы только мешали.

Ну вот и мне мешают. Потому и не ставлю )


 
Rouse_ ©   (2013-07-02 21:28) [129]

Да это-то понятно, просто мне в своем крипто приходится писать примерно такого-же плана конструкции (побольше, правда) и чтобы не запутаться кто от чего зависит я и привык все скобками обрамлять.
Ну а исходя из этого я на автомате за скобки глазом цепляюсь и влет разбиваю конструкцию на составляющие, а вот в твоем варианте пришлось подзадуматься (вчитаться тобишь...) :)


 
Sha ©   (2013-07-02 21:31) [130]

У меня другой прием:
 куски, которые вычисляются по отдельности пишу каждый на своей строчке,
 а внутри кусков операции выполняются последовательно.
В результате и ясно все, и скобки не нужны.


 
Rouse_ ©   (2013-07-02 21:40) [131]

Принцип понятен, но все равно не привычен (попробовал - ну не получается на автомате разбирать такие конструкции) :)


 
Sha ©   (2013-07-02 21:46) [132]

Я уже давно так пишу, привык.
Наоборот, скобки тормозят чтение кода.
А лишние скобки просто бесят. Потому, что пытаюсь понять, нафига их сюда впихнули, а вдруг это ошибка?


 
Inovet ©   (2013-07-03 06:33) [133]

> [127] Rouse_ ©   (02.07.13 21:22)
> Оть так-же гораздо удобней:
>
> or (((i shr 16) and $FF) div 3) shl 16

Ну, как бы наоборот - путают скобки.


 
Inovet ©   (2013-07-03 06:34) [134]

> [132] Sha ©   (02.07.13 21:46)
> понять, нафига их сюда впихнули

Вот.


 
Вова   (2013-07-03 18:38) [135]


> че-то ты притих )i shr 24 and $F0 - ставим нулевой байт
> второго триплета на нулевое место и оставляем в нем только
> 4 старших бита в старшем нибле,


я просто уже выпал в осадок. Я уже заметил что нет единого мнения где у чего начало и конец, натворили че попало, без картинок и ящика водки не разберешься.

11111111 11111111 11111111 11111111 shr 24 and $F0= 00000000 00000000 0000000 11110000

т.е. самый левый байт становится самым правым. это как я себе представлял, но и также я себе представлял, что именно самый правый был первым байтом второго триплета. Теперь я уже затрудняюсь себе что либо представлять (
или таки т.е. нулевой это самый правый, первый это второй справа и т.д. и т.е. самый левый на самом деле 3й )) ппц. Че за наркоман это придумывал.


 
Sha ©   (2013-07-03 20:06) [136]

Мы, пишушие слева направо, любим стрелки вдаль к бесконечности направлять направо,
а числа записывать так, чтобы разряды с бОльшим весом располагались слева.
И это создает проблему.

Когда мы мыслим число в вакууме, с заякоренным разрядом единиц,
то чем оно больше тем левее у него левый край.
Но то же, лежащее поразрядно в бесконечной памяти уходит далеко направо.

Так что лево/право весьма относительно.
Этой проблемы не было бы, если б мы считали, что адреса растут от нуля налево.
Но как только мы начнем так считать, то сразу же появится аналогичная проблема для строк.
Наверно, поэтому никто из пишущих направо так и не считает )

Резюмируя, можно сказать, что команды SHR и SHL относятся к числу в вакууме.
И если тебе так будет проще, можешь считать,
что в памяти число вывернуто наизнанку, и левый фланг у него справа )


 
Вова   (2013-07-03 20:38) [137]

нет уш. Если у нас уже готовый битмап есть, то чтобы пройти от начала  до конца строки, нужно идти справа на лево получается.  так что это письмо справа налево.  и т.е. получается что второй триплет левее первого... но сдвиг вправо я надеюсь правильно нарисовал?) а то может у них и сдвиг вправо на самом деле влево ))


 
Sha ©   (2013-07-03 20:42) [138]

Сдвиг у тебя правильный )

А второй триплет, тот который на экране правее первого,
расположен в памяти по адресу на 3 больше, чем адрес первого.


 
Вова   (2013-07-04 01:50) [139]

12500670 =
10111110 10111110 10111110 shr 12 =  00000000 00001011 11101011 and $F0F =00000000 00001011 00001011

10111110 10111110 10111110 and $F0 = 10111110 10111110 10110000

00000000 00001011 00001011 or
10111110 10111110 10110000 =
10111110 10111111 10111011 = 12500923

и в чем тут смысл? да и по моему че то не так....


 
Sha ©   (2013-07-04 10:18) [140]

$87654321 shr 12             = $00087654
$00087654 and $00000F0F = $00000604
$87654321 and $000000F0 = $00000020
$00000604  or $00000020 = $00000624


Мы сформировали число в интервале 0..4095 (индекс цвета в нашей таблице),
комбинируя старшие ниблы каждого из трех цветовых каналов.

Порядок следования исходных ниблов в полученном числе выбран таким,
чтобы обеспечить максимальную скорость преобразования цвета в индекс.


 
DevilDevil ©   (2013-07-29 15:02) [141]

> Вова   (04.07.13 01:50) 

подниму ка я ветку
пока работающий вариант с циклом for по X и по Y в 24 битах
оптимизирую

а то развели тут бардак ))


 
DevilDevil ©   (2013-07-29 15:25) [142]

*покажи


 
Вова   (2013-07-29 17:20) [143]


> *покажи


в 81м посте, но нафига, если 32 проще и быстрее работает.


 
Sha ©   (2013-07-29 17:41) [144]

> Вова   (29.07.13 17:20) [143]
> если 32 проще и быстрее работает

хочешь поговорить об этом? )


 
DevilDevil ©   (2013-07-29 17:44) [145]

ok, покажи текущий код для 32 бита


 
Вова   (2013-07-29 18:06) [146]


> > Вова   (29.07.13 17:20) [143]> если 32 проще и быстрее
> работаетхочешь поговорить об этом? )


ты же сам сказал, что по определению быстрее. Ну из того что я пробовал оно следует.


 
Вова   (2013-07-29 18:09) [147]


> ok, покажи текущий код для 32 бита


Там выше где то было, но вообще я еще не делал, мне под него программу нужно переделывать, время пока нет на это (


 
DevilDevil ©   (2013-07-29 18:10) [148]

> Вова   (29.07.13 18:06) [146]
> ты же сам сказал, что по определению быстрее. Ну из того
> что я пробовал оно следует.


всё верно
в современном мире используют преимущественно 32 бита, даже если нет альфаканала
ибо проще и быстрее
"стильно модно молодёжно" хочется сказать :)


 
DevilDevil ©   (2013-07-29 18:11) [149]

> Вова   (29.07.13 18:09) [147]

> Там выше где то было, но вообще я еще не делал, мне под
> него программу нужно переделывать, время пока нет на это (


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


 
Вова   (2013-07-29 20:27) [150]


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


не забросил, а отложил )


 
Вова   (2013-07-29 20:31) [151]

как то так было:

function LockConvertBmpToRGBColorMapM(ppixel: pAnsiChar;last:pAnsiChar): Boolean;
var
i    : integer ;
begin

repeat;
 i:=pInteger(ppixel)^;
 pInteger(ppixel)^:=ColorMap[i shr 12 and $F0F or i and $F0];
 inc(ppixel,4)
 until ppixel=last;

Result := true;
end;


> лол, а вот так 2 миллисекунды, ток все через черную полоску.
>   и даж цвета похожи на те что я выводил


только я ему картинку неправильную давал


 
DevilDevil ©   (2013-07-29 21:00) [152]

> Вова   (29.07.13 20:31) [151]

дак ты покажи рабочий вариант )

p.s.
и рассчёт индекса в табличке выглядит как-то странно


 
Вова   (2013-08-22 23:43) [153]

итаг, я приступил к воплощению сего плана и начал переворачивать все шо не попадя. и вот ниже процедура, часть из которой закоментирована. И суть проблемы в том, что закоментированный и раскоментированный участки делают вроде бы одно и тоже. Но нижний участок при обратном преобразовании в битмап дает нормальные цвета. А вот тот что ща закоментирован, желтый делает голубым, голубой светлокоричневым и т.д. получается очень красиво, но нихрена не работает в результате. Почему так и как исправить верхний закоментированный кусок? )

function ConvertBmpToRGBColorMapM(tbmp:TBitmap; var M: TMass;
 Mass: TColorMapByte): Boolean;
var
Pixel1,i,x,y:Integer;
Start,Stop:pInteger;
QP: TQuickPixels;
begin

//    Start := tbmp.ScanLine[tbmp.Height - 1];
//    Stop  := tbmp.ScanLine[0];
//    Pixel1:= 0;
//    repeat
//      i:= Start^;
//      M.Mass[Pixel1] := i;
//      //Mass[i shr 12 and $F0F or i and $F0];
//      inc(Start);
//      inc(Pixel1);
//    until Start = Stop;

QP := TQuickPixels.Create;
 QP.Attach(tbmp);

 for y := 0 to QP.Height - 1 do
 begin
   for x := 0 to QP.Width - 1 do
   begin
     Pixel1 := QP.GetPixels32(x, y);
     M.Mass[x + y * M.Xsize] := Pixel1;
     //Mass[Pixel1 shr 12 and $F0F or Pixel1 and $F0];
   end;
 end;
 Result := true;
   QP.Free;

 Result := true;
end;


 
Sapersky   (2013-08-23 00:10) [154]

[78]:

> Проблемы с цветами видимо из-за того, что порядок цветовых
> компонент изменился, раньше было RGB, сейчас BGR. Нужно
> сдвиги и and"ы с масками поменять соот-но.

Точнее BGRA, раз это 32 бита.


 
Вова   (2013-08-23 00:18) [155]

    repeat
       i:= Start^;
       Start^ := ColorMap[i shr 12 and $F0F or i and $F0];
       inc(Start);
       inc(Pixel1);
     until Start = Stop;


да (

проблемма в том, что я так и не понял что все это значит(i shr 12 and $F0F or i and $F0). Вообщем первую проблему то я решил.....но, при таком преобразовании, результат вовсе не такой как был раньше (

вместо желтого красный ну и т.д ( как поменять?


 
Вова   (2013-08-23 00:34) [156]

RGBV.red := color;
 RGBV.green := color shr 8;
 RGBV.blue := color shr 16;


блин, а это теперь тогда тоже не правильно? чот как не крутил все равно лажа (


 
Sapersky   (2013-08-23 00:50) [157]

Проще всего как раз в этом месте поменять red и blue, чтобы не ковырять биты заново. И ещё  i:= Start^ shr 8, чтобы привести BGRA к BGR.


 
Вова   (2013-08-23 00:57) [158]


> Проще всего как раз в этом месте поменять red и blue, чтобы
> не ковырять биты заново. И ещё  i:= Start^ shr 8, чтобы
> привести BGRA к BGR.


не ( не помогает, еще больше цвета путаются.

ненавижу тех кто придумал вот эту хренотень с битмапами и всем вывернутым на изнанку ( и ниодной нормальной инструкции с картинками.


 
Германн ©   (2013-08-23 01:13) [159]


> и ниодной нормальной инструкции с картинками

))))


 
Вова   (2013-08-23 01:21) [160]


 TRGB = record
  case integer of
  1: (RGB: LongInt);
  2: (B, G, R, O: BYTE);

var
 rRGB:TRGB;

 rrgb.RGB := ColorToRGB(color);
 RGBV.red := rrgb.B;
 RGBV.green := rrgb.G;
 RGBV.blue := rrgb.R;

CODE</>


 RGBV.red   := color;
 RGBV.green := color shr 8;
 RGBV.blue := color shr 16;


оба варианта дают одинаковый результат. (второй старый на 24 бита был). то что было раньше желтым теперь красное, и появился голубой....откуда блин голубой, у меня в массиве его вообще нет.

Function ConvertColorToRGBColorMap(color: LongInt; ColSel: string = "None")
 : TColorWithName;
var
 RGBV: trgbcolor;
 bg: Boolean;
 rb: Boolean;
 rg: Boolean;
 rRGB:TRGB;
begin

//  rrgb.RGB := ColorToRGB(color);
//  RGBV.red := rrgb.B;
//  RGBV.green := rrgb.G;
//  RGBV.blue := rrgb.R;

 RGBV.red   := color;
 RGBV.green := color shr 8;
 RGBV.blue := color shr 16;

 rb := almostEqual(RGBV.red, RGBV.blue);
 bg := almostEqual(RGBV.blue, RGBV.green);
 rg := almostEqual(RGBV.red, RGBV.green);

 with RGBV do

   if rg and rb and bg then // тогда это серый или черный или белый
   begin
     if red > 230 then // белый
     begin
       result.color := RGB(255, 255, 255);
       result.Name := "White";
     end
     else if red > 120 then
     begin
       result.color := RGB(190, 190, 190);
       result.Name := "LightGray";
     end
     else if (red > 92) then // темно серый
     begin
       result.color := RGB(100, 100, 100);
       result.Name := "DarkGray";
     end
     else
     begin
       result.color := RGB(0, 0, 0);
       result.Name := "Black";
     end // черный
   end
   else
   begin
     if (red < green) and (red < blue) and bg and (blue > 130) then
     begin
       result.color := RGB(0, 0, 255);
       result.Name := "Blue";
     end // result:= rgb(0,255,255)//голубой
     else if (green < red) and (green < blue) and rb and (red > 130) then
     begin
       result.color := RGB(255, 0, 255);
       result.Name := "Pink";
     end // розовый
     else if (blue < green) and (blue < red) and rg and (green > 130) then
     begin
       result.color := RGB(255, 255, 0);
       result.Name := "Yellow";
     end // желтый
     else if (red > green) and (red > blue) and (red > 130) then
     begin
       result.color := RGB(255, 0, 0);
       result.Name := "Red";
     end // красный
     else if (blue > green) and (blue > red) and (blue > 130) then
     begin
       result.color := RGB(0, 0, 255);
       result.Name := "Blue";
     end // синий
     else if (green > blue) and (green > red) and (green > 130) then
     begin
       result.color := RGB(0, 255, 0);
       result.Name := "Green";
     end // зеленый
     else
     begin
       result.color := RGB(0, 0, 0);
       result.Name := "Black";
     end
   end;

 if not(ColSel = "None") then
   if (ColSel = result.Name) then
   begin
     result.color := 255; // картинка инвертирована для дальнейшей обработки
   end
   else
   begin
     result.color := 0;
   end;
end;

Procedure InitColorMap();
var
 i, j, k: byte;
begin
 for i := 0 to 15 do
   for j := 0 to 15 do
     for k := 0 to 15 do
       ColorMap[i * 256 + 16 * k + j] := ConvertColorToRGBColorMap
         ((i * 256 * 256 + j * 256 + k) * 16).color;
 // for i:=0 to 15 do for j:=0 to 15 do for k:=0 to 15 do ColorMap[i*256+16*k+j]:=ConvertColorToRGBColorMap((i*16+15)*256*256+(j*16+15)*256+(k*16+15));
end;

Function ConvertBmpToRGBColorMap(var tBmp: Tbitmap;
 ColSel: String = "None"): Boolean;
var
 QP: TQuickPixels;
 Pixel1: Cardinal;
 x: integer;
 y: integer;
 i: integer;
 numCol: byte;
 Start,Stop:pInteger;
begin

 if (tBmp.Height > 2) and (tBmp.Width >= 1) then
 begin
 
   numCol := TextColorToDigit(ColSel);

   if numCol = 0 then
   begin

     Start := tBmp.ScanLine[tBmp.Height - 1];
     Stop := tBmp.ScanLine[0];

     repeat
       i:= Start^;
       Start^ := ColorMap[i shr 12 and $F0F or i and $F0];
       inc(Start);
       inc(Pixel1);
     until Start = Stop;
   end;
   

   Result := true;
 end
 else
   Result := false;

end;




Страницы: 1 2 3 4 5 6 вся ветка

Текущий архив: 2014.07.06;
Скачать: CL | DM;

Наверх




Память: 0.84 MB
Время: 0.022 c
15-1387485002
Юрий
2013-12-20 00:30
2014.07.06
С днем рождения ! 20 декабря 2013 пятница


2-1378365351
lewka-mar
2013-09-05 11:15
2014.07.06
Подстановка значений в edit


3-1299228082
Очень злой
2011-03-04 11:41
2014.07.06
Выборка "в ширину". Можно ли такое сделать?


15-1387524120
DevilDevil
2013-12-20 11:22
2014.07.06
Ассемблерщикам: CF/ZF


3-1299090765
John_Vattic
2011-03-02 21:32
2014.07.06
Access 2007 и Delphi 7