98 int32_t ibh, uint8_t *o, int32_t ox, int32_t oy, int32_t ow, int32_t oh,
99 int32_t obw, int32_t obh)
101 const float scalex = iw / (float)ow;
102 const float scaley = ih / (float)oh;
103 const int32_t ix2 =
MAX(ix, 0);
104 const int32_t iy2 =
MAX(iy, 0);
105 const int32_t ox2 =
MAX(ox, 0);
106 const int32_t oy2 =
MAX(oy, 0);
107 const int32_t oh2 =
MIN(
MIN(oh, (ibh - iy2) / scaley), obh - oy2);
108 const int32_t ow2 =
MIN(
MIN(ow, (ibw - ix2) / scalex), obw - ox2);
109 assert((
int)(ix2 + ow2 * scalex) <= ibw);
110 assert((
int)(iy2 + oh2 * scaley) <= ibh);
111 assert(ox2 + ow2 <= obw);
112 assert(oy2 + oh2 <= obh);
113 assert(ix2 >= 0 && iy2 >= 0 && ox2 >= 0 && oy2 >= 0);
114 float x = ix2, y = iy2;
115 for(
int s = 0; s < oh2; s++)
117 int idx = ox2 + obw * (oy2 + s);
118 for(
int t = 0;
t < ow2;
t++)
120 for(
int k = 0;
k < 3;
k++)
122 CLAMP(((int32_t)
i[(4 * (ibw * (int32_t)y + (int32_t)(
x + .5f * scalex)) +
k)]
123 + (int32_t)
i[(4 * (ibw * (int32_t)(y + .5f * scaley) + (int32_t)(
x + .5f * scalex)) +
k)]
124 + (int32_t)
i[(4 * (ibw * (int32_t)(y + .5f * scaley) + (int32_t)(
x)) +
k)]
125 + (int32_t)
i[(4 * (ibw * (int32_t)y + (int32_t)(
x)) +
k)])
178 const dt_iop_roi_t *
const roi_in,
const int32_t out_stride,
179 const int32_t in_stride,
const uint32_t filters)
183 const float px_footprint = 1.f / roi_out->
scale;
187 int trggbx = 0, trggby = 0;
188 if(
FC(trggby, trggbx + 1, filters) != 1) trggbx++;
189 if(
FC(trggby, trggbx, filters) != 0)
191 trggbx = (trggbx + 1) & 1;
194 const int rggbx = trggbx, rggby = trggby;
200 int clut[4][3] = {{0}};
201 for(
int y = 0; y < 2; ++y)
202 for(
int x = 0;
x < 2; ++
x)
204 const int c =
FC(y + rggby,
x + rggbx, filters);
205 assert(clut[c][0] < 2);
206 clut[c][++clut[c][0]] =
x + y * in_stride;
209 for(
int y = 0; y < roi_out->
height; y++)
211 uint16_t *outc =
out + out_stride * y;
213 const float fy = (y + roi_out->
y) * px_footprint;
214 const int miny = (
CLAMPS((
int)floorf(fy - px_footprint), 0, roi_in->
height-3) & ~1u) + rggby;
215 const int maxy =
MIN(roi_in->
height-1, (
int)ceilf(fy + px_footprint));
217 float fx = roi_out->
x * px_footprint;
218 for(
int x = 0;
x < roi_out->
width;
x++,
fx += px_footprint, outc++)
220 const int minx = (
CLAMPS((
int)floorf(
fx - px_footprint), 0, roi_in->
width-3) & ~1u) + rggbx;
221 const int maxx =
MIN(roi_in->
width-1, (
int)ceilf(
fx + px_footprint));
223 const int c =
FC(y,
x, filters);
227 for(
int yy = miny; yy < maxy; yy += 2)
228 for(
int xx = minx; xx < maxx; xx += 2)
230 col += in[clut[c][1] + xx + in_stride * yy];
234 col += in[clut[c][2] + xx + in_stride * yy];
238 if(num) *outc = col / num;
245 const dt_iop_roi_t *
const roi_in,
const int32_t out_stride,
246 const int32_t in_stride,
const uint32_t filters)
250 const float px_footprint = 1.f / roi_out->
scale;
252 const int samples = round(px_footprint / 2);
255 int trggbx = 0, trggby = 0;
256 if(
FC(trggby, trggbx + 1, filters) != 1) trggbx++;
257 if(
FC(trggby, trggbx, filters) != 0)
259 trggbx = (trggbx + 1) & 1;
262 const int rggbx = trggbx, rggby = trggby;
264 for(
int y = 0; y < roi_out->
height; y++)
266 float *outc =
out + out_stride * y;
268 const float fy = (y + roi_out->
y) * px_footprint;
269 int py = (int)fy & ~1;
270 const float dy = (fy - py) / 2;
271 py =
MIN(((roi_in->
height - 6) & ~1u), py) + rggby;
273 int maxj =
MIN(((roi_in->
height - 5) & ~1u) + rggby, py + 2 * samples);
275 for(
int x = 0;
x < roi_out->
width;
x++)
279 const float fx = (
x + roi_out->
x) * px_footprint;
280 int px = (int)
fx & ~1;
281 const float dx = (
fx - px) / 2;
282 px =
MIN(((roi_in->
width - 6) & ~1u), px) + rggbx;
284 const int maxi =
MIN(((roi_in->
width - 5) & ~1u) + rggbx, px + 2 * samples);
290 p[0] = in[px + in_stride * py];
291 p[1] = in[px + 1 + in_stride * py];
292 p[2] = in[px + in_stride * (py + 1)];
293 p[3] = in[px + 1 + in_stride * (py + 1)];
294 for(
int c = 0; c < 4; c++) col[c] += ((1 - dx) * (1 - dy)) *
p[c];
297 for(
int j = py + 2; j <= maxj; j += 2)
299 p[0] = in[px + in_stride * j];
300 p[1] = in[px + 1 + in_stride * j];
301 p[2] = in[px + in_stride * (j + 1)];
302 p[3] = in[px + 1 + in_stride * (j + 1)];
303 for(
int c = 0; c < 4; c++) col[c] += (1 - dx) *
p[c];
307 for(
int i = px + 2;
i <= maxi;
i += 2)
309 p[0] = in[
i + in_stride * py];
310 p[1] = in[
i + 1 + in_stride * py];
311 p[2] = in[
i + in_stride * (py + 1)];
312 p[3] = in[
i + 1 + in_stride * (py + 1)];
313 for(
int c = 0; c < 4; c++) col[c] += (1 - dy) *
p[c];
317 for(
int j = py + 2; j <= maxj; j += 2)
318 for(
int i = px + 2;
i <= maxi;
i += 2)
320 p[0] = in[
i + in_stride * j];
321 p[1] = in[
i + 1 + in_stride * j];
322 p[2] = in[
i + in_stride * (j + 1)];
323 p[3] = in[
i + 1 + in_stride * (j + 1)];
324 for(
int c = 0; c < 4; c++) col[c] +=
p[c];
327 if(maxi == px + 2 * samples && maxj == py + 2 * samples)
330 for(
int j = py + 2; j <= maxj; j += 2)
332 p[0] = in[maxi + 2 + in_stride * j];
333 p[1] = in[maxi + 3 + in_stride * j];
334 p[2] = in[maxi + 2 + in_stride * (j + 1)];
335 p[3] = in[maxi + 3 + in_stride * (j + 1)];
336 for(
int c = 0; c < 4; c++) col[c] += dx *
p[c];
340 p[0] = in[maxi + 2 + in_stride * py];
341 p[1] = in[maxi + 3 + in_stride * py];
342 p[2] = in[maxi + 2 + in_stride * (py + 1)];
343 p[3] = in[maxi + 3 + in_stride * (py + 1)];
344 for(
int c = 0; c < 4; c++) col[c] += (dx * (1 - dy)) *
p[c];
347 for(
int i = px + 2;
i <= maxi;
i += 2)
349 p[0] = in[
i + in_stride * (maxj + 2)];
350 p[1] = in[
i + 1 + in_stride * (maxj + 2)];
351 p[2] = in[
i + in_stride * (maxj + 3)];
352 p[3] = in[
i + 1 + in_stride * (maxj + 3)];
353 for(
int c = 0; c < 4; c++) col[c] += dy *
p[c];
357 p[0] = in[px + in_stride * (maxj + 2)];
358 p[1] = in[px + 1 + in_stride * (maxj + 2)];
359 p[2] = in[px + in_stride * (maxj + 3)];
360 p[3] = in[px + 1 + in_stride * (maxj + 3)];
361 for(
int c = 0; c < 4; c++) col[c] += ((1 - dx) * dy) *
p[c];
364 p[0] = in[maxi + 2 + in_stride * (maxj + 2)];
365 p[1] = in[maxi + 3 + in_stride * (maxj + 2)];
366 p[2] = in[maxi + 2 + in_stride * (maxj + 3)];
367 p[3] = in[maxi + 3 + in_stride * (maxj + 3)];
368 for(
int c = 0; c < 4; c++) col[c] += (dx * dy) *
p[c];
370 num = (samples + 1) * (samples + 1);
372 else if(maxi == px + 2 * samples)
375 for(
int j = py + 2; j <= maxj; j += 2)
377 p[0] = in[maxi + 2 + in_stride * j];
378 p[1] = in[maxi + 3 + in_stride * j];
379 p[2] = in[maxi + 2 + in_stride * (j + 1)];
380 p[3] = in[maxi + 3 + in_stride * (j + 1)];
381 for(
int c = 0; c < 4; c++) col[c] += dx *
p[c];
385 p[0] = in[maxi + 2 + in_stride * py];
386 p[1] = in[maxi + 3 + in_stride * py];
387 p[2] = in[maxi + 2 + in_stride * (py + 1)];
388 p[3] = in[maxi + 3 + in_stride * (py + 1)];
389 for(
int c = 0; c < 4; c++) col[c] += (dx * (1 - dy)) *
p[c];
391 num = ((maxj - py) / 2 + 1 - dy) * (samples + 1);
393 else if(maxj == py + 2 * samples)
396 for(
int i = px + 2;
i <= maxi;
i += 2)
398 p[0] = in[
i + in_stride * (maxj + 2)];
399 p[1] = in[
i + 1 + in_stride * (maxj + 2)];
400 p[2] = in[
i + in_stride * (maxj + 3)];
401 p[3] = in[
i + 1 + in_stride * (maxj + 3)];
402 for(
int c = 0; c < 4; c++) col[c] += dy *
p[c];
406 p[0] = in[px + in_stride * (maxj + 2)];
407 p[1] = in[px + 1 + in_stride * (maxj + 2)];
408 p[2] = in[px + in_stride * (maxj + 3)];
409 p[3] = in[px + 1 + in_stride * (maxj + 3)];
410 for(
int c = 0; c < 4; c++) col[c] += ((1 - dx) * dy) *
p[c];
412 num = ((maxi - px) / 2 + 1 - dx) * (samples + 1);
416 num = ((maxi - px) / 2 + 1 - dx) * ((maxj - py) / 2 + 1 - dy);
419 const int c = (2 * ((y + rggby) % 2) + ((
x + rggbx) % 2));
420 if(num) *outc = col[c] / num;
510 const int32_t out_stride,
511 const int32_t in_stride)
515 const float px_footprint = 1.f / roi_out->
scale;
517 const int samples = round(px_footprint);
519 for(
int y = 0; y < roi_out->
height; y++)
521 float *outc =
out + 4 * (out_stride * y);
523 const float fy = (y + roi_out->
y) * px_footprint;
525 const float dy = fy - py;
528 const int maxj =
MIN(((roi_in->
height - 2)), py + samples);
530 for(
int x = 0;
x < roi_out->
width;
x++)
534 const float fx = (
x + roi_out->
x) * px_footprint;
536 const float dx =
fx - px;
537 px =
MIN(((roi_in->
width - 3)), px);
539 const int maxi =
MIN(((roi_in->
width - 2)), px + samples);
545 p = in[px + in_stride * py];
546 col += ((1 - dx) * (1 - dy)) *
p;
549 for(
int j = py + 1; j <= maxj; j++)
551 p = in[px + in_stride * j];
556 for(
int i = px + 1;
i <= maxi;
i++)
558 p = in[
i + in_stride * py];
563 for(
int j = py + 1; j <= maxj; j++)
564 for(
int i = px + 1;
i <= maxi;
i++)
566 p = in[
i + in_stride * j];
570 if(maxi == px + samples && maxj == py + samples)
573 for(
int j = py + 1; j <= maxj; j++)
575 p = in[maxi + 1 + in_stride * j];
580 p = in[maxi + 1 + in_stride * py];
581 col += (dx * (1 - dy)) *
p;
584 for(
int i = px + 1;
i <= maxi;
i++)
586 p = in[
i + in_stride * (maxj + 1)];
591 p = in[px + in_stride * (maxj + 1)];
592 col += ((1 - dx) * dy) *
p;
595 p = in[maxi + 1 + in_stride * (maxj + 1)];
596 col += (dx * dy) *
p;
598 num = (samples + 1) * (samples + 1);
600 else if(maxi == px + samples)
603 for(
int j = py + 1; j <= maxj; j++)
605 p = in[maxi + 1 + in_stride * j];
610 p = in[maxi + 1 + in_stride * py];
611 col += (dx * (1 - dy)) *
p;
613 num = ((maxj - py) / 2 + 1 - dy) * (samples + 1);
615 else if(maxj == py + samples)
618 for(
int i = px + 1;
i <= maxi;
i++)
620 p = in[
i + in_stride * (maxj + 1)];
625 p = in[px + in_stride * (maxj + 1)];
626 col += ((1 - dx) * dy) *
p;
628 num = ((maxi - px) / 2 + 1 - dx) * (samples + 1);
632 num = ((maxi - px) / 2 + 1 - dx) * ((maxj - py) / 2 + 1 - dy);
635 const float pix = (num) ? col / num : 0.0f;
647 const dt_iop_roi_t *
const roi_in,
const int32_t out_stride,
648 const int32_t in_stride,
const uint32_t filters)
652 const float px_footprint = 1.f / roi_out->
scale;
654 const int samples = round(px_footprint / 2);
657 int trggbx = 0, trggby = 0;
658 if(
FC(trggby, trggbx + 1, filters) != 1) trggbx++;
659 if(
FC(trggby, trggbx, filters) != 0)
661 trggbx = (trggbx + 1) & 1;
664 const int rggbx = trggbx, rggby = trggby;
666 for(
int y = 0; y < roi_out->
height; y++)
668 float *outc =
out + 4 * (out_stride * y);
670 const float fy = (y + roi_out->
y) * px_footprint;
671 int py = (int)fy & ~1;
672 const float dy = (fy - py) / 2;
673 py =
MIN(((roi_in->
height - 6) & ~1u), py) + rggby;
675 const int maxj =
MIN(((roi_in->
height - 5) & ~1u) + rggby, py + 2 * samples);
677 for(
int x = 0;
x < roi_out->
width;
x++)
681 const float fx = (
x + roi_out->
x) * px_footprint;
682 int px = (int)
fx & ~1;
683 const float dx = (
fx - px) / 2;
684 px =
MIN(((roi_in->
width - 6) & ~1u), px) + rggbx;
686 const int maxi =
MIN(((roi_in->
width - 5) & ~1u) + rggbx, px + 2 * samples);
692 p[0] = in[px + in_stride * py];
693 p[1] = in[px + 1 + in_stride * py] + in[px + in_stride * (py + 1)];
694 p[2] = in[px + 1 + in_stride * (py + 1)];
695 for(
int c = 0; c < 3; c++) col[c] += ((1 - dx) * (1 - dy)) *
p[c];
698 for(
int j = py + 2; j <= maxj; j += 2)
700 p[0] = in[px + in_stride * j];
701 p[1] = in[px + 1 + in_stride * j] + in[px + in_stride * (j + 1)];
702 p[2] = in[px + 1 + in_stride * (j + 1)];
703 for(
int c = 0; c < 3; c++) col[c] += (1 - dx) *
p[c];
707 for(
int i = px + 2;
i <= maxi;
i += 2)
709 p[0] = in[
i + in_stride * py];
710 p[1] = in[
i + 1 + in_stride * py] + in[
i + in_stride * (py + 1)];
711 p[2] = in[
i + 1 + in_stride * (py + 1)];
712 for(
int c = 0; c < 3; c++) col[c] += (1 - dy) *
p[c];
716 for(
int j = py + 2; j <= maxj; j += 2)
717 for(
int i = px + 2;
i <= maxi;
i += 2)
719 p[0] = in[
i + in_stride * j];
720 p[1] = in[
i + 1 + in_stride * j] + in[
i + in_stride * (j + 1)];
721 p[2] = in[
i + 1 + in_stride * (j + 1)];
722 for(
int c = 0; c < 3; c++) col[c] +=
p[c];
725 if(maxi == px + 2 * samples && maxj == py + 2 * samples)
728 for(
int j = py + 2; j <= maxj; j += 2)
730 p[0] = in[maxi + 2 + in_stride * j];
731 p[1] = in[maxi + 3 + in_stride * j] + in[maxi + 2 + in_stride * (j + 1)];
732 p[2] = in[maxi + 3 + in_stride * (j + 1)];
733 for(
int c = 0; c < 3; c++) col[c] += dx *
p[c];
737 p[0] = in[maxi + 2 + in_stride * py];
738 p[1] = in[maxi + 3 + in_stride * py] + in[maxi + 2 + in_stride * (py + 1)];
739 p[2] = in[maxi + 3 + in_stride * (py + 1)];
740 for(
int c = 0; c < 3; c++) col[c] += (dx * (1 - dy)) *
p[c];
743 for(
int i = px + 2;
i <= maxi;
i += 2)
745 p[0] = in[
i + in_stride * (maxj + 2)];
746 p[1] = in[
i + 1 + in_stride * (maxj + 2)] + in[
i + in_stride * (maxj + 3)];
747 p[2] = in[
i + 1 + in_stride * (maxj + 3)];
748 for(
int c = 0; c < 3; c++) col[c] += dy *
p[c];
752 p[0] = in[px + in_stride * (maxj + 2)];
753 p[1] = in[px + 1 + in_stride * (maxj + 2)] + in[px + in_stride * (maxj + 3)];
754 p[2] = in[px + 1 + in_stride * (maxj + 3)];
755 for(
int c = 0; c < 3; c++) col[c] += ((1 - dx) * dy) *
p[c];
758 p[0] = in[maxi + 2 + in_stride * (maxj + 2)];
759 p[1] = in[maxi + 3 + in_stride * (maxj + 2)] + in[maxi + 2 + in_stride * (maxj + 3)];
760 p[2] = in[maxi + 3 + in_stride * (maxj + 3)];
761 for(
int c = 0; c < 3; c++) col[c] += (dx * dy) *
p[c];
763 num = (samples + 1) * (samples + 1);
765 else if(maxi == px + 2 * samples)
768 for(
int j = py + 2; j <= maxj; j += 2)
770 p[0] = in[maxi + 2 + in_stride * j];
771 p[1] = in[maxi + 3 + in_stride * j] + in[maxi + 2 + in_stride * (j + 1)];
772 p[2] = in[maxi + 3 + in_stride * (j + 1)];
773 for(
int c = 0; c < 3; c++) col[c] += dx *
p[c];
777 p[0] = in[maxi + 2 + in_stride * py];
778 p[1] = in[maxi + 3 + in_stride * py] + in[maxi + 2 + in_stride * (py + 1)];
779 p[2] = in[maxi + 3 + in_stride * (py + 1)];
780 for(
int c = 0; c < 3; c++) col[c] += (dx * (1 - dy)) *
p[c];
782 num = ((maxj - py) / 2 + 1 - dy) * (samples + 1);
784 else if(maxj == py + 2 * samples)
787 for(
int i = px + 2;
i <= maxi;
i += 2)
789 p[0] = in[
i + in_stride * (maxj + 2)];
790 p[1] = in[
i + 1 + in_stride * (maxj + 2)] + in[
i + in_stride * (maxj + 3)];
791 p[2] = in[
i + 1 + in_stride * (maxj + 3)];
792 for(
int c = 0; c < 3; c++) col[c] += dy *
p[c];
796 p[0] = in[px + in_stride * (maxj + 2)];
797 p[1] = in[px + 1 + in_stride * (maxj + 2)] + in[px + in_stride * (maxj + 3)];
798 p[2] = in[px + 1 + in_stride * (maxj + 3)];
799 for(
int c = 0; c < 3; c++) col[c] += ((1 - dx) * dy) *
p[c];
801 num = ((maxi - px) / 2 + 1 - dx) * (samples + 1);
805 num = ((maxi - px) / 2 + 1 - dx) * ((maxj - py) / 2 + 1 - dy);
808 outc[0] = col[0] / num;
809 outc[1] = (col[1] / num) / 2.0f;
810 outc[2] = col[2] / num;
878static inline void mat4inv(
const float X[][4],
float R[][4])
880 const float det = X[0][3] * X[1][2] * X[2][1] * X[3][0] - X[0][2] * X[1][3] * X[2][1] * X[3][0]
881 - X[0][3] * X[1][1] * X[2][2] * X[3][0] + X[0][1] * X[1][3] * X[2][2] * X[3][0]
882 + X[0][2] * X[1][1] * X[2][3] * X[3][0] - X[0][1] * X[1][2] * X[2][3] * X[3][0]
883 - X[0][3] * X[1][2] * X[2][0] * X[3][1] + X[0][2] * X[1][3] * X[2][0] * X[3][1]
884 + X[0][3] * X[1][0] * X[2][2] * X[3][1] - X[0][0] * X[1][3] * X[2][2] * X[3][1]
885 - X[0][2] * X[1][0] * X[2][3] * X[3][1] + X[0][0] * X[1][2] * X[2][3] * X[3][1]
886 + X[0][3] * X[1][1] * X[2][0] * X[3][2] - X[0][1] * X[1][3] * X[2][0] * X[3][2]
887 - X[0][3] * X[1][0] * X[2][1] * X[3][2] + X[0][0] * X[1][3] * X[2][1] * X[3][2]
888 + X[0][1] * X[1][0] * X[2][3] * X[3][2] - X[0][0] * X[1][1] * X[2][3] * X[3][2]
889 - X[0][2] * X[1][1] * X[2][0] * X[3][3] + X[0][1] * X[1][2] * X[2][0] * X[3][3]
890 + X[0][2] * X[1][0] * X[2][1] * X[3][3] - X[0][0] * X[1][2] * X[2][1] * X[3][3]
891 - X[0][1] * X[1][0] * X[2][2] * X[3][3] + X[0][0] * X[1][1] * X[2][2] * X[3][3];
892 R[0][0] = (X[1][2] * X[2][3] * X[3][1] - X[1][3] * X[2][2] * X[3][1] + X[1][3] * X[2][1] * X[3][2]
893 - X[1][1] * X[2][3] * X[3][2] - X[1][2] * X[2][1] * X[3][3] + X[1][1] * X[2][2] * X[3][3])
895 R[1][0] = (X[1][3] * X[2][2] * X[3][0] - X[1][2] * X[2][3] * X[3][0] - X[1][3] * X[2][0] * X[3][2]
896 + X[1][0] * X[2][3] * X[3][2] + X[1][2] * X[2][0] * X[3][3] - X[1][0] * X[2][2] * X[3][3])
898 R[2][0] = (X[1][1] * X[2][3] * X[3][0] - X[1][3] * X[2][1] * X[3][0] + X[1][3] * X[2][0] * X[3][1]
899 - X[1][0] * X[2][3] * X[3][1] - X[1][1] * X[2][0] * X[3][3] + X[1][0] * X[2][1] * X[3][3])
901 R[3][0] = (X[1][2] * X[2][1] * X[3][0] - X[1][1] * X[2][2] * X[3][0] - X[1][2] * X[2][0] * X[3][1]
902 + X[1][0] * X[2][2] * X[3][1] + X[1][1] * X[2][0] * X[3][2] - X[1][0] * X[2][1] * X[3][2])
905 R[0][1] = (X[0][3] * X[2][2] * X[3][1] - X[0][2] * X[2][3] * X[3][1] - X[0][3] * X[2][1] * X[3][2]
906 + X[0][1] * X[2][3] * X[3][2] + X[0][2] * X[2][1] * X[3][3] - X[0][1] * X[2][2] * X[3][3])
908 R[1][1] = (X[0][2] * X[2][3] * X[3][0] - X[0][3] * X[2][2] * X[3][0] + X[0][3] * X[2][0] * X[3][2]
909 - X[0][0] * X[2][3] * X[3][2] - X[0][2] * X[2][0] * X[3][3] + X[0][0] * X[2][2] * X[3][3])
911 R[2][1] = (X[0][3] * X[2][1] * X[3][0] - X[0][1] * X[2][3] * X[3][0] - X[0][3] * X[2][0] * X[3][1]
912 + X[0][0] * X[2][3] * X[3][1] + X[0][1] * X[2][0] * X[3][3] - X[0][0] * X[2][1] * X[3][3])
914 R[3][1] = (X[0][1] * X[2][2] * X[3][0] - X[0][2] * X[2][1] * X[3][0] + X[0][2] * X[2][0] * X[3][1]
915 - X[0][0] * X[2][2] * X[3][1] - X[0][1] * X[2][0] * X[3][2] + X[0][0] * X[2][1] * X[3][2])
918 R[0][2] = (X[0][2] * X[1][3] * X[3][1] - X[0][3] * X[1][2] * X[3][1] + X[0][3] * X[1][1] * X[3][2]
919 - X[0][1] * X[1][3] * X[3][2] - X[0][2] * X[1][1] * X[3][3] + X[0][1] * X[1][2] * X[3][3])
921 R[1][2] = (X[0][3] * X[1][2] * X[3][0] - X[0][2] * X[1][3] * X[3][0] - X[0][3] * X[1][0] * X[3][2]
922 + X[0][0] * X[1][3] * X[3][2] + X[0][2] * X[1][0] * X[3][3] - X[0][0] * X[1][2] * X[3][3])
924 R[2][2] = (X[0][1] * X[1][3] * X[3][0] - X[0][3] * X[1][1] * X[3][0] + X[0][3] * X[1][0] * X[3][1]
925 - X[0][0] * X[1][3] * X[3][1] - X[0][1] * X[1][0] * X[3][3] + X[0][0] * X[1][1] * X[3][3])
927 R[3][2] = (X[0][2] * X[1][1] * X[3][0] - X[0][1] * X[1][2] * X[3][0] - X[0][2] * X[1][0] * X[3][1]
928 + X[0][0] * X[1][2] * X[3][1] + X[0][1] * X[1][0] * X[3][2] - X[0][0] * X[1][1] * X[3][2])
931 R[0][3] = (X[0][3] * X[1][2] * X[2][1] - X[0][2] * X[1][3] * X[2][1] - X[0][3] * X[1][1] * X[2][2]
932 + X[0][1] * X[1][3] * X[2][2] + X[0][2] * X[1][1] * X[2][3] - X[0][1] * X[1][2] * X[2][3])
934 R[1][3] = (X[0][2] * X[1][3] * X[2][0] - X[0][3] * X[1][2] * X[2][0] + X[0][3] * X[1][0] * X[2][2]
935 - X[0][0] * X[1][3] * X[2][2] - X[0][2] * X[1][0] * X[2][3] + X[0][0] * X[1][2] * X[2][3])
937 R[2][3] = (X[0][3] * X[1][1] * X[2][0] - X[0][1] * X[1][3] * X[2][0] - X[0][3] * X[1][0] * X[2][1]
938 + X[0][0] * X[1][3] * X[2][1] + X[0][1] * X[1][0] * X[2][3] - X[0][0] * X[1][1] * X[2][3])
940 R[3][3] = (X[0][1] * X[1][2] * X[2][0] - X[0][2] * X[1][1] * X[2][0] + X[0][2] * X[1][0] * X[2][1]
941 - X[0][0] * X[1][2] * X[2][1] - X[0][1] * X[1][0] * X[2][2] + X[0][0] * X[1][1] * X[2][2])