#ifndef COSMOPOLITAN_TOOL_VIZ_LIB_CONVOLUTION_H_ #define COSMOPOLITAN_TOOL_VIZ_LIB_CONVOLUTION_H_ #include "dsp/core/q.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) /* clang-format off */ #define CONVROUND(X) ((int)rint(X)) #define CONVOLVE1X1(COEFFICIENT, DY, DX) (COEFFICIENT * (img[iy[y DY]][ix[x DX]])) #define CONVOLVE1X12(IMG, COEFFICIENT, DY, DX) (COEFFICIENT * IMG[iy[y DY]][ix[x DX]]) #define CONVOLVE3X3(NORMALIZER, \ C00, C01, C02, \ C10, C11, C12, \ C20, C21, C22) \ (NORMALIZER * \ (CONVOLVE1X1(C00,-1,-1)+CONVOLVE1X1(C01,-1,+0)+CONVOLVE1X1(C02,-1,+1)+ \ CONVOLVE1X1(C10,+0,-1)+CONVOLVE1X1(C11,+0,+0)+CONVOLVE1X1(C12,+0,+1)+ \ CONVOLVE1X1(C20,+1,-1)+CONVOLVE1X1(C21,+1,+0)+CONVOLVE1X1(C22,+1,+1))) #define CONVOLVE3X6(NORMALIZER, \ C00, C01, C02, \ C10, C11, C12, \ C20, C21, C22) \ (NORMALIZER * \ (CONVOLVE1X1(C00/2.f,-1,-1)+CONVOLVE1X1(C01/2.f,-1,+0)+CONVOLVE1X1(C02/2.f,-1,+1)+ \ CONVOLVE1X1(C00/2.f,-1,-1)+CONVOLVE1X1(C01/2.f,-1,+0)+CONVOLVE1X1(C02/2.f,-1,+1)+ \ CONVOLVE1X1(C10/2.f,+0,-1)+CONVOLVE1X1(C11/2.f,+0,+0)+CONVOLVE1X1(C12/2.f,+0,+1)+ \ CONVOLVE1X1(C10/2.f,+0,-1)+CONVOLVE1X1(C11/2.f,+0,+0)+CONVOLVE1X1(C12/2.f,+0,+1)+ \ CONVOLVE1X1(C20/2.f,+1,-1)+CONVOLVE1X1(C21/2.f,+1,+0)+CONVOLVE1X1(C22/2.f,+1,+1)+ \ CONVOLVE1X1(C20/2.f,+1,-1)+CONVOLVE1X1(C21/2.f,+1,+0)+CONVOLVE1X1(C22/2.f,+1,+1))) /* clang-format on */ #define CONVOLVE5X5(M, NORM, IMG, C00, C01, C02, C03, C04, C10, C11, C12, C13, \ C14, C20, C21, C22, C23, C24, C30, C31, C32, C33, C34, \ C40, C41, C42, C43, C44) \ QRS(M, (CONVOLVE1X12(IMG, CONVROUND((NORM * C00) * (1 << M)), -2, -2) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C01) * (1 << M)), -2, -1) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C02) * (1 << M)), -2, +0) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C03) * (1 << M)), -2, +1) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C04) * (1 << M)), -2, +2) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C10) * (1 << M)), -1, -2) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C11) * (1 << M)), -1, -1) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C12) * (1 << M)), -1, +0) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C13) * (1 << M)), -1, +1) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C14) * (1 << M)), -1, +2) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C20) * (1 << M)), +0, -2) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C21) * (1 << M)), +0, -1) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C22) * (1 << M)), +0, +0) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C23) * (1 << M)), +0, +1) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C24) * (1 << M)), +0, +2) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C30) * (1 << M)), +1, -2) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C31) * (1 << M)), +1, -1) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C32) * (1 << M)), +1, +0) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C33) * (1 << M)), +1, +1) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C34) * (1 << M)), +1, +2) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C40) * (1 << M)), +2, -2) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C41) * (1 << M)), +2, -1) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C42) * (1 << M)), +2, +0) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C43) * (1 << M)), +2, +1) + \ CONVOLVE1X12(IMG, CONVROUND((NORM * C44) * (1 << M)), +2, +2))) unsigned *convoindex(unsigned, unsigned, unsigned) mallocesque; #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_TOOL_VIZ_LIB_CONVOLUTION_H_ */