97 int32_t ibh, uint8_t *o, int32_t ox, int32_t oy, int32_t ow, int32_t oh,
98 int32_t obw, int32_t obh)
100 const float scalex = iw / (float)ow;
101 const float scaley = ih / (float)oh;
102 const int32_t ix2 =
MAX(ix, 0);
103 const int32_t iy2 =
MAX(iy, 0);
104 const int32_t ox2 =
MAX(ox, 0);
105 const int32_t oy2 =
MAX(oy, 0);
106 const int32_t oh2 =
MIN(
MIN(oh, (ibh - iy2) / scaley), obh - oy2);
107 const int32_t ow2 =
MIN(
MIN(ow, (ibw - ix2) / scalex), obw - ox2);
108 assert((
int)(ix2 + ow2 * scalex) <= ibw);
109 assert((
int)(iy2 + oh2 * scaley) <= ibh);
110 assert(ox2 + ow2 <= obw);
111 assert(oy2 + oh2 <= obh);
112 assert(ix2 >= 0 && iy2 >= 0 && ox2 >= 0 && oy2 >= 0);
113 float x = ix2, y = iy2;
114 for(
int s = 0; s < oh2; s++)
116 int idx = ox2 + obw * (oy2 + s);
117 for(
int t = 0;
t < ow2;
t++)
119 for(
int k = 0;
k < 3;
k++)
121 CLAMP(((int32_t)
i[(4 * (ibw * (int32_t)y + (int32_t)(
x + .5f * scalex)) +
k)]
122 + (int32_t)
i[(4 * (ibw * (int32_t)(y + .5f * scaley) + (int32_t)(
x + .5f * scalex)) +
k)]
123 + (int32_t)
i[(4 * (ibw * (int32_t)(y + .5f * scaley) + (int32_t)(
x)) +
k)]
124 + (int32_t)
i[(4 * (ibw * (int32_t)y + (int32_t)(
x)) +
k)])
177 const dt_iop_roi_t *
const roi_in,
const int32_t out_stride,
178 const int32_t in_stride,
const uint32_t filters)
182 const float px_footprint = 1.f / roi_out->
scale;
186 int trggbx = 0, trggby = 0;
187 if(
FC(trggby, trggbx + 1, filters) != 1) trggbx++;
188 if(
FC(trggby, trggbx, filters) != 0)
190 trggbx = (trggbx + 1) & 1;
193 const int rggbx = trggbx, rggby = trggby;
199 int clut[4][3] = {{0}};
200 for(
int y = 0; y < 2; ++y)
201 for(
int x = 0;
x < 2; ++
x)
203 const int c =
FC(y + rggby,
x + rggbx, filters);
204 assert(clut[c][0] < 2);
205 clut[c][++clut[c][0]] =
x + y * in_stride;
208 for(
int y = 0; y < roi_out->
height; y++)
210 uint16_t *outc =
out + out_stride * y;
212 const float fy = (y + roi_out->
y) * px_footprint;
213 const int miny = (
CLAMPS((
int)floorf(fy - px_footprint), 0, roi_in->
height-3) & ~1u) + rggby;
214 const int maxy =
MIN(roi_in->
height-1, (
int)ceilf(fy + px_footprint));
216 float fx = roi_out->
x * px_footprint;
217 for(
int x = 0;
x < roi_out->
width;
x++,
fx += px_footprint, outc++)
219 const int minx = (
CLAMPS((
int)floorf(
fx - px_footprint), 0, roi_in->
width-3) & ~1u) + rggbx;
220 const int maxx =
MIN(roi_in->
width-1, (
int)ceilf(
fx + px_footprint));
222 const int c =
FC(y,
x, filters);
226 for(
int yy = miny; yy < maxy; yy += 2)
227 for(
int xx = minx; xx < maxx; xx += 2)
229 col += in[clut[c][1] + xx + in_stride * yy];
233 col += in[clut[c][2] + xx + in_stride * yy];
237 if(num) *outc = col / num;
244 const dt_iop_roi_t *
const roi_in,
const int32_t out_stride,
245 const int32_t in_stride,
const uint32_t filters)
249 const float px_footprint = 1.f / roi_out->
scale;
251 const int samples = round(px_footprint / 2);
254 int trggbx = 0, trggby = 0;
255 if(
FC(trggby, trggbx + 1, filters) != 1) trggbx++;
256 if(
FC(trggby, trggbx, filters) != 0)
258 trggbx = (trggbx + 1) & 1;
261 const int rggbx = trggbx, rggby = trggby;
263 for(
int y = 0; y < roi_out->
height; y++)
265 float *outc =
out + out_stride * y;
267 const float fy = (y + roi_out->
y) * px_footprint;
268 int py = (int)fy & ~1;
269 const float dy = (fy - py) / 2;
270 py =
MIN(((roi_in->
height - 6) & ~1u), py) + rggby;
272 int maxj =
MIN(((roi_in->
height - 5) & ~1u) + rggby, py + 2 * samples);
274 for(
int x = 0;
x < roi_out->
width;
x++)
278 const float fx = (
x + roi_out->
x) * px_footprint;
279 int px = (int)
fx & ~1;
280 const float dx = (
fx - px) / 2;
281 px =
MIN(((roi_in->
width - 6) & ~1u), px) + rggbx;
283 const int maxi =
MIN(((roi_in->
width - 5) & ~1u) + rggbx, px + 2 * samples);
289 p[0] = in[px + in_stride * py];
290 p[1] = in[px + 1 + in_stride * py];
291 p[2] = in[px + in_stride * (py + 1)];
292 p[3] = in[px + 1 + in_stride * (py + 1)];
293 for(
int c = 0; c < 4; c++) col[c] += ((1 - dx) * (1 - dy)) *
p[c];
296 for(
int j = py + 2; j <= maxj; j += 2)
298 p[0] = in[px + in_stride * j];
299 p[1] = in[px + 1 + in_stride * j];
300 p[2] = in[px + in_stride * (j + 1)];
301 p[3] = in[px + 1 + in_stride * (j + 1)];
302 for(
int c = 0; c < 4; c++) col[c] += (1 - dx) *
p[c];
306 for(
int i = px + 2;
i <= maxi;
i += 2)
308 p[0] = in[
i + in_stride * py];
309 p[1] = in[
i + 1 + in_stride * py];
310 p[2] = in[
i + in_stride * (py + 1)];
311 p[3] = in[
i + 1 + in_stride * (py + 1)];
312 for(
int c = 0; c < 4; c++) col[c] += (1 - dy) *
p[c];
316 for(
int j = py + 2; j <= maxj; j += 2)
317 for(
int i = px + 2;
i <= maxi;
i += 2)
319 p[0] = in[
i + in_stride * j];
320 p[1] = in[
i + 1 + in_stride * j];
321 p[2] = in[
i + in_stride * (j + 1)];
322 p[3] = in[
i + 1 + in_stride * (j + 1)];
323 for(
int c = 0; c < 4; c++) col[c] +=
p[c];
326 if(maxi == px + 2 * samples && maxj == py + 2 * samples)
329 for(
int j = py + 2; j <= maxj; j += 2)
331 p[0] = in[maxi + 2 + in_stride * j];
332 p[1] = in[maxi + 3 + in_stride * j];
333 p[2] = in[maxi + 2 + in_stride * (j + 1)];
334 p[3] = in[maxi + 3 + in_stride * (j + 1)];
335 for(
int c = 0; c < 4; c++) col[c] += dx *
p[c];
339 p[0] = in[maxi + 2 + in_stride * py];
340 p[1] = in[maxi + 3 + in_stride * py];
341 p[2] = in[maxi + 2 + in_stride * (py + 1)];
342 p[3] = in[maxi + 3 + in_stride * (py + 1)];
343 for(
int c = 0; c < 4; c++) col[c] += (dx * (1 - dy)) *
p[c];
346 for(
int i = px + 2;
i <= maxi;
i += 2)
348 p[0] = in[
i + in_stride * (maxj + 2)];
349 p[1] = in[
i + 1 + in_stride * (maxj + 2)];
350 p[2] = in[
i + in_stride * (maxj + 3)];
351 p[3] = in[
i + 1 + in_stride * (maxj + 3)];
352 for(
int c = 0; c < 4; c++) col[c] += dy *
p[c];
356 p[0] = in[px + in_stride * (maxj + 2)];
357 p[1] = in[px + 1 + in_stride * (maxj + 2)];
358 p[2] = in[px + in_stride * (maxj + 3)];
359 p[3] = in[px + 1 + in_stride * (maxj + 3)];
360 for(
int c = 0; c < 4; c++) col[c] += ((1 - dx) * dy) *
p[c];
363 p[0] = in[maxi + 2 + in_stride * (maxj + 2)];
364 p[1] = in[maxi + 3 + in_stride * (maxj + 2)];
365 p[2] = in[maxi + 2 + in_stride * (maxj + 3)];
366 p[3] = in[maxi + 3 + in_stride * (maxj + 3)];
367 for(
int c = 0; c < 4; c++) col[c] += (dx * dy) *
p[c];
369 num = (samples + 1) * (samples + 1);
371 else if(maxi == px + 2 * samples)
374 for(
int j = py + 2; j <= maxj; j += 2)
376 p[0] = in[maxi + 2 + in_stride * j];
377 p[1] = in[maxi + 3 + in_stride * j];
378 p[2] = in[maxi + 2 + in_stride * (j + 1)];
379 p[3] = in[maxi + 3 + in_stride * (j + 1)];
380 for(
int c = 0; c < 4; c++) col[c] += dx *
p[c];
384 p[0] = in[maxi + 2 + in_stride * py];
385 p[1] = in[maxi + 3 + in_stride * py];
386 p[2] = in[maxi + 2 + in_stride * (py + 1)];
387 p[3] = in[maxi + 3 + in_stride * (py + 1)];
388 for(
int c = 0; c < 4; c++) col[c] += (dx * (1 - dy)) *
p[c];
390 num = ((maxj - py) / 2 + 1 - dy) * (samples + 1);
392 else if(maxj == py + 2 * samples)
395 for(
int i = px + 2;
i <= maxi;
i += 2)
397 p[0] = in[
i + in_stride * (maxj + 2)];
398 p[1] = in[
i + 1 + in_stride * (maxj + 2)];
399 p[2] = in[
i + in_stride * (maxj + 3)];
400 p[3] = in[
i + 1 + in_stride * (maxj + 3)];
401 for(
int c = 0; c < 4; c++) col[c] += dy *
p[c];
405 p[0] = in[px + in_stride * (maxj + 2)];
406 p[1] = in[px + 1 + in_stride * (maxj + 2)];
407 p[2] = in[px + in_stride * (maxj + 3)];
408 p[3] = in[px + 1 + in_stride * (maxj + 3)];
409 for(
int c = 0; c < 4; c++) col[c] += ((1 - dx) * dy) *
p[c];
411 num = ((maxi - px) / 2 + 1 - dx) * (samples + 1);
415 num = ((maxi - px) / 2 + 1 - dx) * ((maxj - py) / 2 + 1 - dy);
418 const int c = (2 * ((y + rggby) % 2) + ((
x + rggbx) % 2));
419 if(num) *outc = col[c] / num;
509 const int32_t out_stride,
510 const int32_t in_stride)
514 const float px_footprint = 1.f / roi_out->
scale;
516 const int samples = round(px_footprint);
518 for(
int y = 0; y < roi_out->
height; y++)
520 float *outc =
out + 4 * (out_stride * y);
522 const float fy = (y + roi_out->
y) * px_footprint;
524 const float dy = fy - py;
527 const int maxj =
MIN(((roi_in->
height - 2)), py + samples);
529 for(
int x = 0;
x < roi_out->
width;
x++)
533 const float fx = (
x + roi_out->
x) * px_footprint;
535 const float dx =
fx - px;
536 px =
MIN(((roi_in->
width - 3)), px);
538 const int maxi =
MIN(((roi_in->
width - 2)), px + samples);
544 p = in[px + in_stride * py];
545 col += ((1 - dx) * (1 - dy)) *
p;
548 for(
int j = py + 1; j <= maxj; j++)
550 p = in[px + in_stride * j];
555 for(
int i = px + 1;
i <= maxi;
i++)
557 p = in[
i + in_stride * py];
562 for(
int j = py + 1; j <= maxj; j++)
563 for(
int i = px + 1;
i <= maxi;
i++)
565 p = in[
i + in_stride * j];
569 if(maxi == px + samples && maxj == py + samples)
572 for(
int j = py + 1; j <= maxj; j++)
574 p = in[maxi + 1 + in_stride * j];
579 p = in[maxi + 1 + in_stride * py];
580 col += (dx * (1 - dy)) *
p;
583 for(
int i = px + 1;
i <= maxi;
i++)
585 p = in[
i + in_stride * (maxj + 1)];
590 p = in[px + in_stride * (maxj + 1)];
591 col += ((1 - dx) * dy) *
p;
594 p = in[maxi + 1 + in_stride * (maxj + 1)];
595 col += (dx * dy) *
p;
597 num = (samples + 1) * (samples + 1);
599 else if(maxi == px + samples)
602 for(
int j = py + 1; j <= maxj; j++)
604 p = in[maxi + 1 + in_stride * j];
609 p = in[maxi + 1 + in_stride * py];
610 col += (dx * (1 - dy)) *
p;
612 num = ((maxj - py) / 2 + 1 - dy) * (samples + 1);
614 else if(maxj == py + samples)
617 for(
int i = px + 1;
i <= maxi;
i++)
619 p = in[
i + in_stride * (maxj + 1)];
624 p = in[px + in_stride * (maxj + 1)];
625 col += ((1 - dx) * dy) *
p;
627 num = ((maxi - px) / 2 + 1 - dx) * (samples + 1);
631 num = ((maxi - px) / 2 + 1 - dx) * ((maxj - py) / 2 + 1 - dy);
634 const float pix = (num) ? col / num : 0.0f;
646 const dt_iop_roi_t *
const roi_in,
const int32_t out_stride,
647 const int32_t in_stride,
const uint32_t filters)
651 const float px_footprint = 1.f / roi_out->
scale;
653 const int samples = round(px_footprint / 2);
656 int trggbx = 0, trggby = 0;
657 if(
FC(trggby, trggbx + 1, filters) != 1) trggbx++;
658 if(
FC(trggby, trggbx, filters) != 0)
660 trggbx = (trggbx + 1) & 1;
663 const int rggbx = trggbx, rggby = trggby;
665 for(
int y = 0; y < roi_out->
height; y++)
667 float *outc =
out + 4 * (out_stride * y);
669 const float fy = (y + roi_out->
y) * px_footprint;
670 int py = (int)fy & ~1;
671 const float dy = (fy - py) / 2;
672 py =
MIN(((roi_in->
height - 6) & ~1u), py) + rggby;
674 const int maxj =
MIN(((roi_in->
height - 5) & ~1u) + rggby, py + 2 * samples);
676 for(
int x = 0;
x < roi_out->
width;
x++)
680 const float fx = (
x + roi_out->
x) * px_footprint;
681 int px = (int)
fx & ~1;
682 const float dx = (
fx - px) / 2;
683 px =
MIN(((roi_in->
width - 6) & ~1u), px) + rggbx;
685 const int maxi =
MIN(((roi_in->
width - 5) & ~1u) + rggbx, px + 2 * samples);
691 p[0] = in[px + in_stride * py];
692 p[1] = in[px + 1 + in_stride * py] + in[px + in_stride * (py + 1)];
693 p[2] = in[px + 1 + in_stride * (py + 1)];
694 for(
int c = 0; c < 3; c++) col[c] += ((1 - dx) * (1 - dy)) *
p[c];
697 for(
int j = py + 2; j <= maxj; j += 2)
699 p[0] = in[px + in_stride * j];
700 p[1] = in[px + 1 + in_stride * j] + in[px + in_stride * (j + 1)];
701 p[2] = in[px + 1 + in_stride * (j + 1)];
702 for(
int c = 0; c < 3; c++) col[c] += (1 - dx) *
p[c];
706 for(
int i = px + 2;
i <= maxi;
i += 2)
708 p[0] = in[
i + in_stride * py];
709 p[1] = in[
i + 1 + in_stride * py] + in[
i + in_stride * (py + 1)];
710 p[2] = in[
i + 1 + in_stride * (py + 1)];
711 for(
int c = 0; c < 3; c++) col[c] += (1 - dy) *
p[c];
715 for(
int j = py + 2; j <= maxj; j += 2)
716 for(
int i = px + 2;
i <= maxi;
i += 2)
718 p[0] = in[
i + in_stride * j];
719 p[1] = in[
i + 1 + in_stride * j] + in[
i + in_stride * (j + 1)];
720 p[2] = in[
i + 1 + in_stride * (j + 1)];
721 for(
int c = 0; c < 3; c++) col[c] +=
p[c];
724 if(maxi == px + 2 * samples && maxj == py + 2 * samples)
727 for(
int j = py + 2; j <= maxj; j += 2)
729 p[0] = in[maxi + 2 + in_stride * j];
730 p[1] = in[maxi + 3 + in_stride * j] + in[maxi + 2 + in_stride * (j + 1)];
731 p[2] = in[maxi + 3 + in_stride * (j + 1)];
732 for(
int c = 0; c < 3; c++) col[c] += dx *
p[c];
736 p[0] = in[maxi + 2 + in_stride * py];
737 p[1] = in[maxi + 3 + in_stride * py] + in[maxi + 2 + in_stride * (py + 1)];
738 p[2] = in[maxi + 3 + in_stride * (py + 1)];
739 for(
int c = 0; c < 3; c++) col[c] += (dx * (1 - dy)) *
p[c];
742 for(
int i = px + 2;
i <= maxi;
i += 2)
744 p[0] = in[
i + in_stride * (maxj + 2)];
745 p[1] = in[
i + 1 + in_stride * (maxj + 2)] + in[
i + in_stride * (maxj + 3)];
746 p[2] = in[
i + 1 + in_stride * (maxj + 3)];
747 for(
int c = 0; c < 3; c++) col[c] += dy *
p[c];
751 p[0] = in[px + in_stride * (maxj + 2)];
752 p[1] = in[px + 1 + in_stride * (maxj + 2)] + in[px + in_stride * (maxj + 3)];
753 p[2] = in[px + 1 + in_stride * (maxj + 3)];
754 for(
int c = 0; c < 3; c++) col[c] += ((1 - dx) * dy) *
p[c];
757 p[0] = in[maxi + 2 + in_stride * (maxj + 2)];
758 p[1] = in[maxi + 3 + in_stride * (maxj + 2)] + in[maxi + 2 + in_stride * (maxj + 3)];
759 p[2] = in[maxi + 3 + in_stride * (maxj + 3)];
760 for(
int c = 0; c < 3; c++) col[c] += (dx * dy) *
p[c];
762 num = (samples + 1) * (samples + 1);
764 else if(maxi == px + 2 * samples)
767 for(
int j = py + 2; j <= maxj; j += 2)
769 p[0] = in[maxi + 2 + in_stride * j];
770 p[1] = in[maxi + 3 + in_stride * j] + in[maxi + 2 + in_stride * (j + 1)];
771 p[2] = in[maxi + 3 + in_stride * (j + 1)];
772 for(
int c = 0; c < 3; c++) col[c] += dx *
p[c];
776 p[0] = in[maxi + 2 + in_stride * py];
777 p[1] = in[maxi + 3 + in_stride * py] + in[maxi + 2 + in_stride * (py + 1)];
778 p[2] = in[maxi + 3 + in_stride * (py + 1)];
779 for(
int c = 0; c < 3; c++) col[c] += (dx * (1 - dy)) *
p[c];
781 num = ((maxj - py) / 2 + 1 - dy) * (samples + 1);
783 else if(maxj == py + 2 * samples)
786 for(
int i = px + 2;
i <= maxi;
i += 2)
788 p[0] = in[
i + in_stride * (maxj + 2)];
789 p[1] = in[
i + 1 + in_stride * (maxj + 2)] + in[
i + in_stride * (maxj + 3)];
790 p[2] = in[
i + 1 + in_stride * (maxj + 3)];
791 for(
int c = 0; c < 3; c++) col[c] += dy *
p[c];
795 p[0] = in[px + in_stride * (maxj + 2)];
796 p[1] = in[px + 1 + in_stride * (maxj + 2)] + in[px + in_stride * (maxj + 3)];
797 p[2] = in[px + 1 + in_stride * (maxj + 3)];
798 for(
int c = 0; c < 3; c++) col[c] += ((1 - dx) * dy) *
p[c];
800 num = ((maxi - px) / 2 + 1 - dx) * (samples + 1);
804 num = ((maxi - px) / 2 + 1 - dx) * ((maxj - py) / 2 + 1 - dy);
807 outc[0] = col[0] / num;
808 outc[1] = (col[1] / num) / 2.0f;
809 outc[2] = col[2] / num;
877static inline void mat4inv(
const float X[][4],
float R[][4])
879 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]
880 - X[0][3] * X[1][1] * X[2][2] * X[3][0] + X[0][1] * X[1][3] * X[2][2] * X[3][0]
881 + X[0][2] * X[1][1] * X[2][3] * X[3][0] - X[0][1] * X[1][2] * X[2][3] * X[3][0]
882 - X[0][3] * X[1][2] * X[2][0] * X[3][1] + X[0][2] * X[1][3] * X[2][0] * X[3][1]
883 + X[0][3] * X[1][0] * X[2][2] * X[3][1] - X[0][0] * X[1][3] * X[2][2] * X[3][1]
884 - X[0][2] * X[1][0] * X[2][3] * X[3][1] + X[0][0] * X[1][2] * X[2][3] * X[3][1]
885 + X[0][3] * X[1][1] * X[2][0] * X[3][2] - X[0][1] * X[1][3] * X[2][0] * X[3][2]
886 - X[0][3] * X[1][0] * X[2][1] * X[3][2] + X[0][0] * X[1][3] * X[2][1] * X[3][2]
887 + X[0][1] * X[1][0] * X[2][3] * X[3][2] - X[0][0] * X[1][1] * X[2][3] * X[3][2]
888 - X[0][2] * X[1][1] * X[2][0] * X[3][3] + X[0][1] * X[1][2] * X[2][0] * X[3][3]
889 + X[0][2] * X[1][0] * X[2][1] * X[3][3] - X[0][0] * X[1][2] * X[2][1] * X[3][3]
890 - X[0][1] * X[1][0] * X[2][2] * X[3][3] + X[0][0] * X[1][1] * X[2][2] * X[3][3];
891 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]
892 - 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])
894 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]
895 + 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])
897 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]
898 - 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])
900 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]
901 + 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])
904 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]
905 + 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])
907 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]
908 - 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])
910 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]
911 + 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])
913 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]
914 - 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])
917 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]
918 - 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])
920 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]
921 + 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])
923 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]
924 - 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])
926 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]
927 + 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])
930 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]
931 + 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])
933 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]
934 - 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])
936 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]
937 + 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])
939 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]
940 - 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])