снова Dither

 

Как-то раз мне понадобилась  размытая картинка, пришлось писать код по-быстрому:

UseJPEGImageDecoder()
Dim ba.a(15,15)
Restore bayer8x8;bayer
For y=0 To 15-8
  For x=0 To 15-8
    Read.a ba(x,y)
Next x  
Next y  
LoadImage(0,"5d0fdb994d657d62f6b2a83caf2d2604.jpg")
StartDrawing(ImageOutput(0))
For y=0 To ImageHeight(0)-1
For x=0 To ImageWidth(0)-1
co=Point(x,y)
r=Red(co)
g=Green(co)
b=Blue(co)
bw=15-8
If r>ba(x&bw,y&bw)
  r=255
Else
  r=0
EndIf
If g>ba(x&bw,y&bw)
  g=255
Else
  g=0
EndIf
If b>ba(x&bw,y&bw)
  b=255
Else
  b=0
EndIf
Box(x,y,1,1,RGB(r,g,b))
Next x
Next y
StopDrawing()
SaveImage(0,"hrumpy.bmp")
DataSection
  bayer:
Data.a     0, 191,  48, 239,  12, 203,  60, 251,   3, 194,  51, 242,  15, 206,  63, 254   
Data.a   127,  64, 175, 112, 139,  76, 187, 124, 130,  67, 178, 115, 142,  79, 190, 127  
Data.a    32, 223,  16, 207,  44, 235,  28, 219,  35, 226,  19, 210,  47, 238,  31, 222  
Data.a   159,  96, 143,  80, 171, 108, 155,  92, 162,  99, 146,  83, 174, 111, 158,  95  
Data.a     8, 199,  56, 247,   4, 195,  52, 243,  11, 202,  59, 250,   7, 198,  55, 246  
Data.a   135,  72, 183, 120, 131,  68, 179, 116, 138,  75, 186, 123, 134,  71, 182, 119  
Data.a    40, 231,  24, 215,  36, 227,  20, 211,  43, 234,  27, 218,  39, 230,  23, 214  
Data.a   167, 104, 151,  88, 163, 100, 147,  84, 170, 107, 154,  91, 166, 103, 150,  87  
Data.a     2, 193,  50, 241,  14, 205,  62, 253,   1, 192,  49, 240,  13, 204,  61, 252  
Data.a   129,  66, 177, 114, 141,  78, 189, 126, 128,  65, 176, 113, 140,  77, 188, 125  
Data.a    34, 225,  18, 209,  46, 237,  30, 221,  33, 224,  17, 208,  45, 236,  29, 220  
Data.a   161,  98, 145,  82, 173, 110, 157,  94, 160,  97, 144,  81, 172, 109, 156,  93  
Data.a    10, 201,  58, 249,   6, 197,  54, 245,   9, 200,  57, 248,   5, 196,  53, 244  
Data.a   137,  74, 185, 122, 133,  70, 181, 118, 136,  73, 184, 121, 132,  69, 180, 117  
Data.a    42, 233,  26, 217,  38, 229,  22, 213,  41, 232,  25, 216,  37, 228,  21, 212  
Data.a   169, 106, 153,  90, 165, 102, 149,  86, 168, 105, 152,  89, 164, 101, 148,  85
bayer8x8:
Data.a   0, 128,  32, 160,   8, 136,  40, 168
Data.a 192,  64, 224,  96, 200,  72, 232, 104
Data.a 48, 176,  16, 144,  56, 184,  24, 152
Data.a 240, 112, 208,  80, 248, 120, 216,  88
Data.a 12, 140,  44, 172,   4, 132,  36, 164
Data.a 204,  76, 236, 108, 196,  68, 228, 100
Data.a 60, 188,  28, 156,  52, 180,  20, 148
Data.a 252, 124, 220,  92, 244, 116, 212,  84

Я использовал разные наборы данных, и не заметил особой разницы. Дальше стал искать способ генерации матрицы данных. Нашел:

// The original C algorithm
#include <stdio.h>

int main()
{
int M=2;
const unsigned dim = 1 << M;
for (unsigned y = 0; y < dim; ++y) {
    for (unsigned x = 0; x < dim; ++x) {
        unsigned v = 0, mask = M - 1, xc = x ^ y, yc = y;
        for (unsigned bit = 0; bit < 2 * M; --mask) {
            v |= ((yc >> mask) & 1) << bit++;
            v |= ((xc >> mask) & 1) << bit++;
        }
        printf("%4d ", v);
    }
    printf("\n");
}
}

и понеслось: переписанный код неверно генерирует данные. Поступил старым индейским способом - скормил код компилятору и посмотрел на листинг ассемблера, переписал как положено, исправил работающий код

;M=2
;    0    8    2   10
;   12    4   14    6
;    3   11    1    9
;   15    7   13    5
;M=3 (2n)^2
; 0 32 8 40 2 34 10 42 
; 48 16 56 24 50 18 58 26 
; 12 44 4 36 14 46 6 38 
; 60 28 52 20 62 30 54 22 
; 3 35 11 43 1 33 9 41 
; 51 19 59 27 49 17 57 25 
; 15 47 7 39 13 45 5 37 
; 63 31 55 23 61 29 53 21 
; // The original C algorithm
M=3
ddim=1<<M; const unsigned Dim = 1 << M;
; For (unsigned y = 0; y < dim; ++y) {
y=0
Repeat
r.s="";result
;For (unsigned x = 0; x < dim; ++x) {
x=0
Repeat
;unsigned v = 0, mask = M - 1, xc = x ^ y, yc = y;
v=0
mask=M-1
xc=x!y
yc=y
;For (unsigned bit = 0; bit < 2 * M; --mask) {
bit=0
Repeat
;  mask-1
;v |= ((yc >> mask) & 1) << bit++;
 v =v| ((yc >> mask) & 1) << bit
 bit+1
;v |= ((xc >> mask) & 1) << bit++;
v =v| ((xc >> mask) & 1) << bit
 bit+1
mask-1
 Until bit>2*M
;Debug v
r=r+Str(v)+" "
x+1
Until x>ddim-1
Debug r
y+1
Until y>ddim-1


Интересно, что погромисты относятся к алгоритму очень вольно - матрица выглядит так, что попутали координаты. Моя похожа на Вракипедию. Файлы тут.






Комментарии