| 737 | } |
| 738 | |
| 739 | void |
| 740 | Lut::from_float_packed(float* to, |
| 741 | const float* from, |
| 742 | const RectI & conversionRect, |
| 743 | const RectI & srcBounds, |
| 744 | const RectI & dstBounds, |
| 745 | PixelPackingEnum inputPacking, |
| 746 | PixelPackingEnum outputPacking, |
| 747 | bool invertY, |
| 748 | bool premult) const |
| 749 | { |
| 750 | if ( ( inputPacking == ePixelPackingPLANAR) || ( outputPacking == ePixelPackingPLANAR) ) { |
| 751 | throw std::runtime_error("Invalid pixel format."); |
| 752 | } |
| 753 | |
| 754 | ///clip the conversion rect to srcBounds and dstBounds |
| 755 | RectI rect = conversionRect; |
| 756 | if ( !clip(&rect, srcBounds) || !clip(&rect, dstBounds) ) { |
| 757 | return; |
| 758 | } |
| 759 | |
| 760 | |
| 761 | bool inputHasAlpha = inputPacking == ePixelPackingBGRA || inputPacking == ePixelPackingRGBA; |
| 762 | bool outputHasAlpha = outputPacking == ePixelPackingBGRA || outputPacking == ePixelPackingRGBA; |
| 763 | int inROffset, inGOffset, inBOffset, inAOffset; |
| 764 | int outROffset, outGOffset, outBOffset, outAOffset; |
| 765 | getOffsetsForPacking(inputPacking, &inROffset, &inGOffset, &inBOffset, &inAOffset); |
| 766 | getOffsetsForPacking(outputPacking, &outROffset, &outGOffset, &outBOffset, &outAOffset); |
| 767 | |
| 768 | int inPackingSize, outPackingSize; |
| 769 | inPackingSize = inputHasAlpha ? 4 : 3; |
| 770 | outPackingSize = outputHasAlpha ? 4 : 3; |
| 771 | |
| 772 | validate(); |
| 773 | |
| 774 | for (int y = rect.y1; y < rect.y2; ++y) { |
| 775 | int srcY = y; |
| 776 | if (invertY) { |
| 777 | srcY = srcBounds.y2 - y - 1; |
| 778 | } |
| 779 | const float *src_pixels = from + (srcY * (srcBounds.x2 - srcBounds.x1) * inPackingSize); |
| 780 | float *dst_pixels = to + (y * (dstBounds.x2 - dstBounds.x1) * outPackingSize); |
| 781 | for (int x = rect.x1; x < rect.x2; ++x) { |
| 782 | int inCol = x * inPackingSize; |
| 783 | int outCol = x * outPackingSize; |
| 784 | float a = (inputHasAlpha && premult) ? src_pixels[inCol + inAOffset] : 1.f;; |
| 785 | float rf = 0., gf = 0., bf = 0.; |
| 786 | if (a > 0.) { |
| 787 | rf = src_pixels[inCol + inROffset] / a; |
| 788 | gf = src_pixels[inCol + inGOffset] / a; |
| 789 | bf = src_pixels[inCol + inBOffset] / a; |
| 790 | } |
| 791 | dst_pixels[outCol + outROffset] = fromColorSpaceFloatToLinearFloat(rf) * a; |
| 792 | dst_pixels[outCol + outGOffset] = fromColorSpaceFloatToLinearFloat(gf) * a; |
| 793 | dst_pixels[outCol + outBOffset] = fromColorSpaceFloatToLinearFloat(bf) * a; |
| 794 | if (outputHasAlpha) { |
| 795 | // alpha is linear |
| 796 | dst_pixels[outCol + outAOffset] = a; |
nothing calls this directly
no test coverage detected