alpha_blend.cc (2082B)
1 // Copyright (c) the JPEG XL Project Authors. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 #include "lib/extras/alpha_blend.h" 7 8 #include "lib/extras/packed_image.h" 9 #include "lib/jxl/base/status.h" 10 11 namespace jxl { 12 namespace extras { 13 14 namespace { 15 16 Status AlphaBlend(PackedFrame* frame, const float background[3]) { 17 if (!frame) return true; 18 const PackedImage& im = frame->color; 19 JxlPixelFormat format = im.format; 20 if (format.num_channels != 2 && format.num_channels != 4) { 21 return true; 22 } 23 --format.num_channels; 24 JXL_ASSIGN_OR_RETURN(PackedImage blended, 25 PackedImage::Create(im.xsize, im.ysize, format)); 26 // TODO(szabadka) SIMDify this and make it work for float16. 27 for (size_t y = 0; y < im.ysize; ++y) { 28 for (size_t x = 0; x < im.xsize; ++x) { 29 if (format.num_channels == 2) { 30 float g = im.GetPixelValue(y, x, 0); 31 float a = im.GetPixelValue(y, x, 1); 32 float out = g * a + background[0] * (1 - a); 33 blended.SetPixelValue(y, x, 0, out); 34 } else { 35 float r = im.GetPixelValue(y, x, 0); 36 float g = im.GetPixelValue(y, x, 1); 37 float b = im.GetPixelValue(y, x, 2); 38 float a = im.GetPixelValue(y, x, 3); 39 float out_r = r * a + background[0] * (1 - a); 40 float out_g = g * a + background[1] * (1 - a); 41 float out_b = b * a + background[2] * (1 - a); 42 blended.SetPixelValue(y, x, 0, out_r); 43 blended.SetPixelValue(y, x, 1, out_g); 44 blended.SetPixelValue(y, x, 2, out_b); 45 } 46 } 47 } 48 frame->color = blended.Copy(); 49 return true; 50 } 51 52 } // namespace 53 54 Status AlphaBlend(PackedPixelFile* ppf, const float background[3]) { 55 if (!ppf || ppf->info.alpha_bits == 0) { 56 return true; 57 } 58 ppf->info.alpha_bits = 0; 59 JXL_RETURN_IF_ERROR(AlphaBlend(ppf->preview_frame.get(), background)); 60 for (auto& frame : ppf->frames) { 61 JXL_RETURN_IF_ERROR(AlphaBlend(&frame, background)); 62 } 63 return true; 64 } 65 66 } // namespace extras 67 } // namespace jxl