| 139 | |
| 140 | |
| 141 | void RasterizeGradient( const std::string_view& path, ImageIO::HostBitmap& bitmap ) |
| 142 | { |
| 143 | bitmap.Destroy(); |
| 144 | |
| 145 | if( !IsGradientTexturePath( path ) ) |
| 146 | { |
| 147 | return; |
| 148 | } |
| 149 | |
| 150 | auto data = Base64::Decode( std::string_view( path.data() + gradientPrefix.size(), path.size() - gradientPrefix.size() ) ); |
| 151 | if( data.size() < sizeof( Header ) ) |
| 152 | { |
| 153 | CCP_LOGERR( "Failed to parse dynamic:/gradient_1d/ texture path: the path %s is invalid", std::string( path ).c_str() ); |
| 154 | return; |
| 155 | } |
| 156 | Header* header = reinterpret_cast<Header*>( data.data() ); |
| 157 | auto keyCount = header->r.keyCount + header->g.keyCount + header->b.keyCount + header->a.keyCount; |
| 158 | if( data.size() != sizeof( Header ) + keyCount * sizeof( Tr2CurveScalarKey ) ) |
| 159 | { |
| 160 | CCP_LOGERR( "Failed to parse dynamic:/gradient_1d/ texture path: the path %s is invalid", std::string( path ).c_str() ); |
| 161 | return; |
| 162 | } |
| 163 | if( header->width == 0 ) |
| 164 | { |
| 165 | CCP_LOGERR( "The texture path %s has texture width of zero: the path is invalid", std::string( path ).c_str() ); |
| 166 | return; |
| 167 | } |
| 168 | auto keys = reinterpret_cast<Tr2CurveScalarKey*>( data.data() + sizeof( Header ) ); |
| 169 | Tr2CurveScalarDefinition r = { keys, header->r.keyCount, Tr2CurveExtrapolation::Type( header->r.extrapolationBefore ), Tr2CurveExtrapolation::Type( header->r.extrapolationAfter ) }; |
| 170 | keys += header->r.keyCount; |
| 171 | Tr2CurveScalarDefinition g = { keys, header->g.keyCount, Tr2CurveExtrapolation::Type( header->g.extrapolationBefore ), Tr2CurveExtrapolation::Type( header->g.extrapolationAfter ) }; |
| 172 | keys += header->g.keyCount; |
| 173 | Tr2CurveScalarDefinition b = { keys, header->b.keyCount, Tr2CurveExtrapolation::Type( header->b.extrapolationBefore ), Tr2CurveExtrapolation::Type( header->b.extrapolationAfter ) }; |
| 174 | keys += header->b.keyCount; |
| 175 | Tr2CurveScalarDefinition a = { keys, header->a.keyCount, Tr2CurveExtrapolation::Type( header->a.extrapolationBefore ), Tr2CurveExtrapolation::Type( header->a.extrapolationAfter ) }; |
| 176 | |
| 177 | bitmap.Create( header->width, 1, 1, ImageIO::PIXEL_FORMAT_R16G16B16A16_FLOAT ); |
| 178 | auto pixels = reinterpret_cast<Float_16*>( bitmap.GetRawData() ); |
| 179 | |
| 180 | CTr2CurveScalar curve; |
| 181 | curve.SetDefinition( r ); |
| 182 | curve.Rasterize( { header->width, 4, pixels } ); |
| 183 | curve.SetDefinition( g ); |
| 184 | curve.Rasterize( { header->width, 4, pixels + 1 } ); |
| 185 | curve.SetDefinition( b ); |
| 186 | curve.Rasterize( { header->width, 4, pixels + 2 } ); |
| 187 | curve.SetDefinition( a ); |
| 188 | curve.Rasterize( { header->width, 4, pixels + 3 } ); |
| 189 | } |
| 190 | |
| 191 | |
| 192 | bool IsGradientTexturePath( const wchar_t* path ) |
nothing calls this directly
no test coverage detected