Page 1 of 2

Ошибка в просчете палитры?

PostPosted: 02 Aug 2009, 12:55
by moroz1999
В общем, если я не ошибаюсь, то в процедуре расчета палитры закралась ошибка.
При расчете палитры результат делится не на 255, а на 256, из-за чего реальные RGB цвета высчитываются с небольшой погрешностью.
Экспериментальным путём подтвердил, что, например, при выставленной в настройках палитре от pulsar, ярко-красный цвет получается #FE0000 вместо #FF0000.

Вот формула из конфига:
; Rnn - matrix for post-processing:
; real_Red = (Red*R11 + Green*R12 + Blue*R13) / 0x100
; real_Green = (Red*R21 + Green*R22 + Blue*R23) / 0x100
; real_Blue = (Red*R31 + Green*R32 + Blue*R33) / 0x100

Вот палитра от Pulsar:
pulsar=00,76,CD,E9,FF,9F:FF,00,00;00,FF,00;00,00,FF

По формуле для ярко-красного выходит следующее:
real_Red = (0xFF*0xFF + 0*0 + 0*0) / 0x100 = 0xFE
И это более чем логично - деля 0xFF*0xFF на 0x100, мы никогда не получим 0xFF.
Следовательно, в формуле - логическая ошибка и 0x100 должно быть поменяно на 0xFF.

Я никогда не писал на C++, поэтому проверить свои измышления не смогу, но, руководствуясь своей интуицией, могу сказать, что изменения надо вносить в draw.cpp, линии 220, 221, 222. Исходники брал us0.37.3-src.rar

Re: Ошибка в просчете палитры?

PostPosted: 02 Aug 2009, 23:38
by deathsoft
Ошибки там никаокй нету, это обычное математическое нормирование, делится на размер диапазона 0-255 (всего целых чисел там 256). А FF там не получить из за погрешности расчета в 8битной арифметике, более того - там еще и переполнение возможно, когда все коэффициенты FF. От этого никуда не дется, либо надо считать не целочисленно и не в 8бит.

Коэффициент 255 в матрице не соответствует единице, для единицы в матрице должно быть 256.

[Ro] [R11 R12 R13] [Ri]
[Go]=[R21 R22 R23]*[Gi]
[Bo] [R31 R32 R33] [Bi]


В случае преоразования 1 в 1 матрица должна состоять из чисел

  [0x100 0 0]
I=[0 0x100 0]
  [0 0 0x100]


8-битный цап никогда не дает единицу на выходе, он дает значения от 0 до 255/256

P.S. Тут еще и арифметику с насыщением надо использовать, если результат превышает 255, то нужно брать 255.

Re: Ошибка в просчете палитры?

PostPosted: 03 Aug 2009, 14:02
by lvd
А что мешает считать единицей 0xFF, кроме предрассудков?

Re: Ошибка в просчете палитры?

PostPosted: 03 Aug 2009, 15:14
by deathsoft
lvd wrote:А что мешает считать единицей 0xFF, кроме предрассудков?

Тогда нуля не будет и будет неточно, надо просто в матрицу записывать коэффициенты 0..256 и все, а в унриале исправить расчет, чтобы внутринние вычисления были int а на байт, и будет все как надо, т.е. результирующий цвет будет 0..255. Еще сделать проверку на насыщение (не знаю сделано ли сейчас).

P.S. Ну и все палитры в ини файле надо будет поправить, чтобы где 1 было 0x100.

Re: Ошибка в просчете палитры?

PostPosted: 03 Aug 2009, 19:22
by lvd
deathsoft wrote:Тогда нуля не будет и будет неточно,

Ты шо, тормоз?
0 это ноль
255 это 1
ff*ff/ff === ff

deathsoft wrote:надо просто в матрицу записывать коэффициенты 0..256 и все, а в унриале исправить расчет, чтобы внутринние вычисления были int а на байт, и будет все как надо, т.е. результирующий цвет будет 0..255. Еще сделать проверку на насыщение (не знаю сделано ли сейчас).

Ну или так сделай, но 1 хуй получишь ты 0x100, и куды ты будешь пихать это в РГБ? Проще сделать 1===0xFF и не епсть мозг. Делить придётся на 255, а не сдвигать на 256, вот и всё.

Re: Ошибка в просчете палитры?

PostPosted: 03 Aug 2009, 22:27
by deathsoft
lvd wrote:Ну или так сделай, но 1 хуй получишь ты 0x100, и куды ты будешь пихать это в РГБ?

Там же написано - арифметика с насыщением если > 255 то записывается 255. Посмотри любые алгоритмы преобразования цветов (в MMX даже спец команды есть для сложения с насыщением).

Re: Ошибка в просчете палитры?

PostPosted: 04 Aug 2009, 19:09
by lvd
deathsoft wrote:Там же написано - арифметика с насыщением если > 255 то записывается 255.

Какая должна быть матрица, чтобы тройку RGB тождественно перевести в её же саму? Для случая 1===0xFF матрица ff 0 0;0 ff 0;0 0 ff.
Для случая 1===0x100 в студию. Используй любые насыщения в процессе расчёта, матрицу в студию и алгоритм пост-обработки.

Re: Ошибка в просчете палитры?

PostPosted: 05 Aug 2009, 00:10
by deathsoft
lvd wrote:Какая должна быть матрица, чтобы тройку RGB тождественно перевести в её же саму?

deathsoft wrote:В случае преоразования 1 в 1 матрица должна состоять из чисел


  [0x100 0 0]
I=[0 0x100 0]
  [0 0 0x100]



Ro=(Ri*0x100+Gi*0+Bi*0)/0x100
Go=(Ri*0+Gi*0x100+Bi*0)/0x100
Bo=(Ri*0+Gi*0+Bi*0x100)/0x100

Собственно все уже сделано в унриале, только коэффициенты в матрице неверные. Вместо 1.0 там 255/256

Re: Ошибка в просчете палитры?

PostPosted: 05 Aug 2009, 06:23
by lvd
deathsoft wrote:Ro=(Ri*0x100+Gi*0+Bi*0)/0x100 Go=(Ri*0+Gi*0x100+Bi*0)/0x100 Bo=(Ri*0+Gi*0+Bi*0x100)/0x100

Это выходит за пределы 8*8->16 умножения и за пределы 8-битной матрицы. Если это приемлемо, то да, всё ОК.

Re: Ошибка в просчете палитры?

PostPosted: 05 Aug 2009, 11:07
by deathsoft
lvd wrote:Это выходит за пределы 8*8->16 умножения и за пределы 8-битной матрицы. Если это приемлемо, то да, всё ОК.

Приемлемо, промежуточные расчеты просто int, а результат char, если бы были ограничения с разрядностью - то пришлось бы извращатся.