| 947 | } |
| 948 | |
| 949 | std::vector<Uint8> webpPacker( const Image& img, Uint32 quality, Uint32 compressionMethod, |
| 950 | bool lossless ) { |
| 951 | quality = eeclamp( quality, 0u, 100u ); |
| 952 | compressionMethod = eeclamp( quality, 0u, 6u ); |
| 953 | |
| 954 | if ( img.getChannels() < 3 ) |
| 955 | return {}; |
| 956 | |
| 957 | Sizei s( img.getWidth(), img.getHeight() ); |
| 958 | const Uint8* r = img.getPixelsPtr(); |
| 959 | |
| 960 | WebPConfig config; |
| 961 | WebPPicture pic; |
| 962 | if ( !WebPConfigInit( &config ) || !WebPPictureInit( &pic ) ) { |
| 963 | return {}; |
| 964 | } |
| 965 | |
| 966 | WebPMemoryWriter wrt; |
| 967 | if ( lossless ) { |
| 968 | config.lossless = 1; |
| 969 | config.exact = 1; |
| 970 | } |
| 971 | config.method = compressionMethod; |
| 972 | config.quality = quality; |
| 973 | config.use_sharp_yuv = 1; |
| 974 | pic.use_argb = 1; |
| 975 | pic.width = s.getWidth(); |
| 976 | pic.height = s.getHeight(); |
| 977 | pic.writer = WebPMemoryWrite; |
| 978 | pic.custom_ptr = &wrt; |
| 979 | WebPMemoryWriterInit( &wrt ); |
| 980 | |
| 981 | bool successImport = false; |
| 982 | if ( img.getChannels() == 3 ) { |
| 983 | successImport = WebPPictureImportRGB( &pic, r, 3 * s.getWidth() ); |
| 984 | } else { |
| 985 | successImport = WebPPictureImportRGBA( &pic, r, 4 * s.getWidth() ); |
| 986 | } |
| 987 | |
| 988 | bool successEncode = false; |
| 989 | if ( successImport ) { |
| 990 | successEncode = WebPEncode( &config, &pic ); |
| 991 | } |
| 992 | WebPPictureFree( &pic ); |
| 993 | |
| 994 | if ( !successEncode ) { |
| 995 | WebPMemoryWriterClear( &wrt ); |
| 996 | return {}; |
| 997 | } |
| 998 | |
| 999 | // copy from wrt |
| 1000 | std::vector<Uint8> dst; |
| 1001 | dst.resize( wrt.size ); |
| 1002 | Uint8* w = dst.data(); |
| 1003 | memcpy( w, wrt.mem, wrt.size ); |
| 1004 | WebPMemoryWriterClear( &wrt ); |
| 1005 | return dst; |
| 1006 | } |
no test coverage detected