Compare commits

...

927 Commits

Author SHA1 Message Date
8bacd63a6d Fix OOB write in BuildHuffmanTable.
First, BuildHuffmanTable is called to check if the data is valid.
If it is and the table is not big enough, more memory is allocated.

This will make sure that valid (but unoptimized because of unbalanced
codes) streams are still decodable.

Bug: chromium:1479274
Change-Id: I31c36dbf3aa78d35ecf38706b50464fd3d375741
(cherry picked from commit 902bc91903)
(cherry picked from commit 2af26267cd)
2023-09-07 15:36:52 -07:00
0aa5f755c6 Merge "PaletteSortModifiedZeng: fix leak on error" into 1.2.4 2023-03-01 01:02:47 +00:00
d2d5a51b13 PaletteSortModifiedZeng: fix leak on error
Change-Id: I462bd9a3bc4670efdf251c295f6771a38c08a6ce
(cherry picked from commit 0edbb6ea71)
2023-03-01 00:16:09 +00:00
39219028af EncodeAlphaInternal: clear result->bw on error
This avoids a double free should the function fail prior to
VP8BitWriterInit() and a previous trial result's buffer carried over.
Previously in ApplyFiltersAndEncode() trial.bw (with a previous
iteration's buffer) would be freed, followed by best.bw pointing to the
same buffer.

Since:
187d379d add a fallback to ALPHA_NO_COMPRESSION

In addition, check the return value of VP8BitWriterInit() in this
function.

Bug: webp:603
Change-Id: Ic258381ee26c8c16bc211d157c8153831c8c6910
(cherry picked from commit a486d800b6)
2023-03-01 00:15:55 +00:00
b24b22fbc8 WebPConfig.cmake.in: add find_dependency(Threads)
when WEBP_USE_THREAD=1; this is necessary after:
0d1b9bc4 WEBP_DEP_LIBRARIES: use Threads::Threads

fixes:
CMake Error at WebPTargets.cmake:76 (set_target_properties):
  The link interface of target "WebP::webp" contains:

    Threads::Threads

  but the target was not found.  Possible reasons include:

    * There is a typo in the target name.
    * A find_package call is missing for an IMPORTED target.
    * An ALIAS target is missing.

Bug: webp:583
Change-Id: I19633bcceccacb95be06aa9610512127f3c288a6
Fixed: webp:583
(cherry picked from commit 5dbc4bfa1b)
2023-02-28 03:22:02 +00:00
0d1f12546b update ChangeLog
Change-Id: Ie649805f89f4b483c70462d1aafef01e4dff7bc2
2022-08-05 16:49:26 -07:00
980d24884c update NEWS
Bug: webp:579
Change-Id: I5cc91d6711a1b2feb3dd2d0cd13befee881fe85a
2022-08-04 22:02:45 -07:00
9fde812779 bump version to 1.2.4
libwebp{,decoder} - 1.2.4
libwebp libtool - 8.5.1
libwebpdecoder libtool - 4.5.1

mux - 1.2.4
libtool - 3.10.0

demux - 1.2.4
libtool - 2.11.0

Bug: webp:579
Change-Id: I5fae4184ac6fe4b9c719856080020fd107f18b7f
2022-08-04 22:02:35 -07:00
e626925cef lossless: fix crunch mode w/WEBP_REDUCE_SIZE
WEBP_REDUCE_SIZE was introduced to bring down the library size by
removing cropping and scaling support. Previously WebPPictureView() was
only used with these two, but in
  ec178f2c Add progress hook granularity in lossless
an additional use was added in VP8LEncodeStream() when extra side
configurations are used in crunch mode (-mt, quality == 100 & method ==
6 or quality >= 75 & method == 5 with a palette present currently).

WebPPictureView() and, for coherency, WebPPictureIsView() are
restored in this configuration to avoid affecting the general encode
path.

Previously WebPPictureView() was assumed to always succeed in these
cases which could result in crashes with WEBP_REDUCE_SIZE defined.

Bug: chromium:1345547
Bug: chromium:1345595
Bug: chromium:1345772
Bug: chromium:1345804
Change-Id: Ifecde36a726a434510478a764514b1469942c684
(cherry picked from commit 84163d9d02)
2022-08-03 23:57:12 +00:00
bfad7ab589 CMakeLists.txt: correct libwebpmux name in WebPConfig.cmake
this fixes link errors when using ${WEBP_LIBRARIES} from
WebPConfig.cmake:
/usr/bin/ld: cannot find -llibwebpmux: No such file or directory
/usr/bin/ld: note to link with /tmp/install/lib/libwebpmux.a use
-l:libwebpmux.a or rename it to liblibwebpmux.a

previously mentioned in https://github.com/openwrt/packages/pull/16784

Bug: webp:575
Change-Id: I38b45cb102ef1086ed992178cd736f45acf10d35
2022-07-21 19:12:38 -07:00
c2e3fd30c4 Revert "cmake: fix webpmux lib name for cmake linking"
This reverts commit 13b8281609.

This breaks target name compatibility with earlier releases.

Conflicts:
	CMakeLists.txt

Bug: webp:575
Change-Id: I3d4895b8a8d14b3f4595ec19646ec4a1001c7748
2022-07-21 18:32:17 -07:00
3c4a0fbfbc update ChangeLog
Change-Id: I6c00a2c32e94d886f749fc09e2bdd71acfeb5402
2022-07-15 12:48:16 -07:00
56a480e80c dsp/cpu.h: add missing extern "C"
fixes linking of tests/fuzzer/animencoder_fuzzer on windows

Change-Id: I0bd14b0e8c7ecb261e861689c25cd4b7fdaecbfd
2022-07-08 15:44:39 -07:00
62b45bddcd update ChangeLog
Bug: webp:568
Change-Id: Icdb0657f9d19ba85e6235c6ce9577afa23e0ce21
2022-07-07 15:23:40 -07:00
8764ec7a07 Merge changes Idb037953,Id582e395 into 1.2.3
* changes:
  vwebp: fix file name display in windows unicode build
  webpmux: fix -frame option in windows unicode build
2022-07-07 22:18:26 +00:00
bcb872c31f vwebp: fix file name display in windows unicode build
glutBitmapCharacter() isn't limited to 8-bit characters; add
PrintStringW() to iterate through the file name. This may not fix all
cases, non-existent characters in the font used have no effect.

https://www.opengl.org/resources/libraries/glut/spec3/node76.html#SECTION000111000000000000000

Change-Id: Idb0379539d556a89ec694127f766eb662f09d597
2022-07-05 12:59:06 -07:00
67c44ac5db webpmux: fix -frame option in windows unicode build
-frame takes a file name parameter, use wargv[] like in other paths

Change-Id: Id582e395d3ff9b00bb7fcc0261b475211758f6d4
2022-07-05 11:48:56 -07:00
8278825aac makefile.unix: add sharpyuv objects to clean target
Change-Id: Iad9ac2530bd892681c055e5ae1bf82eb8782d2a2
2022-07-05 10:41:14 -07:00
14a49e018d update NEWS
Bug: webp:568
Change-Id: I0986c33910eba862ef6c1676d7dc58ea6df7ba3b
2022-06-30 19:30:31 -07:00
34b1dc336d bump version to 1.2.3
libwebp{,decoder} - 1.2.3
libwebp libtool - 8.4.1
libwebpdecoder libtool - 4.4.1

mux - 1.2.3
libtool - 3.4.0

demux - 1.2.3
libtool - 2.10.0

Bug: webp:568
Change-Id: I943bae1b7eacb445f6a4e13123e63170ac8bb142
2022-06-30 19:30:31 -07:00
0b397fda9d update AUTHORS
Bug: webp:568
Change-Id: I333e9679d1d9a9c33f94e214b7ab1723e063fe51
2022-06-30 19:30:27 -07:00
c16488ac4a update .mailmap
Bug: webp:568
Change-Id: I34df01bf958ef9de87345e5e43034fafd185f42a
2022-06-30 19:29:53 -07:00
5a2d929cd8 Merge "unicode.h: set console mode before using wprintf" into main 2022-07-01 01:03:01 +00:00
169f867f3c unicode.h: set console mode before using wprintf
This fixes incorrect character display in the file name
in e.g., stats output from cwebp.exe in visual studio builds.

In mingw further changes will be needed as using %s in wfprintf() for
wchar_t pointers is a Microsoft extension that doesn't seem to be
supported with gcc -fms-extensions. %ls works, but will require updating
format strings and wrapping concatenations with TO_W_CHAR() as visual
studio will reject merging string constants of different width.

https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setmode

Change-Id: I57d24c3815f7b5aa3971ac315c65c4458258d706
2022-06-29 22:05:26 -07:00
a94b855c54 Merge "libsharpyuv: add version defines" into main 2022-06-28 09:49:56 +00:00
f83bdb5251 libsharpyuv: add version defines
Change-Id: I2dbe69d1ce5abaf7f5bd83daec99655520b5abad
2022-06-28 11:08:14 +02:00
bef0d79764 unicode_gif.h: fix -Wdeclaration-after-statement
when building for windows with _UNICODE defined

unicode_gif.h|49 col 3| warning: ISO C90 forbids mixed declarations and
code [-Wdeclaration-after-statement]

Change-Id: Ib9f0cc0eba036d6cd4221a4f70a078770dde01d0
2022-06-20 11:40:09 -07:00
404c1622f8 Rename Huffman coding to prefix coding in the bitstream spec
... since no guarantee of Huffman coding can be introduced at decoding
time and encoding didn't actually use Huffman coding in the first place

Bug: webp:551
Change-Id: I400466bb3b4a1d5506353eb3f287d658603164ee
2022-06-16 10:56:03 -07:00
8895f8a345 Merge "run_static_analysis.sh: fix scan-build archive path" into main 2022-06-16 17:27:52 +00:00
92a673d258 Merge "Add -fvisibility=hidden flag in CMakeLists." into main 2022-06-16 08:02:28 +00:00
67c1d72239 Merge "add WEBP_MSAN" into main 2022-06-16 05:11:26 +00:00
1124ff662d Add -fvisibility=hidden flag in CMakeLists.
This way, only functions marked with WEBP_EXTERN get exposed by the library.
This flag is already set in other build configs: configure.ac, makefile.unix,
Android.mk

Change-Id: Iafd8f160e539290e7ea46ceec764a090c6e626a9
2022-06-15 10:03:03 +02:00
e15b356014 add WEBP_MSAN
and use it to suppress a false positive related to data that passes
through RGBA32PackedToPlanar_16b_SSE41(). Current versions (tested with
clang 13.0.1, using -O0 and the build from oss-fuzz of enc_dec_fuzzer)
model shuffles incorrectly reporting use of uninitialized
data related to the alpha change that's removed when converting to YUV.
valgrind behaves correctly, however.

Bug: webp:573
Change-Id: If76997668dcdd436adf280a2e6dcffba766a2875
2022-06-14 21:49:46 -07:00
ec9e782a35 sharpyuv: remove minimum image size from sharpyuv library
libwebp still has a size threshold of 4 pixels in picture_csp_enc.c
but the sharpyuv library itself can handle any image size.

Change-Id: Ic1c78c8f8fae528395fa46a74f717f47cb13098e
2022-06-14 14:55:12 +02:00
7bd07f3b5d run_static_analysis.sh: fix scan-build archive path
move any error reports to the top-level of OUTPUT_DIR rather than
BUILD_DIR

Change-Id: Icb6677c42a89ef86d9d295a27b79a8a591672b87
2022-06-13 16:17:42 -07:00
5ecee06f7a Merge "sharpyuv: increase precision of gamma<->linear conversion" into main 2022-06-02 08:30:18 +00:00
f81dd7d63e Merge changes I3d17d529,I53026880,I1bd61639,I6bd4b25d,Icfec8fba into main
* changes:
  CMake: add src to webpinfo includes
  CMake: add WEBP_BUILD_WEBPINFO to list of checks for exampleutil
  CMake: add WEBP_BUILD_WEBPMUX to list of checks for exampleutil
  CMake: link imageioutil to exampleutil after defined
  WEBP_DEP_LIBRARIES: use Threads::Threads
2022-06-01 18:18:00 +00:00
2d607ee646 sharpyuv: increase precision of gamma<->linear conversion
Change-Id: I261bae3628315bda4ec0dafb8798c7512dd03a36
2022-06-01 15:38:44 +02:00
266cbbc511 sharpyuv: add 32bit version of SharpYuvFilterRow.
This allows increasing intermediate value precision from 10 bits to 14 bits.

Change-Id: I0fc33400d200a849bcc2c677ab8346215a9dbc3b
2022-06-01 13:42:29 +02:00
9fc12274ce CMake: add src to webpinfo includes
Fixes an include error with webp/types.h

Signed-off-by: Christopher Degawa <ccom@randomderp.com>
Change-Id: I3d17d529c904cdb4e5c8ae630e89ed3789791e79
2022-05-31 20:46:21 -05:00
7d18f40ac1 CMake: add WEBP_BUILD_WEBPINFO to list of checks for exampleutil
Signed-off-by: Christopher Degawa <ccom@randomderp.com>
Change-Id: I530268809468107fe29e0f04278791fe7c583208
2022-05-31 17:45:32 -05:00
11309aa54c CMake: add WEBP_BUILD_WEBPMUX to list of checks for exampleutil
Signed-off-by: Christopher Degawa <ccom@randomderp.com>
Change-Id: I1bd6163966d8cec9fc240fa46d41605f11d0c1ac
2022-05-31 17:45:30 -05:00
4bc762f729 CMake: link imageioutil to exampleutil after defined
Signed-off-by: Christopher Degawa <ccom@randomderp.com>
Change-Id: I6bd4b25d31a85839aadef57437faa04966085f52
2022-05-31 17:11:20 -05:00
0d1b9bc433 WEBP_DEP_LIBRARIES: use Threads::Threads
Signed-off-by: Christopher Degawa <ccom@randomderp.com>
Change-Id: Icfec8fba117cbf5668c6f4c7d46d05cbb17e3dea
2022-05-31 17:09:09 -05:00
20ef48f05a Merge "sharpyuv: add support for 10/12/16 bit rgb and 10/12 bit yuv." into main 2022-05-24 11:05:08 +00:00
93c5437115 sharpyuv: add support for 10/12/16 bit rgb and 10/12 bit yuv.
10bit+ input is truncated to 10bits for now.

Change-Id: I7ac00ca54c623d94c76ccd8954418e11095997d2
2022-05-23 20:48:44 +02:00
53cf2b4997 normalize WebPValidatePicture declaration w/definition
quiets a warning under visual studio:
src\enc\picture_enc.c(48) : warning C4028: formal parameter 1 different
from declaration

Change-Id: Ic3affbbb0e22ac8c43fa183e13506eee72e180dc
2022-05-17 09:46:51 -07:00
d3006f4b96 sharpyuv: slightly improve precision
- Remove SHALF constant so that we get back the original value when
  calling UpScale then downscale with rounding
- Make the linear->gamma precomputed table bigger (8 bits rather than 5)
- Round values in kLinearToGammaTabS

Change-Id: Ic9634d32cf93de321d2f6e9e4cad7f156d8d07df
2022-05-17 10:36:44 +02:00
ea967098a4 Merge changes Ia01bd397,Ibf3771af into main
* changes:
  Add an internal WebPValidatePicture.
  Some renamings for consistency.
2022-05-16 17:49:04 +00:00
11bc8410bd Merge changes I2d317c4b,I9e77f6db into main
* changes:
  webp-lossless-bitstream-spec,cosmetics: normalize range syntax
  webp-lossless-bitstream-spec,cosmetics: fix code typo
2022-05-16 17:17:22 +00:00
30453ea4e6 Add an internal WebPValidatePicture.
Change-Id: Ia01bd3975f7bd0d47eb0a1764807baed16f0d268
2022-05-16 17:37:20 +02:00
6c43219a5f Some renamings for consistency.
- pic->picture in public header
- match implementation to declaration in PictureImport, WebPPictureRescale, WebpBlendAlpha

Change-Id: Ibf3771af22d671bba6fd657684add618c6f32978
2022-05-16 17:33:49 +02:00
4f59fa7390 update .mailmap
Change-Id: I246d84d735bc0efada544a9051ddcb3c3a7ceabf
2022-05-14 20:57:41 -07:00
e74f8a62b2 webp-lossless-bitstream-spec,cosmetics: normalize range syntax
[N, M] -> [N..M] the latter is more common in this doc

Bug: webp:551
Change-Id: I2d317c4b8bb31d313123e981f93cd1feb346a98a
2022-05-14 20:51:43 -07:00
5a709ec0d7 webp-lossless-bitstream-spec,cosmetics: fix code typo
code_lengths -> code_length_code_lengths
after:
86f94ee0 Update lossless spec with Huffman codes.

Bug: webp:551
Change-Id: I9e77f6db0fca6fe8294cb31a3015e723050094b5
2022-05-14 20:51:34 -07:00
a2093acc4b webp-lossless-bitstream-spec: add amendment note
for recent changes to color transform, simple code length code, image
structure and details of decoding prefix codes

Bug: webp:551
Change-Id: I36a4d1ee3e25b8a56f5d926f4770374ace99bc2f
2022-05-13 18:50:55 -07:00
86c669303a webp-lossless-bitstream-spec: fix BNF
color cache info precedes the meta huffman info

Bug: webp:551
Change-Id: Ibb69b4ffad6bff5693015be3fe6c600c53fd06c0
2022-05-13 18:41:30 -07:00
232f22da5a webp-lossless-bitstream-spec: fix 'simple code' snippet
based on https://crbug.com/webp/551#c3 & https://crbug.com/webp/551#c4

Bug: webp:551
Change-Id: I4bcc19643b0bdda999247e9c3457d6954a49e35f
2022-05-13 18:41:20 -07:00
44dd765def webp-lossless-bitstream-spec: fix ColorTransform impl
and the corresponding InverseTransform(); the operations were swapped.
The forward transform subtracts the deltas, the inverse adds them.

Bug: webp:551
Change-Id: Ieb90a24f843cee7cdfe46cbb15ec7d716ca9d269
2022-05-13 18:33:16 -07:00
7a7e33e977 webp-lossless-bitstream-spec: fix TR-pixel right border note
the value of the TR-pixel on the right border is the leftmost pixel on
the current row, not the previous one

Bug: webp:551
Change-Id: I157e8c16ce43a9f52c36aa880be1be3bef19c063
2022-05-13 16:48:23 -07:00
86f94ee010 Update lossless spec with Huffman codes.
Bug: webp:551
Change-Id: I28b57c8e87a8023b727fe8359c2e2809cf92752d
2022-05-13 16:42:00 -07:00
a3927cc800 sharpyuv.c,cosmetics: fix indent
+ a few typos in sharpyuv_csp.c

Change-Id: I34b208d10d7808b42afb39b0618fb2e5d76633eb
2022-05-11 11:53:25 -07:00
6c45cef7ff Make sure the stride has a minimum value in the importer.
Bug: webp:569
Change-Id: Ia48d064dbb10e7179ae3da04ca8d769d1c447276
2022-05-10 10:18:46 +02:00
0c8b0e67a4 sharpyuv: cleanup/cosmetic changes
Remove unused constants.
Use ALL_CAPS for defines and kCamelCase for static const values.
Change some defines into static constants if they are not used in array sizes.

Change-Id: I036b0f99215fd0414a33f099bd6b809ff8ee4541
2022-05-09 15:10:14 +02:00
dc3841e077 {histogram,predictor}_enc: quiet int -> float warnings
after:
a19a25bb Replace doubles by floats in lossless misc cost estimations.

Change-Id: Idc5888b40ce5b591b72c6e51a188a9ab8c5d9823
2022-04-20 10:10:27 -07:00
a19a25bb03 Replace doubles by floats in lossless misc cost estimations.
Doubles are slower and use more RAM for no benefit.

Change-Id: I05b313576f9b33388c7c39d7fed8de84170c3753
2022-04-17 21:07:54 +02:00
42888f6c7c Add an option to enable static builds.
The build is not fully static but enough for certain usage.

Change-Id: I269fa40f332365873634b12ac54fd3c36beefd66
2022-04-12 17:50:19 +02:00
7efcf3cc26 Merge "Fix typo in color constants: Marix -> Matrix" into main 2022-04-12 05:08:08 +00:00
8f4b5c62b7 Fix typo in color constants: Marix -> Matrix
Change-Id: Ia5dc8b37ea7ddbb3dba923e24ef07633edb822eb
2022-04-11 14:54:43 -07:00
90084d84f9 Merge "demux,IsValidExtendedFormat: remove unused variable" into main 2022-04-11 20:29:24 +00:00
ed643f619d Merge changes I452d2485,Ic6d75475 into main
* changes:
  SharpYuvComputeConversionMatrix: quiet int->float warnings
  Makefile.vc: add sharpyuv_csp.obj to SHARPYUV_OBJS
2022-04-11 18:54:25 +00:00
8fa053d134 Rename SharpYUV to SharpYuv for consistency.
Change-Id: I21df96b4c8f8fa97bfd2ac9c806c7e5119b55691
2022-04-11 11:55:10 +02:00
99a8756201 SharpYuvComputeConversionMatrix: quiet int->float warnings
under some versions of visual studio:
sharpyuv\sharpyuv_csp.c(43): warning C4244: '=': conversion from 'int' to
'float', possible loss of data
sharpyuv\sharpyuv_csp.c(35): warning C4244: 'initializing': conversion from
'int' to 'float', possible loss of data

Change-Id: I452d24857b43b8a80fae0f339163b4b3965f2d9f
2022-04-09 11:07:09 -07:00
deb426becc Makefile.vc: add sharpyuv_csp.obj to SHARPYUV_OBJS
missed in:
01a05de1a libsharpyuv: add colorspace utilities

Change-Id: Ic6d754757a54dc098d5c761f03480a3766d60db6
2022-04-09 11:06:17 -07:00
779597d443 demux,IsValidExtendedFormat: remove unused variable
quiets -Wunused-but-set-variable

frame_count has been unused in this function since:
ab714b8a demux, Frame: remove is_fragment_ field

Change-Id: Ie6afda915c6b82736e05e7490eba0165c3dd37e4
2022-04-08 15:28:05 -07:00
40e8aa57f8 Merge "libsharpyuv: add colorspace utilities" into main 2022-04-08 09:06:23 +00:00
01a05de1a7 libsharpyuv: add colorspace utilities
Change-Id: I620c8593dc81f39e747de5ed354332adb7278bed
2022-04-08 10:07:22 +02:00
2de4b05a56 Merge changes Id9890a60,I376d81e6,I1c958838 into main
* changes:
  GetBackwardReferences: fail on alloc error
  BackwardReferencesHashChainDistanceOnly: fix segfault on OOM
  VP8LEncodeStream: fix segfault on OOM
2022-04-06 20:04:25 +00:00
b8bca81fb6 Merge "configure.ac: use LT_INIT if available" into main 2022-04-05 16:47:37 +00:00
e8e77b9c47 Merge changes I479bc487,I39864691,I5d486c2c,I186d13be into main
* changes:
  mux{edit,internal}: fix leaks on error
  ExUtilInitCommandLineArguments: fix leak on error
  anim_util: fix leaks on error
  gif2webp: fix segfault on OOM
2022-04-05 05:51:53 +00:00
7e7d5d503a Merge ".gitignore: add Android Studio & VS code dirs" into main 2022-04-04 22:27:07 +00:00
10c5084842 normalize label indent
1 space is most common in the source; this fixes some mixed cases within
lossless files, likely from clang-format

Change-Id: I504206d5bf418781d4131ee73570ecee4e0a69a1
2022-04-04 12:47:41 -07:00
89f774e61d mux{edit,internal}: fix leaks on error
several calls to ChunkSetHead() were unchecked, causing the chunk to
leak should the call fail due to OOM

Tested:
for i in `seq 1 1125`; do
  export MALLOC_FAIL_AT=$i
  ./examples/gif2webp gif_file
  ./examples/gif2webp -mixed gif_file
done
for i in `seq 1 171`; do
  export MALLOC_FAIL_AT=$i
  ./examples/img2webp jpeg_file -o /dev/null
  ./examples/img2webp -mixed jpeg_file -o /dev/null
done

Change-Id: I479bc487f61b493e5ce033872d353007055c172a
2022-04-04 11:26:25 -07:00
2d3293ad76 ExUtilInitCommandLineArguments: fix leak on error
argv_data would leak if the argv_ allocation failed or the MAX_ARGC cap
was hit

Tested:
for i in `seq 1 171`; do
  export MALLOC_FAIL_AT=$i
  ./examples/img2webp jpeg_file -o /dev/null
  ./examples/img2webp -mixed jpeg_file -o /dev/null
done

Change-Id: I39864691e96d5456f324d95a3653bba0f6d6a7be
2022-04-04 11:26:25 -07:00
ec34fd7023 anim_util: fix leaks on error
in ReadAnimatedWebP() & ReadAnimatedGIF() when AllocateFrames() fails
due to OOM

Tested:
for i in `seq 1 278`; do
  export MALLOC_FAIL_AT=$i
  ./examples/anim_diff webp1 webp2
  ./examples/anim_diff gif1 gif2
done

Change-Id: I5d486c2c2982ae088e34a25d8e3e0188df1a9b51
2022-04-04 11:26:25 -07:00
e471728754 gif2webp: fix segfault on OOM
previously calls to WebPPictureCopy() weren't checked, causing a crash
when the canvas copies were accessed later in the loop

Tested:
for i in `seq 1 1125`; do
  export MALLOC_FAIL_AT=$i
  ./examples/gif2webp gif_file
  ./examples/gif2webp -mixed gif_file
done

Change-Id: I186d13be0ec8f3b72b7d247a8482590c1b1be541
2022-04-04 11:26:12 -07:00
e3cfafaf71 GetBackwardReferences: fail on alloc error
previously failures in the call to
VP8LBackwardReferencesTraceBackwards() would be ignored which, though it
wouldn't result in a crash, would produce non-deterministic output

Change-Id: Id9890a60883c3270ec75e968506d46eea32b76d4
2022-04-04 11:24:06 -07:00
a828a59b49 BackwardReferencesHashChainDistanceOnly: fix segfault on OOM
change CostManager to calloc to avoid frees on undefined pointer
values in CostManagerClear() should the cost_model allocation succeed,
but the cost_manager allocation fail

since:
v0.5.0-93-g3e023c17 Speed-up BackwardReferencesHashChainDistanceOnly.

Tested:
for i in `seq 1 639`; do
  export MALLOC_FAIL_AT=$i
  ./examples/cwebp -m 6 -q 100 -lossless jpeg_file
done

Bug: webp:565
Change-Id: I376d81e6f41eb73529053e9e30c142b4b4f6b45b
2022-04-04 11:23:39 -07:00
fe153fae98 VP8LEncodeStream: fix segfault on OOM
initialize bw_side before calling EncoderAnalyze() & EncoderInit() which
may fail; previously this would cause a free of an invalid pointer in
VP8LBitWriterWipeOut().

since at least:
v0.6.0-120-gf8c2ac15 Multi-thread the lossless cruncher.

Tested:
for i in `seq 1 639`; do
  export MALLOC_FAIL_AT=$i
  ./examples/cwebp -m 6 -q 100 -lossless jpeg_file
done

Bug: webp:565
Change-Id: I1c95883834b6e4b13aee890568ce3bad0f4266f0
2022-04-04 11:21:30 -07:00
919acc0ef5 .gitignore: add Android Studio & VS code dirs
Change-Id: I0a8b8124f568df1a4e6bbf96e5a1144b2e7606a1
2022-04-04 10:28:06 -07:00
efa0731b9d configure.ac: use LT_INIT if available
AC_PROG_LIBTOOL is deprecated. quiets a warning from autoconf 2.71:
configure.ac:12: warning: The macro `AC_PROG_LIBTOOL' is obsolete.

Change-Id: I3b131f5ee636a8df48057862e600759f25ad7289
2022-04-04 10:25:26 -07:00
0957fd69ee tiffdec: add grayscale support
the file is always decoded to RGBA, so just the samples_per_px needed an
update

Bug: webp:563
Change-Id: I95d95c3b9e45dc8ecb2223f89f4ba791f0b21e8b
2022-03-31 21:43:29 -07:00
e685feef0c Merge "Make libsharpyuv self-contained by removing dependency on cpu.c" into main 2022-03-31 09:04:06 +00:00
841960b670 Make libsharpyuv self-contained by removing dependency on cpu.c
Change-Id: I2edac1afa38bfddf2a91e7829e38425bd3519feb
2022-03-30 15:04:35 +02:00
617cf03656 image_dec: add WebPGetEnabledInputFileFormats()
and use it to output the types supported in the examples

Change-Id: Ia6b8624a2146cf72c679129065a72f215644e1e9
2022-03-26 15:37:25 -07:00
7a68afaac5 Let SharpArgbToYuv caller pass in an RGB>YUV conversion matrix.
Change-Id: I4ed2dfc00ce63361abd49c693f31f307e0b0262f
2022-03-24 16:37:47 +01:00
34bb332ca1 man/cwebp.1: add note about crop/resize order
+ normalize help text in [cd]webp

Bug: webp:561
Change-Id: Id92ec4228d4933cd033b2bf68a43192532cef483
2022-03-17 16:08:34 -07:00
f0e9351cce webp-lossless-bitstream-spec,cosmetics: fix some typos
Bug: webp:551
Change-Id: I9ff90601b77deb9034ed7bef9cfd421d1f6e2e2b
2022-03-15 17:57:31 -07:00
5ccbd6ed8c vp8l_dec.c,cosmetics: fix a few typos
Change-Id: Ia2906883e7d19bd96f355b4ade98d29ac2efe8cc
2022-03-14 10:15:31 -07:00
c3d0c2d7d8 fix ios build scripts after sharpyuv dep added
in:
d55d447c Make libwebp depend on libsharpyuv.

Change-Id: I8efa679686b792da4cedf23f580152fecfe42275
2022-03-08 19:52:45 -08:00
d0d2292e1a Merge "Make libwebp depend on libsharpyuv." into main 2022-03-07 09:34:37 +00:00
03d1219055 alpha_processing_neon.c: fix 0x01... typo
one instance was overlong leading to a int64->uint32 conversion warning

Change-Id: I56d5ab75d89960c79293f62cd489d7ab519bbc34
2022-03-04 15:26:21 -08:00
d55d447c9a Make libwebp depend on libsharpyuv.
Change-Id: I6d8ebfe1f855024fc0694b1aa584f71fa27b83ae
2022-03-04 11:35:03 +01:00
e4cbcdd2b5 Fix lossless encoding for MIPS.
Bug: webp:558
Change-Id: I3d3ddb64ed26a8d8ff5664664c5f20f6eadfeb4f
2022-03-01 14:01:49 +01:00
924e7ca654 alpha_processing_neon.c: fix Dispatch/ExtractAlpha_NEON
the trailing width % 8 bytes would clear the upper bytes of
alpha_mask as they're done one at a time

since:
49d0280d NEON: implement several alpha-processing functions

Change-Id: Iff76c0af3094597285a6aa6ed032b345f9856aae
2022-02-28 13:57:23 -08:00
0fa0ea5488 Makefile.vc: use /MANIFEST:EMBED
this removes the mt.exe step and may fix some build failures if the
executable is locked after linking, e.g., by an antivirus program

Change-Id: I9a8184f3aaecb62a133a13d9ad3383667bc93fd3
2022-02-19 17:02:31 -08:00
29cc95ce4c Basic version of libsharpyuv in libwebp, in C.
It's self contained apart from a dependency on src/webp/types.h and src/dsp/cpu.h
For now it's only set up as an internal library, not an installable one.
Webp doesn't depend on it yet, the code is only duplicated.

Change-Id: I752799894f9d4105d0d296ddebd9f9641181a1ec
2022-02-18 14:52:44 +00:00
a30f219016 examples/webpmux.c: fix a couple of typos
in the code and help output; the man page is already correct

Change-Id: Id07d32cde24447cf61e1a2b3d55ab4a33549adde
2022-02-17 17:10:08 -08:00
66b3ce239e Fix bad overflow check in ReadTIFF()
See ImgIoUtilCheckSizeArgumentsOverflow() usage at line 199.

Change-Id: Iecad9278446a2f189e287e08512d26a794270a5a
2022-02-15 17:51:14 +01:00
54e61a3864 Markdownify libwebp docs and reorganize them.
Break the main README into into multiple pages in the doc/ directory,
except for the tests, swig and webp_js docs which are in the corresponding
directories.
The webp mux doc is merged into the API doc and the tools doc.

Change-Id: Ia407617dd88094f4662841d37947cfef80799914
2022-02-15 15:31:56 +00:00
b4533debd9 CMakeLists.txt,cosmetics: break long line
Change-Id: Ibe48516e858d4443d9ae43d8a5f6d074c7b07dd8
2022-02-14 10:06:03 -08:00
b9d2f9cd3b quant_enc.c: use WEBP_RESTRICT qualifier
results in code layout changes, a couple fewer instructions; some of the
smaller functions were unaffected as they were inlined, but are updated
for consistency. this mostly affects VP8Decimate(), ReconstructIntra16()
and ReconstructUV().

Change-Id: Icc2582278987a66ad1110bab683d1e0c21e6591a
2022-02-10 11:07:18 -08:00
ec178f2c7f Add progress hook granularity in lossless
A WebPPicture instance is necessary to call WebPReportProgress() which
sets WebPPicture::error_code so as well use WebPEncodingSetError() to
record errors too, instead of functions returning a WebPEncodingError.
However there must be one WebPPicture instance per thread, with error
codes merged at sync time. A mutex could simplify that but it is not
the objective of this change.

https://groups.google.com/a/webmproject.org/g/webp-discuss/c/yOiP8APubgc/m/vCTvxl6ODgAJ

Change-Id: Ia1a8f9d1199202e1c88484ce719b0180a80447ce
2022-02-07 11:00:09 +01:00
26139c7398 Rename MAX_COST to MAX_BIT_COST in histogram_enc.c
To differentiate it with the one in vp8i_enc.h

Change-Id: If4ecc40246cb1c6e42a2ae77328966c4069d441c
2022-02-03 09:57:30 +01:00
13b8281609 cmake: fix webpmux lib name for cmake linking
When using CMake the `<prefix>/usr/share/WebP/cmake/WebPConfig.cmake` gets
used to get the names of the libraries to link against.

Since version 1.2.1 of libwebp, libwebpmux is on by default.
This causes a linker error because the linker arg should be `-lwebpmux`
instead of `-llibwebpmux`.

This is fixable by renaming `libwebpmux` to `webpmux` in a few places.

This was identified after an update to 1.2.1 of libwebp in the OpenWrt
project:
  https://github.com/openwrt/packages/pull/16766

Internally in OpenWrt, this was patched here:
  https://github.com/openwrt/packages/pull/16784

Change-Id: I97501c62b1e97b133a62b04d6516261d6d7c7fd0
Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
2022-01-31 14:38:16 +01:00
88b6a396f1 webp-container-spec.txt,cosmetics: normalize formatting
- prefer Exif to EXIF when not referring to the chunk
- normalize use of code format for canvas / frame width & height

Change-Id: I7fc9e87baeb5d8e719274680ce621dcb078a985f
2022-01-25 18:36:36 -08:00
6f49654024 Merge tag 'v1.2.2'
libwebp-1.2.2

- 1/11/2022: version 1.2.2
  This is a binary compatible release.
  * webpmux: add "-set bgcolor A,R,G,B"
  * add ARM64 NEON support for MSVC builds (#539)
  * fix duplicate include error in Xcode when using multiple XCFrameworks in a
    project (#542)
  * doc updates and bug fixes (#538, #544, #548, #550)

* tag 'v1.2.2':
  update ChangeLog
  libwebp: Fix VP8EncTokenLoop() progress
  BMP enc: fix the transparency case
  libwebp: do not destroy jpeg codec twice on error
  update ChangeLog
  update NEWS
  man/img2webp.1: update date
  Reword img2webp synopsis command line
  anim_decode: fix alpha blending with big-endian
  webpinfo: fix fourcc comparison w/big-endian
  update ChangeLog
  update NEWS
  bump version to 1.2.2
  update AUTHORS

Bug: webp:541, b/202302177
Change-Id: Iae875b6ec3084157837cc774c94088ca72e8dd91
2022-01-20 10:17:37 -08:00
4074acf873 dsp.h: bump msvc arm64 version requirement to 16.6
there was a bug in 16.4 causing compile failures with vtbl4_u8():

src\dsp\lossless_neon.c(105): error C2143: syntax error: missing ')'
before '{'
src\dsp\lossless_neon.c(105): error C2168: 'neon_tbl2_q8': too few
actual parameters for intrinsic function

https://developercommunity.visualstudio.com/t/cannot-compile-arm64-neon-vtbl4-u8-function-in-c-f/859331

Change-Id: I87c21850b3c597aa5cb41a8105b81e2135a9f890
2022-01-19 21:49:59 -08:00
b0a860891d update ChangeLog
Change-Id: I8a18162a178f1686cc8359ce48d90c1c7f65ec91
2022-01-19 15:35:26 -08:00
6db8248c01 libwebp: Fix VP8EncTokenLoop() progress
Encoding the image found in the user bug report below would result in
a progress rising up to 173% because of the extra 20% caused by each
of the 4 extra lossy passes. It happened at methods 3 to 6.

https://groups.google.com/a/webmproject.org/g/webp-discuss/c/yOiP8APubgc/m/FP3r5X2rDAAJ

Change-Id: I95318d0dc4df546044eb926c786c04bb7f915cbe
(cherry picked from commit db25f1b4ed)
2022-01-19 18:07:42 +00:00
827a307fec BMP enc: fix the transparency case
When transparency is present, it's not enough to just write 32bpp samples.
One need to use the full BITMAPV3INFOHEADER syntax and specify the
masks for BGRA.

 see https://en.wikipedia.org/wiki/BMP_file_format#Pixel_storage

Also remove the height-flip trick and write samples bottom-to-top instead.

Change-Id: If5d92c11453b96764b5bfbf19e9678e632bc911f
(cherry picked from commit 480cd51de6)
2022-01-19 18:07:17 +00:00
db25f1b4ed libwebp: Fix VP8EncTokenLoop() progress
Encoding the image found in the user bug report below would result in
a progress rising up to 173% because of the extra 20% caused by each
of the 4 extra lossy passes. It happened at methods 3 to 6.

https://groups.google.com/a/webmproject.org/g/webp-discuss/c/yOiP8APubgc/m/FP3r5X2rDAAJ

Change-Id: I95318d0dc4df546044eb926c786c04bb7f915cbe
2022-01-18 21:12:11 +00:00
286e7fceaa libwebp: do not destroy jpeg codec twice on error
WebPPictureImportRGB() can fail on memory allocation. In this case,
jpeg_destroy_decompress() was already called, so do not go to Error.
Free metadata as an error is returned.

Change-Id: I045b072090e9063d3ad10369ad18b0f08bdffe9f
(cherry picked from commit 6e8a4126f2)
2022-01-17 18:47:10 +00:00
6e8a4126f2 libwebp: do not destroy jpeg codec twice on error
WebPPictureImportRGB() can fail on memory allocation. In this case,
jpeg_destroy_decompress() was already called, so do not go to Error.
Free metadata as an error is returned.

Change-Id: I045b072090e9063d3ad10369ad18b0f08bdffe9f
2022-01-13 14:10:43 +00:00
faf219684c Merge "BMP enc: fix the transparency case" into main 2022-01-12 23:24:23 +00:00
480cd51de6 BMP enc: fix the transparency case
When transparency is present, it's not enough to just write 32bpp samples.
One need to use the full BITMAPV3INFOHEADER syntax and specify the
masks for BGRA.

 see https://en.wikipedia.org/wiki/BMP_file_format#Pixel_storage

Also remove the height-flip trick and write samples bottom-to-top instead.

Change-Id: If5d92c11453b96764b5bfbf19e9678e632bc911f
2022-01-12 07:48:01 +01:00
9195ea0538 update ChangeLog
Bug: webp:541
Change-Id: I6cfb9da3a3944f66efa681cffec7f3e6a84c8800
2022-01-11 18:46:37 -08:00
4acae017bd update NEWS
Bug: webp:541
Change-Id: I529210f8ecaa8f2e9a6fae2518ba71f7fd56a701
2022-01-11 18:45:55 -08:00
883f063397 man/img2webp.1: update date
after:
a80954a1 Reword img2webp synopsis command line

Change-Id: I0a5c18f7947d15fcd66dc32fab9b525186f7fcc5
(cherry picked from commit 1b0c15db02)
2022-01-11 02:03:24 +00:00
567e1f442b Reword img2webp synopsis command line
See https://bugs.chromium.org/p/webp/issues/detail?id=549

Change-Id: I75562d2ad021d8ec107eb4ced5b28e0abf373324
(cherry picked from commit a80954a1d9)
2022-01-11 02:02:57 +00:00
1b0c15db02 man/img2webp.1: update date
after:
a80954a1 Reword img2webp synopsis command line

Change-Id: I0a5c18f7947d15fcd66dc32fab9b525186f7fcc5
2022-01-10 10:57:55 -08:00
17bade381a Merge "Reword img2webp synopsis command line" into main 2022-01-05 12:04:26 +00:00
a80954a1d9 Reword img2webp synopsis command line
See https://bugs.chromium.org/p/webp/issues/detail?id=549

Change-Id: I75562d2ad021d8ec107eb4ced5b28e0abf373324
2022-01-05 10:15:28 +01:00
f084244d9f anim_decode: fix alpha blending with big-endian
images are decoded in RGBA/BGRA, but represented as uint32_t during the
blend process; this fixes the channel extraction

Bug: webp:548
Change-Id: Ie74aa43d8f87d3552d5afc0abba466335f5d1617
(cherry picked from commit e4886716d3)
2021-12-23 14:49:14 +00:00
b217b4fff7 webpinfo: fix fourcc comparison w/big-endian
store the recognized fourccs in little-endian order to match how the
fourcc is being read from the file

Bug: webp:548
Change-Id: I9de77db92208709d5e711846908a51e563102fa5
(cherry picked from commit e3cb052ca5)
2021-12-23 14:48:19 +00:00
ec497b7532 Merge "anim_decode: fix alpha blending with big-endian" into main 2021-12-23 02:36:32 +00:00
e4886716d3 anim_decode: fix alpha blending with big-endian
images are decoded in RGBA/BGRA, but represented as uint32_t during the
blend process; this fixes the channel extraction

Bug: webp:548
Change-Id: Ie74aa43d8f87d3552d5afc0abba466335f5d1617
2021-12-22 17:03:58 -08:00
e3cb052ca5 webpinfo: fix fourcc comparison w/big-endian
store the recognized fourccs in little-endian order to match how the
fourcc is being read from the file

Bug: webp:548
Change-Id: I9de77db92208709d5e711846908a51e563102fa5
2021-12-22 16:01:54 -08:00
a510fedb9a patch-check: detect duplicated files
Change-Id: Ia78425e7f8054d4b0b4e6b365ba0f5887cbcf2d1
Bug: b:185520507
2021-12-17 00:25:43 +00:00
f035d2e40d update ChangeLog
Bug: webp:541
Change-Id: Icd9d0bf1a011263108e899b561f7c8e93dc93e2f
2021-12-15 15:43:43 -08:00
7031946ad8 update NEWS
Change-Id: Id53e61bfb1551b04fe57fd095aa7ef860f60b248
2021-12-14 22:00:58 -08:00
973390b618 bump version to 1.2.2
libwebp{,decoder} - 1.2.2
libwebp libtool - 8.3.1
libwebpdecoder libtool - 4.3.1

mux - 1.2.2
libtool - 3.8.0

demux - 1.2.2
libtool - 2.9.0

Bug: webp:541
Change-Id: Ia9adda28f0320714335156552d0f5b563e1babb6
2021-12-14 19:58:29 -08:00
abd6664fee update AUTHORS
Bug: webp:541
Change-Id: I270b606a16d72dd5012253d932905375692b8eb7
2021-12-14 19:52:01 -08:00
5b7e79303a Merge "add missing USE_{MSA,NEON} checks in headers" into main 2021-12-14 23:39:18 +00:00
02ca04c348 add missing USE_{MSA,NEON} checks in headers
msa_macro.h
neon.h

allows the headers to be built / analyzed under different target
configurations

Change-Id: Ibbcfada210b54988aa5279674d53af8e21fd4a97
2021-12-14 22:21:57 +00:00
e94716e27c xcframeworkbuild.sh: place headers in a subdir
Headers/<framework> rather than Headers/ to avoid a Xcode error when
using multiple frameworks:
  error: Multiple commands produce
    '.../Build/Products/Debug-iphoneos/include/types.h'

WebPMux.xcframework/ios-arm64_i386_x86_64-simulator/Headers/WebPMux
WebPMux.xcframework/ios-arm64_armv7_armv7s/Headers/WebPMux
WebPMux.xcframework/macos-arm64_x86_64/Headers/WebPMux
WebPMux.xcframework/ios-arm64_x86_64-maccatalyst/Headers/WebPMux
WebPDecoder.xcframework/ios-arm64_i386_x86_64-simulator/Headers/WebPDecoder
WebPDecoder.xcframework/ios-arm64_armv7_armv7s/Headers/WebPDecoder
WebPDecoder.xcframework/macos-arm64_x86_64/Headers/WebPDecoder
WebPDecoder.xcframework/ios-arm64_x86_64-maccatalyst/Headers/WebPDecoder
WebPDemux.xcframework/ios-arm64_i386_x86_64-simulator/Headers/WebPDemux
WebPDemux.xcframework/ios-arm64_armv7_armv7s/Headers/WebPDemux
WebPDemux.xcframework/macos-arm64_x86_64/Headers/WebPDemux
WebPDemux.xcframework/ios-arm64_x86_64-maccatalyst/Headers/WebPDemux
WebP.xcframework/ios-arm64_i386_x86_64-simulator/Headers/WebP
WebP.xcframework/ios-arm64_armv7_armv7s/Headers/WebP
WebP.xcframework/macos-arm64_x86_64/Headers/WebP
WebP.xcframework/ios-arm64_x86_64-maccatalyst/Headers/WebP

Bug: webp:542
Change-Id: Ic7e03d85d2119597e422b9cf68b3ac5a892d494d
2021-12-10 19:44:36 -08:00
c846efd888 patch-check: commit subject length check
Change-Id: I7a1c7349f4f461c2384cbd1a62d1aa2e4e3be819
Bug: b:185520507
2021-12-08 18:57:13 +00:00
b6f756e82b update http links
- prefer https

- metadataworkinggroup.org/com seem to be offline; the web archive link
  was obtained from exiftool: https://exiftool.org/TagNames/MWG.html

- fix kramdown link, rubyforge has been gone a long time

- fix png/zlib links

Bug: webp:544
Bug: b/202302177
Change-Id: Id69de4553e7baf00393f12a2c1acb262443a1a93
2021-11-23 10:13:40 -08:00
8f5cb4c18e update rfc links
to https://datatracker.ietf.org/doc/html/... the http tools.ietf.org
links redirect here sometimes, in other cases they 404.

Bug: webp:544
Change-Id: I900972070d6c5659c45a86a89e78b870f42fe5bc
2021-11-17 11:03:35 -08:00
8ea81561d2 change VP8LPredictorFunc signature to avoid reading 'left'
... when it's not available. Even if the value was discarded and
never used, some msan config were complaining about reading it
and passing it around.

Change-Id: Iab8d24676c5bb58e607a829121e36c2862da397c
2021-11-05 16:22:31 +01:00
6b1d18c362 webpmux: fix the -bgcolor description
Change-Id: Iedb1865aec7b8c78c185a0eb17d97a5c9446a275
2021-11-04 22:51:48 +01:00
3368d8768a Merge "webpmux: add "-set bgcolor A,R,G,B"" into main 2021-11-04 19:00:36 +00:00
f213abf620 webpinfo: print the number of warnings
otherwise they can go un-noticed (unless you use -diag).

Change-Id: Ic6faaf09e7993002cdae3e998623764fde860351
2021-11-04 17:09:51 +01:00
50c97c301d webpmux: add "-set bgcolor A,R,G,B"
Similarly to "-set loop <>", this is useful to set
the parameter at global level and not just while assembling
the frames separately.

Change-Id: I79bcbe37f8ff50b9904e78d14011ccbac72f17a1
2021-11-04 15:45:44 +00:00
2c206aaf96 Remove CMakeLists.txt check in compile.sh
Bug: b:185520507
Change-Id: Id573423a9f6960360b9d96950c098ba488e2e9f3
2021-11-02 20:37:11 +00:00
96e3dfef26 Merge "infra/common.sh: add shard_should_run()" into main 2021-10-29 17:08:33 +00:00
0e0f74b7e3 infra/common.sh: add shard_should_run()
Detects whether test block should be run in the current test shard.

if shard_should_run; then
 ...
fi

Bug: b/185520507
Change-Id: I408d226651630a01c5e447dbff7d26b73426ce42
2021-10-28 17:13:11 -07:00
35b7436a21 Jenkins scripts port: update shell function comments
Review function comments style.
https://google.github.io/styleguide/shellguide.html#function-comments

Change-Id: I8c557fd6cb653744d93c28cd28caeef3e4bf10bc
Bug: b:185520507
2021-10-28 01:17:52 +00:00
21d24b4c08 webp-container-spec.txt: remove 'experimental' markers
unknown chunks as a group are well defined in the text

+ remove the Note about stable features as it matched the list given;
there are no WIP features for the format

Change-Id: I11a4de39f9d203b815879f0e9dea9c45b2ae6ff6
2021-10-22 12:17:59 -07:00
cdcf89020e Merge "Port Jenkins script: compile" into main 2021-10-22 04:41:53 +00:00
dc683cdef5 Jenkins scripts port: static analysis
From https://build.webmproject.org/jenkins/view/webp/job/libwebp__static_analysis/

Change-Id: I87846e14351632915a17ee086256dfebdbd656c9
Bug: b:185520507
2021-10-21 00:54:44 +00:00
0858494e96 Port Jenkins script: compile
https://build.webmproject.org/jenkins/view/webp/job/libwebp__compile/

Change-Id: I646e3048cf4e3d8672b66838e31c7ccc53ced60f
Bug: b:185520507
2021-10-21 00:46:57 +00:00
c2cf6a93b0 Jenkins scripts port: android compilation
Port script from https://build.webmproject.org/jenkins/job/libwebp__compile_android/
Change-Id: I4b3f7f15990b5c92971ec5faccc82dca815f92d2
Bug: b:185520507

Change-Id: Ic07f8191db7726e459ee56c04bf6e3776b30b1f7
2021-10-13 18:44:55 +00:00
df0e808fed presubmit: Add pylint-2.7 and .pylintrc
Added files to skip to prevent lint over generated code.

Change-Id: I62de5ec4fa7b6d764df1d8671c0263f668904e52
Bug: b:185520507
2021-10-12 01:01:14 +00:00
676c57dba4 patch-check: shfmt
shfmt is expected to be installed along with go.
GO111MODULE=on go install mvdan.cc/sh/v3/cmd/shfmt@latest

Change-Id: I27004e72f79f71df9405158f77df485f43b028bb
Bug: b:185520494
2021-10-08 05:05:01 +00:00
7bb7f7474e patch-check: Add shellcheck
Shellcheck is expected to be installed because depot_tools does not
provide the tool.

Change-Id: I9c8793cf7e2adedcb1e9f8244b886d6f2a54e2ae
Bug: b:185520494
2021-10-04 23:43:11 +00:00
abcd1797a1 Reformat docstrings and imports
Change-Id: Ie96a21779000a67c272f5e06d2bc11a64b4883f5
Bug: b:185520494
2021-10-04 23:42:35 +00:00
edaf08952d Port Jenkins scripts: compile js
Change-Id: I6d66de114758adccab782870e29a09b66a930ebc
Bug: b:185520507
2021-09-23 22:51:47 +00:00
b96220636b Set CheckPatchFormatted flags to fail on diffs
Change-Id: Ifb826860e27139bc43b4411575e4c2bebcc81239
Bug: b:185520494
2021-09-22 22:44:21 +00:00
e23cd5481c dsp.h: enable NEON w/VS2019+ ARM64 targets
Visual Studio added ARM64 support, but requires arm64_neon.h to be
included rather than arm_neon.h. Visual Studio 2019 addressed this so
we'll start with that version and leave a local adapter include for a
follow up.

Bug: webp:539
Change-Id: If975c029dafffba99210b3bb2d670035a83e8105
2021-09-13 19:56:19 -07:00
3875c7de07 CMakeLists.txt: set minimum version to 3.7
cmake/cpu.cmake (at least) requires 3.7 due to its use of GREATER_EQUAL:
https://cmake.org/cmake/help/latest/release/3.7.html

Bug: webp:538
Change-Id: I63511226a593218e1f4d3b1a7c4c998de3ba2ae1
2021-08-31 13:21:46 -07:00
1a8f0d45d3 Have a hard-coded value for memset in TrellisQuantizeBlock.
Change-Id: I1b842bb0cfec9e8559d0f11b3db8fa1bc1c9692f
2021-08-30 18:50:11 +02:00
934801604e Speed up TrellisQuantizeBlock
- only initialize variable when needed
- perform first loop outside the for loop
- perform computation only if know we are not already worse
- not adding base_score every time

Change-Id: I2cb8231fcaec1113b5902ed61b685f0ae3c78823
2021-08-30 17:07:42 +02:00
45eaacc939 Convert deprecated uint32 to uint32_t.
Change-Id: I057296a7ea90c3eeb9eaf251e08352a8491a591b
2021-08-30 16:06:53 +02:00
42592af875 webp,cmake: Remove unnecessary include dirs
Following crrev.com/c/webm/libwebp/+/3038647

Change-Id: Id43ed9b1cc02a7333bc64e82523122f483c9350a
2021-08-30 09:35:31 +02:00
e298e05f66 Add patch-check steps in PRESUBMIT.py
It substitutes patch-check and style-check by:

- man format checks and warnings
- long lines (max 80, except urls)
- trailing whitespaces
- tab indentation (except make)
- EOL

Change-Id: I33f391bac37c15e995182d735afdbd4efb5c7cae
Bug: b:185520507
2021-08-27 19:32:17 +00:00
29148919e0 Merge tag 'v1.2.1'
libwebp-1.2.1

- 7/20/2021: version 1.2.1
  This is a binary compatible release.
  * minor lossless encoder improvements and x86 color conversion speed up
  * add ARM64 simulator support to xcframeworkbuild.sh (#510)
  * further security related hardening in libwebp & examples
    (issues: #497, #508, #518)
    (chromium: #1196480, #1196773, #1196775, #1196777, #1196778, #1196850)
    (oss-fuzz: #28658, #28978)
  * toolchain updates and bug fixes (#498, #501, #502, #504, #505, #506, #509,
                                     #533)
  * use more inclusive language within the source (#507)

* tag 'v1.2.1':
  update ChangeLog
  fuzzer/*: normalize src/ includes
  fix indent
  update ChangeLog
  dsp/*: use WEBP_HAVE_* to determine Init availability
  update NEWS
  bump version to 1.2.1
  update AUTHORS

Bug: 521, b/188435220
Change-Id: Id6e6781d8da878413c2e57dcae5e2f2841174181
2021-08-13 16:43:13 -07:00
9ce5843dba update ChangeLog
Change-Id: I12c2b718e99087201a57f7ab7cc4c16374e205f6
2021-07-29 15:55:37 -07:00
d9191588ab fuzzer/*: normalize src/ includes
this uses the format introduced to some files in:
cc3577e9 fuzzer/*: use src/ based include paths

Change-Id: I9b5cbeadbb9d54d1e89f474a6e479a5eb3175ed7
(cherry picked from commit c5bc36243a)
2021-07-29 20:15:30 +00:00
c5bc36243a fuzzer/*: normalize src/ includes
this uses the format introduced to some files in:
cc3577e9 fuzzer/*: use src/ based include paths

Change-Id: I9b5cbeadbb9d54d1e89f474a6e479a5eb3175ed7
2021-07-28 13:32:19 -07:00
53b6f76209 fix indent
after:
277d3074 Fix size_t overflow in  WebPRescalerInit

Change-Id: I9adf7f01f28ddd54305512762e2ed28713282966
(cherry picked from commit d2caaba435)
2021-07-28 20:22:18 +00:00
d2caaba435 fix indent
after:
277d3074 Fix size_t overflow in  WebPRescalerInit

Change-Id: I9adf7f01f28ddd54305512762e2ed28713282966
2021-07-28 11:23:45 -07:00
731246ba3b update ChangeLog
Change-Id: Ia3faaafd42eb96e257415e1cf9c7ceb69f851147
2021-07-26 18:19:56 -07:00
d250f01d95 dsp/*: use WEBP_HAVE_* to determine Init availability
after:
  ece18e55 dsp.h: respect --disable-sse2/sse4.1/neon
WEBP_USE_* will be set when a module is targeting a particular
instruction set, e.g., sse4.1, and not overridden if WEBP_HAVE_SSE41 is
set, as previously this would ignore the case where the instruction set
was disabled via config.h and the HAVE macro was unset.

dsp.h not ensures WEBP_HAVE_* are set when WEBP_USE_* to cover cases
where the files are built without config.h.

Change-Id: Ia1c2dcf4100cc1081d968acb6e085e2a1768ece6
(cherry picked from commit 1fe3162541)
2021-07-26 20:44:58 +00:00
1fe3162541 dsp/*: use WEBP_HAVE_* to determine Init availability
after:
  ece18e55 dsp.h: respect --disable-sse2/sse4.1/neon
WEBP_USE_* will be set when a module is targeting a particular
instruction set, e.g., sse4.1, and not overridden if WEBP_HAVE_SSE41 is
set, as previously this would ignore the case where the instruction set
was disabled via config.h and the HAVE macro was unset.

dsp.h not ensures WEBP_HAVE_* are set when WEBP_USE_* to cover cases
where the files are built without config.h.

Change-Id: Ia1c2dcf4100cc1081d968acb6e085e2a1768ece6
2021-07-24 10:19:30 -07:00
3a4d3ecd40 update NEWS
Bug: webp:521
Change-Id: Ic52942bcbfa8aa8e41b95991c0663698884fa8a8
2021-07-20 18:12:28 -07:00
b2bc809346 bump version to 1.2.1
libwebp{,decoder} - 1.2.1
libwebp libtool - 8.2.1
libwebpdecoder libtool - 4.2.1

mux - 1.2.1
libtool - 3.7.0

demux - 1.2.1
libtool - 2.8.0

Bug: webp:521
Change-Id: I098e3e9df698baa275dea85315b9136e565e9971
2021-07-20 18:12:24 -07:00
e542fc7a8a update AUTHORS
Bug: webp:521
Change-Id: Ie2decd9def1a718a01aa1e381ef8f284d18fe279
2021-07-20 18:12:16 -07:00
e024115490 Merge "libwebp/CMake: Add <BUILD_INTERFACE> to webp incl" into main 2021-07-19 20:40:32 +00:00
edea64442c libwebp/CMake: Add <BUILD_INTERFACE> to webp incl
This way target_link_libraries(my_target PUBLIC webp) is enough,
no need to add include directories explicitly for the public headers
such as src/webp/decode.h. This matches the /usr/include/webp/decode.h
installation folder path prefix (#include "webp/decode.h").
See https://bugs.chromium.org/p/webp/issues/detail?id=532

The target_include_directories() calls for cwebp, dwebp etc. may be
unnecessary now and may be removed in another patch.

Change-Id: I2c85218920ffc35ebec23e0dd239f71e29add23b
2021-07-19 18:46:03 +02:00
ece18e5520 dsp.h: respect --disable-sse2/sse4.1/neon
previously this would be overridden if the instruction set was enabled
via -msse4.1, __aarch64__, etc.

Change-Id: I51e87a7da7589c6093d260b848ab41d89ec7b990
2021-07-17 12:14:38 -07:00
a89a3230c9 wicdec: support alpha from WebP WIC decoder
the container check may not be strictly necessary now that the alpha
check has matured and the library will detect usable alpha, but it's
safer to fix this case first before making larger changes.

Bug: webp:533
Change-Id: I2e1ba42156970d579a52bd183707a037e65fd900
2021-07-16 12:19:33 -07:00
26f4aa0115 Merge "alpha_processing: fix visual studio warnings" into main 2021-07-13 23:42:08 +00:00
8f5946634e alpha_processing: fix visual studio warnings
similar to '* const', __restrict needs to be included in the
declaration to avoid warnings like:
src\dsp\alpha_processing.c(429): warning C4028: formal parameter 1
different from declaration

this change also moves WEBP_RESTRICT to dsp.h to avoid a circular
dependency between it and utils.h which already includes dsp.h

Change-Id: Ib070d358a372e76fae4be5445ab288940b9baac0
2021-07-13 23:41:45 +00:00
46d844e6cf Merge "cpu.cmake: fix compiler flag detection w/3.17.0+" into main 2021-07-09 22:22:56 +00:00
298d26eac2 Merge changes I593adf92,If20675e7,Ifac68eac into main
* changes:
  configure: enable libwebpmux by default
  configure: add informational notices when disabling binaries
  configure: move lib flag checks before binaries
2021-07-08 05:35:24 +00:00
a1e5dae0f0 alpha_processing*: use WEBP_RESTRICT qualifier
this helps both auto-vectorization in the C code and the optimized code
generation

Change-Id: Ide570d6be45125ffef7248bdc40e9eb08f00e832
2021-07-07 15:39:21 -07:00
327ef24fbd cpu.cmake: fix compiler flag detection w/3.17.0+
Between 3.17.0 and 3.18.2 check_cxx_compiler_flag() sets a normal
variable at parent scope while check_cxx_source_compiles() continues to
set an internal cache variable, so we unset both to avoid the failure /
success state persisting between checks.

This was fixed in 3.18.3 [1], but regressed shortly afterward [2];
currently seen with 3.20.0 installed via homebrew.

[1] https://gitlab.kitware.com/cmake/cmake/-/issues/21207
[2]
90dead024c CheckCompilerFlag: unified way to check compiler flags per language

Change-Id: I57282f89b07a9cfd85aca7569380f7d115c0b3cf
2021-07-05 18:16:55 -07:00
f70819de51 configure: enable libwebpmux by default
this will provide the main libraries and their supporting examples by
default if external library requirements (e.g., gif2webp+libgif) are
met.

Bug: webp:501
Change-Id: I593adf9222698e2dc5a2199909949c7fea1273b2
2021-07-03 15:58:09 -07:00
dc7e2b42e7 configure: add informational notices when disabling binaries
this better documents the requirements for some of the examples.

Bug: webp:501
Change-Id: If20675e71ebf2c1d9bb51d65a05fd4e9f339ac5a
2021-07-03 15:58:04 -07:00
9df23dddc2 configure: move lib flag checks before binaries
this ensures the defaults are set properly before testing conditions for
enabling certain binaries. previously anim_diff would need
--enable-libwebpdemux to be explicitly added though it defaults to
enabled.

Bug: webp:501
Change-Id: Ifac68eac7096b39e98d0025e07a37b0be3d32c0a
2021-07-03 15:58:01 -07:00
a2e18f10eb Merge "WebPConfig.config.in: correct WEBP_INCLUDE_DIRS" into main 2021-06-29 18:56:36 +00:00
e1a8d4f3fe Merge "bit_reader_inl_utils: uniformly apply WEBP_RESTRICT" into main 2021-06-28 23:19:21 +00:00
4de35f4383 rescaler.c: fix alignment
Change-Id: Ifc2d0d301280baaa403fcdf8722fce42d28a1853
2021-06-28 11:08:50 +02:00
0f13eec7bf bit_reader_inl_utils: uniformly apply WEBP_RESTRICT
this can help with some aliasing issues with some versions of clang/gcc,
similar to:
3e265136 Add WEBP_RESTRICT & use it in VP8BitReader

Change-Id: I863e53cc9d707c9a4b21373ca743c3089aed012e
2021-06-26 10:53:01 -07:00
277d30749f Fix size_t overflow in WebPRescalerInit
we need to surface potential error up, so lot of signature changes.

Change-Id: I7c11a46c4542564d06417203cd1158754e30a9e4
2021-06-25 14:54:42 -07:00
97adbba513 WebPConfig.config.in: correct WEBP_INCLUDE_DIRS
this should be the full path to the installed headers to be added to the
client code's search path, e.g., /usr/local/include when including
<webp/decode.h>

Bug: webp:509
Change-Id: I756249876d8de421c9a33513221fb635157560ef
2021-06-25 10:49:14 -07:00
b60d460318 advanced_api_fuzzer: add extreme config value coverage
this enables cases that might trigger overflows, but increases the risk
of OOM and timeouts

Bug: chromium:1196850
Change-Id: I317b5109525646731e762faa3c34ed28a27595dc
2021-06-23 18:53:05 -07:00
72fe52f623 anim_encode.c,cosmetics: normalize indent
Change-Id: Iba33a60850ec481b73b7eccb67492e7f1dd3d10e
2021-06-23 15:14:04 -07:00
116d235c30 anim_encode: Fix encoded_frames_[] overflow
Check encoded_frames_ count and call FlushFrames if necessary after
IncreasePreviousDuration. Avoids an overflow in encoded_frames_[] with
-kmax 0 and an assertion failure related to the previous and keyframe
durations when a frame is forced in this way.

Based on patch by tomwei7g <at> gmail

Bug: webp:518
Change-Id: Idef685e6c06a67d48fcdc048265ca0e672a01263
2021-06-23 15:13:43 -07:00
6f445b3e3d CMake: set CMP0072 to NEW
Silences CMake's warning and uses GLVND, which still works for linux

Signed-off-by: Christopher Degawa <ccom@randomderp.com>
Change-Id: Iadd173b41c4fbcdff9fe512f9a7dbf70a6d95bcd
2021-06-21 21:25:28 -05:00
b1cf887f86 define WEBP_RESTRICT for MSVC
__restrict is supported:
https://docs.microsoft.com/en-us/cpp/cpp/extension-restrict?view=msvc-160

+ add a comment and simplify the __restrict__ check, clang defines
__GNUC__

Change-Id: I76d8d3cbd1b730f492c6fc0b2114f1897886b677
2021-06-18 19:30:38 -07:00
3e26513656 Add WEBP_RESTRICT & use it in VP8BitReader
Marking the `VP8BitReader` as `__restrict__` helps the compiler generate
better code avoiding issues related to aliasing (re-loads/stores).

Change-Id: Ib7178f57e27e5f40572efc3e567cdf994ea6d928
2021-06-18 19:28:54 -07:00
f6d2924757 vp8l_dec::ProcessRows: fix int overflow in multiply
use 64-bit math in calculating the offsets as they may exceed 32-bits
when scaling

Bug: chromium:1196850
Change-Id: I6a484fc4dded6f6c4b82346ef145eb69c1477b3c
2021-06-16 10:50:44 -07:00
de3b4ba813 CMake: add WEBP_BUILD_LIBWEBPMUX
Adds an additional option similar to configure's --enable-libwebpmux
to toggle building libwebpmux separate from the binaries

Signed-off-by: Christopher Degawa <ccom@randomderp.com>
Change-Id: I0443b84eea36d86791e2e421a6fc0070879a7bef
2021-06-16 16:55:45 +00:00
7f09d3d132 CMakeLists.txt: rm libwebpmux dep from anim_{diff,dump}
Change-Id: Ic293affca5a3e17afbfcda5e96eb101d005621b8
2021-06-16 04:40:21 +00:00
4edea4a695 Init{RGB,YUV}Rescaler: fix a few more int overflows
promote out_width to size_t before multiplying

src/dec/io_dec.c:301:30: runtime error: signed integer overflow: 2 *
1224167500 cannot be represented in type 'int'
  #0 0x55fd9e8de2bd in InitYUVRescaler src/dec/io_dec.c:301:30
  #1 0x55fd9e8de2bd in CustomSetup src/dec/io_dec.c:571:54

Bug: chromium:1196850
Change-Id: I70d0aac1b5eef163a3f353b721fb9ab561e02040
2021-06-14 12:22:28 -07:00
c9e26bdb35 rescaler_utils: set max valid scaled w/h to INT_MAX/2
this will avoid the potential for some integer overflows in rescaler
calculations

Bug: chromium:1196850
Change-Id: Iaa09f5d6b888b39aaeb2154d470279620362d6eb
2021-06-14 12:22:28 -07:00
28d488e6f1 utils.h: add SizeOverflow()
this normalizes the 'size != (size_t)size' checks in the libraries.

Change-Id: I1e8ccd0d3697266f23911ecf0f7a546f011befde
2021-06-14 12:22:28 -07:00
695bdaa2f6 Export/EmitRescaledRowsRGBA: fix pointer offset int overflow
in Export increment the dst pointer, but in EmitRescaledRowsRGBA use
64-bit math as the number of output lines is variable and may still
overflow when incrementing.

Bug: chromium:1196850
Change-Id: I5c65b875894ee9da0fef1e24d27e507171800c4a
2021-06-14 12:22:21 -07:00
685d073ee1 Init{RGB,YUV}Rescaler: fix int overflows in multiplication
with large sizes the intermediate calculations may exceed 32-bits

src/dec/io_dec.c:491:17: runtime error: signed integer overflow: 3 *
788529152 cannot be represented in type 'int'
  #0 0x557a3ad972b2 in InitRGBRescaler src/dec/io_dec.c:491:17
  #1 0x557a3ad972b2 in CustomSetup src/dec/io_dec.c:563:29

Bug: chromium:1196850
Change-Id: Iaf2e8a6de9481dfea31dcd7fccb2d4eca767bddf
2021-06-10 15:26:44 -07:00
d38bd0dda0 WebPFlipBuffer: fix integer overflow
with large scale values the offset to the end of the buffer may exceed
32-bits range.

src/dec/buffer_dec.c:158:39: runtime error: signed integer overflow: 2 *
1275068416 cannot be represented in type 'int'
  #0 0x56444802bea5 in WebPFlipBuffer src/dec/buffer_dec.c:158:39

Bug: chromium:1196850
Change-Id: I08c8b69ada5d5dd3e9bf2b9006dffa0c5f2103a5
2021-06-10 15:26:34 -07:00
109ff0f100 utils: allow MALLOC_LIMIT to indicate a max
in addition to checking the environment for "MALLOC_LIMIT"; the
environment will still take precedence.
this is in preparation for adding extreme config value coverage to
advanced_api_fuzzer

Bug: chromium:1196850
Change-Id: Ibe22f5e39e030a422fd6e383269bde35252d3fae
2021-06-07 18:59:39 -07:00
a2fce86744 WebPRescalerImportRowExpand_C: promote some vals before multiply
avoids integer overflow in extreme cases:
src/dsp/rescaler.c:45:32: runtime error: signed integer overflow: 129 *
16777215 cannot be represented in type 'int'
    #0 0x556bde3538e3 in WebPRescalerImportRowExpand_C src/dsp/rescaler.c:45:32
    #1 0x556bde357465 in RescalerImportRowExpand_SSE2 src/dsp/rescaler_sse2.c:56:5
    ...

Bug: chromium:1196850
Change-Id: I4f923807f106713e113f3eec62a1d1c346066345
2021-06-07 18:59:33 -07:00
776983d427 AllocateBuffer: fix int multiplication overflow check
after the check using 64-bit math we used a signed integer in the
multiplication. previously unsigned integer max was tested.

fixes cases like:
src/dec/buffer_dec.c:108:16: runtime error: signed integer overflow:
944731466 * 4 cannot be represented in type 'int'
    #0 0x55e56187dc1d in AllocateBuffer src/dec/buffer_dec.c:108:16
    #1 0x55e56187dc1d in WebPAllocateDecBuffer src/dec/buffer_dec.c:216:12
    ...

Bug: chromium:1196850
Change-Id: I6e5b3e5d1d5b50b5c98c39bbf9813a63fedc5ca7
2021-06-07 18:59:24 -07:00
315abbd60b Merge "Revert "Do not use a palette for one color images."" 2021-05-24 18:53:42 +00:00
eae815d0d1 Merge changes Ica3bbf75,I82f82954
* changes:
  cosmetics: remove use of 'sanity' / 'master'
  WebPAnimEncoderNewInternal: remove some unnecessary inits
2021-05-24 18:53:20 +00:00
afbca5a152 Require Emscripten 2.0.18
Change-Id: I04fe7041fcd82d08416c37a6e95c36acb70c39dc
2021-05-24 10:35:36 -07:00
3320416b2e CMakeLists,emscripten: use EXPORTED_RUNTIME_METHODS
rather than EXTRA_EXPORTED_RUNTIME_METHODS. this was deprecated in
2.0.18.

quiets a warning:
emcc: warning: EXTRA_EXPORTED_RUNTIME_METHODS is deprecated, please use
EXPORTED_RUNTIME_METHODS instead [-Wdeprecated]

https://emscripten.org/docs/introducing_emscripten/release_notes.html?highlight=exported_runtime_methods

Change-Id: I3acf22339a64f39a342051841a147744f6af954a
2021-05-21 15:09:04 -07:00
29145ed692 Update README instructions for using Emscripten
- Point to a newer URL
- Use emcmake and emmake (which will set the CMake project file)

Change-Id: I3341b9f8e741436bc5961fbc77586963f3241c7a
2021-05-21 11:47:01 -07:00
1f5791398c cosmetics: remove use of 'sanity' / 'master'
replace with more inclusive terms or remove the comment entirely if the
meaning was already clear.

Bug: webp:507
Change-Id: Ica3bbf751ebf79f6668df6e6209af770248ff4ca
2021-05-21 10:38:40 -07:00
29b6129c78 WebPAnimEncoderNewInternal: remove some unnecessary inits
enc is allocated with WebPSafeCalloc so there's no need to clear the
pointers afterward.
this has the side-effect of removing a non-inclusive term.

Bug: webp:507
Change-Id: I82f82954936638c4c15d33b2d6f0497a6a13571f
2021-05-21 10:31:50 -07:00
b60869a18e Revert "Do not use a palette for one color images."
This reverts commit b6513fbaa8.

This change can produce files that can cause decode failures in some
versions of chrome and safari/ios/macos.

https://chromium-review.googlesource.com/c/chromium/src/+/2876279

The chrome fix will be available in M92. This change can be revisited
after it and the mac updates are more widely deployed.

Bug: b/186640109,b/188702956
Change-Id: I296b8fe88c6c48219e3edf532226c4f972f1605b
2021-05-21 10:26:37 -07:00
6fb4cddc93 demux: move padded size calc post unpadded validation
though the max chunk/payload sizes were checked and would fail the
padded size was being calculated beforehand which could result in a
(harmless) unsigned int overflow warning.

Bug: webp:508
Change-Id: I4fa30ded2b027c1577b03049a2deeb7bf75e5472
2021-05-15 10:59:06 -07:00
05b72d4205 vp8l_enc.c: normalize index types
fixes conversion warnings in visual studio after:
b1674240 Add modified Zeng's method to palette sorting.

src\enc\vp8l_enc.c(296) : warning C4244: '=' : conversion from 'const
uint16_t' to 'uint8_t', possible loss of data
src\enc\vp8l_enc.c(299) : warning C4244: '=' : conversion from 'const
uint16_t' to 'uint8_t', possible loss of data

Change-Id: I981b1ba4912edbbafbd49f1f5b1043bf12266920
2021-04-28 15:09:34 -07:00
b6513fbaa8 Do not use a palette for one color images.
1 color images now always take 30 bytes.

Change-Id: Ifa86bc5320362c659672b3836160353d63576467
2021-04-28 13:14:28 +02:00
98bbe35b51 Fix multi-threading with palettes.
Change-Id: Ifa23378c1f9c489d5963b4928781e104a14eb01a
2021-04-27 16:54:03 +02:00
b1674240f9 Add modified Zeng's method to palette sorting.
Also add palette sorting to crunch configurations.

Change-Id: I010a8bf8f1921279db6e9c7209307d8d19a4d105
2021-04-27 13:11:18 +02:00
88c90c4528 add CONTRIBUTING.md
this contains some of the basics for contributing patches to the
project. over time the instructions from
https://www.webmproject.org/code/contribute/submitting-patches/ can be
added here.

Change-Id: Ib5fcbc818c6feb87654517fdd7118f226c5cccc3
2021-04-23 18:35:44 -07:00
6a9916d734 WebPRescalerInit: add missing int64_t promotion
large values of x_add and y_add may rollover an int causing a later
assertion to fail in WebPRescalerExportRow due to fxy_scale incorrectly
being set to 0.

fixes:
src/dsp/rescaler.c:178: void WebPRescalerExportRow(WebPRescaler *const):
Assertion `wrk->src_height == wrk->dst_height && wrk->x_add == 1'
failed.

Bug: chromium:1196480
Change-Id: I2c00f015d61a1257033d8edb1edd4d060d6878b7
2021-04-23 11:46:45 -07:00
b6cf52d5b8 WebPIoInitFromOptions: treat use_scaling as a bool
this matches the description in WebPDecoderOptions and prevents a
mismatch between the user supplied options and the ones used by io.

Bug: chromium:1196773, chromium:1196775, chromium:1196480
Change-Id: I3603b806884cfc6969b093d06b7980b0cc13199b
2021-04-23 11:46:45 -07:00
3b12b7f4b4 WebPIoInitFromOptions: treat use_cropping as a bool
this matches the description in WebPDecoderOptions and prevents a
mismatch between the user supplied options and the ones used by io.

Bug: chromium:1196480
Change-Id: Id464f999d737078078f9d21afe25b349317f5ab4
2021-04-23 11:46:45 -07:00
595fa13f83 add WebPCheckCropDimensions()
and avoid integer overflow in test of x/width and y/height parameters
against the image width/height

Bug: chromium:1196778, chromium:1196777, chromium:1196480
Change-Id: I7b8f1f4dbebfe073b1ba260b8317979488655dcc
2021-04-23 11:46:45 -07:00
8fdaecb09d Disable cross-color when palette is used.
With palette+predictors, cross-color was forced (because of predictors).
No need for cross-color for palettes as R/B==0.
This saves 10 bytes per image that uses palette+predictors.

Change-Id: If2184d16cdabe1e8498009062284ad3e37ef1342
2021-04-23 17:43:36 +02:00
8933bac212 WebPIoInitFromOptions: respect incoming bypass_filtering val
if bypass_filtering was set to 1 in the user provided options it
shouldn't be reset in the use_scaling pass even if the image satisfies
the scaling requirements.

Change-Id: I036029907886acb63748872d5f8763954a7c607b
2021-04-19 19:02:13 -07:00
7d416ff085 webpdec,cosmetics: match error text to function call
WebPINewDecoder -> WebPIDecode

Change-Id: I5c17486ce2598a5dda687d7bc579daf7630c2133
2021-04-17 15:13:43 -07:00
ec6cfeb51e Fix typo on WebPPictureAlloc() in README
Change-Id: I4435a6a2e53495e475f7f833b7d38b6a29ed73d1
2021-04-15 19:11:49 +02:00
7e58a1a260 *.cmake: add license header
this syncs the files with CMakeLists.txt

Change-Id: I94d45ef61d33ee9e43973b5d4e85fab007941f67
2021-04-12 17:28:15 -07:00
5651a6b2ed cmake: fix .so versioning
libtool uses -version-info current:revision:age, but the library created
is [c-a].a.r.

Change-Id: Icf081e156a818a3cd7579ad5ffe3b518d8532bdb
2021-04-07 13:51:22 -07:00
25ae67b3de xcframeworkbuild.sh: add arm64 simulator target
this fixes simulator builds on an M1

Bug: webp:510
Change-Id: Ia2c81d33d9a85b432b17f22305b110ccc337b809
2021-03-15 15:25:44 -07:00
5d4ee4c3c0 cosmetics: remove use of the term 'dummy'
this is replaced with more inclusive / informative text

Bug: webp:507
Change-Id: Ib77f0c79dd548601bf2bc3169985af4b5edf0a62
2021-03-15 11:39:06 -07:00
01b38ee19a faster CollectColorXXXTransforms_SSE41
3/4% faster overall.

Change-Id: If555c5530238ca0342b8d97b0d708b1bdc888d3f
2021-02-19 20:45:07 +01:00
652aa34424 Merge "Use BitCtz for FastSLog2Slow_C" 2021-02-19 17:39:30 +00:00
0320e1e36f add the missing default BitsCtz() code
Change-Id: Iff3ea946a380837b9dfad58350173b68b45e1347
2021-02-19 17:04:35 +00:00
8886f620c0 Use BitCtz for FastSLog2Slow_C
Change-Id: Icc6068b8934e481e6f17efd30616392e68d504ad
2021-02-19 15:11:42 +01:00
fae416179e faster CombinedShannonEntropy_SSE2
optimized for sparse histograms

Change-Id: I54412f5f8fc53d2598964a5be91f6c54ece3f21b
2021-02-19 13:14:46 +01:00
5bd2704e30 Introduce the BitCtz() function.
* Use a WEBP_HAVE_SLOW_CLZ_CTZ flag when they are slow (LUT-based).

Change-Id: If707c121b8800438be404594a39bb123ef25b0f0
2021-02-19 11:52:05 +01:00
fee642870e Merge "wicdec,icc: treat unsupported op as non-fatal" 2021-02-18 21:28:47 +00:00
33ddb894b1 lossless_sse{2,41}: remove some unneeded includes
Change-Id: Icd2cffd32b39c6bf017eee353ac04a4b6d337a11
2021-02-18 10:54:09 -08:00
b27ea8525a wicdec,icc: treat unsupported op as non-fatal
ICC extraction via GetColorContexts may fail due to the operation not
being supported with e.g., bitmaps.

Bug: webp:506
Change-Id: I587220e688ac90d77c84af21c9e7bc8bf178f3aa
2021-02-18 10:36:13 -08:00
b78494a933 Merge "Fix undefined signed shift." 2021-02-18 16:51:17 +00:00
e79974cd6a Fix undefined signed shift.
Using the fix from SSE2.

Change-Id: Ie53d0163d97322da5a722c3e49f9d5f057ee1d91
2021-02-18 16:56:22 +01:00
a885339448 SSE4.1 versions of BGRA to RGB/BGR color-space conversions
Change-Id: Iacafd2f6402080b02fcbf75831e69c488f447454
2021-02-18 15:32:30 +01:00
a09a647241 SSE4.1 version of TransformColorInverse
Change-Id: I6ba5cb35917eef7a52152c4924eca205b4af7220
2021-02-18 12:42:39 +01:00
401da22bd6 Merge "pngdec: check version before using png_get_chunk_malloc_max" 2021-02-11 00:44:19 +00:00
2690782292 pngdec: check version before using png_get_chunk_malloc_max
png_get_chunk_malloc_max / png_set_chunk_malloc_max were added in 1.4.1.

Bug: webp:505, webp:497
Change-Id: Id4e0643a7734563fec7779f7943ec760da8d276d
2021-02-10 13:41:54 -08:00
06c1e72e71 Code cleanup
* match param names

Change-Id: Ib75197a3c6bcc735049c6724dce6c240684108ae
2021-02-10 22:14:45 +01:00
8f0d41aac0 Merge changes Id135bbf4,I99e59797
* changes:
  cmake: add WEBP_USE_THREAD option
  cmake: don't install binaries from extras/
2021-02-09 21:25:12 +00:00
373eb170f1 gif2webp: don't store loop-count if there's only 1 frame
BUG=webp:504

Change-Id: Iacea11a861096ae950379c872d9840bdbec42a21
2021-02-08 22:00:48 +00:00
759b9d5a06 cmake: add WEBP_USE_THREAD option
this controls the config.h define of the same name and matches the
behavior of configure's --disable-threading

Bug: webp:502
Change-Id: Id135bbf4e6b3c9900e2b4f4f7ab744b3457ce41c
2021-02-05 15:32:41 -08:00
926ce921f3 cmake: don't install binaries from extras/
this matches the behavior of configure

Bug: webp:502
Change-Id: I99e597971636bdc2b9a9465ba13bb24c70ce87c0
2021-02-05 15:30:06 -08:00
9c367bc602 WebPAnimDecoderNewInternal: validate bitstream before alloc
this avoids large allocations with corrupt files due to the canvas size

BUG=oss-fuzz:28658

Change-Id: Idd1957e5447a2dadaef1fadaf68820fcb29f045a
2021-02-05 13:01:27 -08:00
47f64f6edd filters_sse2: import Chromium change
VerticalUnfilter_SSE2 has long been disabled due to a crash in an
Android emulator that hasn't reproduced elsewhere (crbug.com/654974).
this synchronizes the code for now to avoid needing to locally edit the
file on import.

Bug: 1141126
Change-Id: Ib61aeab93caaff1759606566b9e499eaac1576cf
2021-01-30 11:44:07 -08:00
cc3577e9b9 fuzzer/*: use src/ based include paths
this synchronizes the code with chrome, where this format allows the
code to pass buildtools/checkdeps/checkdeps.py

Bug: 1141126
Change-Id: I25361b1a43cd95730814302f02aa16af8fdb5fd2
2021-01-29 20:04:08 -08:00
004d77ffab Merge tag 'v1.2.0'
libwebp-1.2.0

- 12/23/2020: version 1.2.0
  * API changes:
    - libwebp:
      encode.h: add a qmin / qmax range for quality factor (cwebp adds -qrange)
  * lossless encoder improvements
  * SIMD support for Wasm builds
  * add xcframeworkbuild.sh, supports Mac Catalyst builds
  * import fuzzers from oss-fuzz & chromium (#409)
  * webpmux: add an '-set loop <value>' option (#494)
  * toolchain updates and bug fixes (#449, #463, #470, #475, #477, #478, #479,
    #488, #491)

* tag 'v1.2.0':
  update ChangeLog
  Fix check_c_source_compiles with pthread.
  disable CombinedShannonEntropy_SSE2 on x86
  pngdec: raise memory limit if needed
  {ios,xcframework}build.sh: make min version(s) more visible
  animdecoder_fuzzer: fix memory leak
  update gradle to 6.1.1
  update NEWS
  bump version to 1.2.0
  webp/encode.h: restore WEBP_ENCODER_ABI_VERSION to v1.1.0
  update AUTHORS

Bug: webp:484
Change-Id: I8f716a0e0438537e674092c1bfb60d27d738f69f
2021-01-29 19:24:01 -08:00
fedac6cc69 update ChangeLog
Bug: webp:484
Change-Id: I071715469d10d590f7a65f9fa8e766f9c7bbf25f
2021-01-20 19:43:45 -08:00
170a871202 Fix check_c_source_compiles with pthread.
Also fix the variables: we need to check for PTHREAD_PRIO_INHERIT
and PTHREAD_CREATE_JOINABLE (not PTHREAD_CREATE_UNDETACHED) and
internally use HAVE_PTHREAD_PRIO_INHERIT and PTHREAD_CREATE_JOINABLE
(and not HAVE_PTHREAD_CREATE_JOINABLE).
cmake/config.h.in actually had the right variables.

BUG=webp:498

Change-Id: Ibf6cf854337cea5781a74316024f8ff4960366d7
(cherry picked from commit ceddb5fc8d)
2021-01-20 19:19:32 -08:00
ceddb5fc8d Fix check_c_source_compiles with pthread.
Also fix the variables: we need to check for PTHREAD_PRIO_INHERIT
and PTHREAD_CREATE_JOINABLE (not PTHREAD_CREATE_UNDETACHED) and
internally use HAVE_PTHREAD_PRIO_INHERIT and PTHREAD_CREATE_JOINABLE
(and not HAVE_PTHREAD_CREATE_JOINABLE).
cmake/config.h.in actually had the right variables.

BUG=webp:498

Change-Id: Ibf6cf854337cea5781a74316024f8ff4960366d7
2021-01-19 23:15:16 +01:00
8599571935 disable CombinedShannonEntropy_SSE2 on x86
this function produces different results from the C code due to
use of double/float resulting in output differences when compared to
-noasm.

Bug: webp:499
Change-Id: Ia039b168c0a66da723fb434656657ba1948db8ae
2021-01-18 16:41:44 -08:00
289757fe1e TiffDec: enforce stricter mem/dimension limit on tiles
Tile can be even larger than image dimensions.

Change-Id: I80518e815bb11d7a07c8189d0493b3cc60e29815
2021-01-12 10:57:27 +01:00
8af7436f10 Merge "{ios,xcframework}build.sh: make min version(s) more visible" into 1.2.0 2021-01-09 18:33:41 +00:00
e56c3c5be3 pngdec: raise memory limit if needed
Some PNG input contain chunks larger than libpng's default
memory-alloc limit (8M).
Raise this limit reasonably if it looks like the input bitstream
is larger than libpng's default limit.

BUG=webp:497

Change-Id: I2c9fbed727424042444b82cbf15e0781cefb38dc
(cherry picked from commit 8696147da4)
2021-01-08 20:30:13 -08:00
8696147da4 pngdec: raise memory limit if needed
Some PNG input contain chunks larger than libpng's default
memory-alloc limit (8M).
Raise this limit reasonably if it looks like the input bitstream
is larger than libpng's default limit.

BUG=webp:497

Change-Id: I2c9fbed727424042444b82cbf15e0781cefb38dc
2021-01-08 08:48:39 +01:00
13b8e9fe16 {ios,xcframework}build.sh: make min version(s) more visible
add IOS_MIN_VERSION, MACOSX_MIN_VERSION and MACOSX_CATALYST_MIN_VERSION
to allow control of the minimum versions supported based on the
deployment target; based on feedback from:
e8e8db98 add xcframeworkbuild.sh
e8e8db985a

Change-Id: I9fbca072bf00c4cb8e59143371a2d3522d22808b
2021-01-05 10:52:44 -08:00
a92254107e animdecoder_fuzzer: fix memory leak
BUG=oss-fuzz:28978

Change-Id: I7b3a495c02b4b03f367d732af5acb02856f8bead
(cherry picked from commit 8df77fb1b1)
2021-01-02 15:52:07 -08:00
d6c2285d7c update gradle to 6.1.1
somewhat arbitrary version selection, but this matches what's currently
in use in ExoPlayer in the dev-v2 branch

fixes:
FAILURE: Build failed with an exception.

* What went wrong:
Could not determine java version from '11.0.9.1'.

and removes the wrapper task as this is predefined in later versions:
Build file '/home/jzern/external/libwebp/build.gradle' line: 437

* What went wrong:
A problem occurred evaluating root project 'libwebp'.
> Cannot add task 'wrapper' as a task with that name already exists.

Change-Id: Ib9ef757d874cd6d4b08da3e7cef3ac5316935966
2021-01-02 15:51:55 -08:00
8df77fb1b1 animdecoder_fuzzer: fix memory leak
BUG=oss-fuzz:28978

Change-Id: I7b3a495c02b4b03f367d732af5acb02856f8bead
2020-12-26 12:26:41 +01:00
52ce633388 update NEWS
Bug: webp:484
Change-Id: Idd2ffc1c0a61f5442adea1ac751c57bd4cc2fced
2020-12-24 10:09:03 -08:00
28c4982064 bump version to 1.2.0
libwebp{,decoder} - 1.2.0
libwebp libtool - 8.1.1
libwebpdecoder libtool - 4.1.1

mux - 1.2.0
libtool - 3.6.0

demux - 1.1.0
libtool - 2.7.0

Bug: webp:484
Change-Id: I458940f407515e0d95d20bbfd670ee29255c12eb
2020-12-23 19:54:29 -08:00
7363dff25c webp/encode.h: restore WEBP_ENCODER_ABI_VERSION to v1.1.0
this was missed in:
f9b30586 fix ABI breakage introduced by 6a0ff358

Bug: webp:484
Change-Id: I64c9e5d1113209727f1ede467316549b4f2ad116
2020-12-23 19:50:03 -08:00
826aafa570 update AUTHORS
Bug: webp:484
Change-Id: I62c722eec267ecd961e66f714beec4a8feafd724
2020-12-23 19:32:04 -08:00
6325882327 animdecoder_fuzzer: validate canvas size
avoids some OOMs due to extreme resolutions

BUG=oss-fuzz:28658

Change-Id: I60b5fb3d7a7d17694a89237d521b851b0897e9fb
2020-12-18 11:18:11 -08:00
9eb2638119 CMake: remove duplicate "include(GNUInstallDirs)"
+ add missing copyright header

Change-Id: I2b61ab56a14d38360ac5beaebab4d2acf165dd46
2020-12-17 08:00:06 +01:00
2e7bed7925 WebPPicture: clarify the ownership of user-owned data.
It's explicitly safe (and recommended!) to plug external data into
the pic->y/u/v/argb fields. They are guaranteed to be preserved
by the encoding process if no conversion is needed.

Change-Id: I325ca41a6a834f7f028431c605dddef67e9542cc
2020-12-14 12:28:52 +01:00
cccf5e337a webpmux: add an '-set loop <value>' option
This allows to change the loop count option on animated files.

BUG=webp:494

Change-Id: I6849f56d7bff8b33a94f14b409e40f99789009ad
2020-12-12 19:05:11 +00:00
c9a3f6a1d0 Merge changes Ie29f9867,I289c54c4
* changes:
  iosbuild.sh: sync some aspects of xcframeworkbuild.sh
  add xcframeworkbuild.sh
2020-12-10 20:23:39 +00:00
319f56f1a1 iosbuild.sh: sync some aspects of xcframeworkbuild.sh
Change-Id: Ie29f986767132fe980d71e43f6b8d367a9e2e6a9
2020-12-08 19:20:53 -08:00
e8e8db985a add xcframeworkbuild.sh
this is similar to iosbuild.sh, but will create .xcframework variants to
support Catalyst targets. currently it includes libs for:
  ios-arm64_armv7_armv7s
  ios-arm64_x86_64-maccatalyst
  ios-i386_x86_64-simulator
  macos-arm64_x86_64

this script requires Xcode 12+ to target arm64 for mac/catalyst, Xcode
11 builds will create x86_64 libraries only. iosbuild.sh remains for
compatibility purposes

Change-Id: I289c54c4b85848392a99bea698d45d54a9781f49
2020-12-08 19:20:46 -08:00
ae54553461 dsp.h: allow config.h to override MSVC SIMD autodetection
this fixes builds with cmake targeting visual studio that set
-DWEBP_ENABLE_SIMD=0

BUG=webp:478

Change-Id: I21b61b112c79ff9cbab9e4502a25d3f1fa096c8b
2020-12-03 10:22:04 -08:00
fef789f366 Merge "cmake: fix per-file assembly flags" 2020-12-02 19:29:21 +00:00
fc14fc038b Have C encoding predictors use decoding predictors.
libwebp.a in Release mode with no symbols size in bytes:
986430 -> 975114  (-1.1%)

Change-Id: Ia96192a6be2911779e359b72132bdba60b60a13d
2020-12-02 11:54:59 +01:00
7656f0b335 README,cosmetics: fix a couple typos
Change-Id: I326db8e04877eeeb52f9f5fba104d8c20938f0e3
2020-11-25 12:55:23 -08:00
d2e245ea9e cmake: disable webp.js if WEBP_ENABLE_SIMD=1
wasm2js doesn't support SIMD, fixes link error

Change-Id: I3d9d3cb5f29434bf6c0c0029c07540a9768f9b95
2020-11-23 18:53:20 -08:00
96099a79a8 cmake: fix per-file assembly flags
Since
a376e7b9 Fix compilation on windows and clang-cl+ninja.
the highest level assembly flag (/arch:AVX / -msse4.1) would be applied
to all assembly files. This could result in higher level instructions
being used which would defeat the runtime cpu detection check and could
result in a crash.

With this change -m style flags are used with clang-cl as it supports
them and allows the correct level to be set. With at least Visual
Studio 12 (2013)+ /arch is not necessary to build SSE2 or SSE4 code
unless a lesser /arch is forced so these flags are avoided. This matches
the nmake build.

For emscripten only sse2 and sse4.1 are tested (NEON will succeed in
being enabled, but fail to build). This is consistent with
the current behavior added in:
commit 36c81ff6a9

    WASM-SIMD: port 2 patches from rreverser@'s tree

    * Stop on first found SIMD version
    * Imply lower SSE version when higher is found

Bug: webp:488
Change-Id: I34d01274e5204a477b6b9f35ed566048a62b4c57
Tested: msvc 2013-2019 debug win32/x64 builds; clang-cl under 2019
2020-11-23 17:31:48 -08:00
5abb55823b Merge "cmake: fix compilation w/Xcode generator" 2020-11-24 01:31:26 +00:00
8484a1204c cmake: fix compilation w/Xcode generator
Add a stub file to object only library targets.

https://cmake.org/cmake/help/v3.18/command/add_library.html#object-libraries
Some native build systems (such as Xcode) may not like targets that have
only object files, so consider adding at least one real source file to
any target that references $<TARGET_OBJECTS:objlib>.

Bug: webp:477
Change-Id: I5d404c921d84433c7a0b22e0736ab0dbe699d264
2020-11-20 13:21:17 -08:00
d7bf01c954 Merge changes Ifcae0f38,Iee2d7401
* changes:
  wicdec: fail with animated images
  [cd]webp: document lack of animated webp support
2020-11-20 19:29:43 +00:00
36c81ff6a9 WASM-SIMD: port 2 patches from rreverser@'s tree
* Stop on first found SIMD version
* Imply lower SSE version when higher is found

Change-Id: I9a4bf24eeebf6c87b6b50f5c969e7e36429b691d
2020-11-20 11:58:39 +01:00
988b02abfd Merge "Couple of fixes to allow SIMD on Emscripten" 2020-11-20 08:18:41 +00:00
26faf7706b wicdec: fail with animated images
this matches the behavior of other decoders (WebP) in imageio.

Bug: webp:479
Change-Id: Ifcae0f38d7eebde31cd294070a6dd1f80cb30043
2020-11-19 19:49:11 -08:00
ab2d08a842 [cd]webp: document lack of animated webp support
Bug: webp:479
Change-Id: Iee2d7401400a5ff0a11682028194e561b365ab78
2020-11-19 19:17:32 -08:00
52273943c6 Couple of fixes to allow SIMD on Emscripten
- Add `-msimd128` to flags to actually enable WebAssembly SIMD
   when performing SIMD detection. It's currently required in
   addition to `-msse*` / `-mfpu=neon` flags which only perform
   translation of corresponding intrinsics to Wasm SIMD ones.
   See a discussion at emscripten-core/emscripten#12714 for
   automating this and making easier in the future.
 - Remove compilation branch that prevented definitions of
   `WEBP_USE_SSE` and `WEBP_USE_NEON` on Emscripten even when
   SIMD support was detected at compile-time.
 - Add an implementation of `VP8GetCPUInfo` for Emscripten which
   uses static `WEBP_USE_*` flags to determine if a corresponding
   SIMD instruction is supported. This is because Wasm doesn't
   have proper feature detection (yet) and requires making separate
   build for SIMD version anyway.

Change-Id: I77592081b91fd0e4cbc9242f5600ce905184f506
2020-11-18 21:51:41 +00:00
8870ba7f06 Fix skia bug #10952
The offset *can* be negative, but the sanitizer reports strange
address behaviour when row_offset is unsigned size_t.

For safety, use int64_t instead (probably overkill. int32_t is probably ok).

Change-Id: I1bd424bfdb5447b3839f40679581d6bdea075320
2020-11-18 14:59:34 +01:00
4b3c6953ef Detect if StoreFrame read more than anmf_payload_size bytes
After ParseAnimationFrame() calls StoreFrame(), check if StoreFrame() reads
more than anmf_payload_size bytes from dmux->mem_. Treat that as PARSE_ERROR.

Change-Id: I0d03885c19d32792af78de7bed1a944ca01f1dc6
2020-11-17 07:57:24 +01:00
17fd4ba820 webp/decode.h,cosmetics: normalize 'flip' comment
have it match the other boolean options with 'if true...'

Change-Id: I5a3e7c17b35a21fc5146ecaf10e226486a2dc740
2020-10-29 16:00:44 -07:00
411d3677ca remove some unreachable break statements
following a goto.
+ enable -Wunreachable-code-aggressive if available

Change-Id: I0312800d84d8984dbc51925600ed5d7d438413fd
2020-10-26 18:45:24 -07:00
3700ffd7e1 WebPPictureHasTransparency: remove unreachable return
Change-Id: Ia8077918b5110fb7fc74f326d4d16b38d9ed1b38
2020-10-26 15:52:20 -07:00
83604bf3ac {animencoder,enc_dec}_fuzzer: convert some abort()s to returns
with functions that can legitimately fail when under memory pressure the
fuzzer should exit gracefully rather than abort().

+ add some more error detail to output

Bug: chromium:1140448
Change-Id: I1a8582a939e0a5b2b8631c95c0464658c99063e2
2020-10-21 10:48:05 -07:00
eb44119c3d Merge changes I8ae09473,I678c8b1e
* changes:
  fuzz_utils.h: rename max() to Max()
  fuzz_utils.h: make functions WEBP_INLINE
2020-10-19 21:56:35 +00:00
9f6055fcb2 fuzz_utils.h: rename max() to Max()
avoids conflict with windows.h define

Bug: webp:409
Change-Id: I8ae0947365e7071d8ebe1d682c9211882cc2fd89
2020-10-17 16:40:58 -07:00
695788e7f5 fuzz_utils.h: make functions WEBP_INLINE
+ add some warnings and avoid overriding implicit %.c, %.cc patterns in
makefile.unix

Bug: webp:409
Change-Id: I678c8b1ed630ebb9114208c20b794d2eefdca5a1
2020-10-17 10:49:26 -07:00
906c1fcd61 make ImgIoUtilReadFile use WebPMalloc instead of malloc
This is a minor technical change in API in case a special allocator
was used in WebPMalloc.

Change-Id: Idb78a9150d006f158c1a9538525097749e42e7f7
2020-10-16 15:40:13 +02:00
8cb7e536d2 rename demux_api_fuzzer.c -> mux_demux_api_fuzzer.c
this better matches the file's contents

Bug: webp:409
Change-Id: I693795370c0d1af198971693b4ff15a57d996c4b
2020-10-15 16:50:25 -07:00
443db47d91 add animdecoder_fuzzer.cc
Bug: webp:409
Change-Id: Iade1e6b1288faad9076f72c21c1bde5a6bbfc7e0
2020-10-14 19:44:19 -07:00
36a6eea3bc Merge "import fuzzers from oss-fuzz/chromium" 2020-10-14 22:12:27 +00:00
ec5f12c11a Makefile.vc: remove deprecated /Gm option
this was only used in debug builds, the build should be fast enough in
either case.

https://docs.microsoft.com/en-us/cpp/build/reference/gm-enable-minimal-rebuild?view=vs-2019
/Gm is deprecated. It may not trigger a build for certain kinds of
header file changes. You may safely remove this option from your
projects. To improve build times, we recommend you use precompiled
headers and incremental and parallel build options instead.

Change-Id: I8e3c0e7cc82e10bd1d2b0904d290fe4e050ebe8b
2020-10-14 13:22:23 -07:00
64425a0884 picture_tools_enc: fix windows build warning
with WebPReplaceTransparentPixels() function signature:

src\enc\picture_tools_enc.c(86): warning C4028: formal parameter 1
different from declaration

Change-Id: I0140d61b0dfebcbb4189707e8f2f4b1af802a4d7
2020-10-14 13:13:53 -07:00
bd94090a11 import fuzzers from oss-fuzz/chromium
+ a simple makefile + README

these were mostly equivalent, chromium added support for
WEBP_REDUCE_CSP.

the file names were normalized as follows:

fuzz_advanced_api.{c,cc} -> advanced_api_fuzzer.c
fuzz_animation_api.{c,cc} -> animation_api_fuzzer.c
fuzz_webp_animencoder.cc -> animencoder_fuzzer.cc
fuzz_demux_api.{c,cc} -> demux_api_fuzzer.c
fuzz_webp_enc_dec.cc -> enc_dec_fuzzer.cc
fuzz.h -> fuzz_utils.h
fuzz_simple_api.{c,cc} -> simple_api_fuzzer.c

Bug: webp:409
Change-Id: Ib997f0c92f25f8a1f91da83790298cd848b61a5d
2020-10-13 18:31:08 -07:00
cf847cba58 use WEBP_DSP_INIT_FUNC for Init{GammaTables*,GetCoeffs}
this provides stronger synchronization when pthreads are available as
was done in 'd77bf512 add WEBP_DSP_INIT / WEBP_DSP_INIT_FUNC' for the
other init functions.

Change-Id: I2ffe4e24454d276c2411ece34dca38d23d4756d5
2020-09-11 11:57:51 -07:00
55a080e50a Add WebPReplaceTransparentPixels() in dsp
with SSE2 implementation.

(Extracted from side experiment)

Change-Id: I62d457fb6643645291cffd6d2d205d4a5ffa4517
2020-09-09 08:15:22 +02:00
84739717d6 GetBackgroundColorGIF: promote to uint32_t before << 24
quiets a signed integer overflow warning

Change-Id: Ie4dd957e9fa7c6e639c2e887c448ecbba7d50a9e
2020-09-03 15:45:05 -07:00
def64e920f cwebp: Fix -print_psnr for near_lossless
The output was always 99dB because the lossless pipeline is not
modifying the 'picture'. Changing that is not that simple because
near_lossless impacts both VP8ApplyNearLossless() and
ApplyPredictFilter(); the latter cannot be applied as is to the input
and thus the final modified 'picture' cannot be easily retrieved
without decoding the encoded bitstream. Hence ReadWebP() is called in
cwebp.c on the encoded bitstream kept in memory to get the correct
distortion.

However -get_psnr returns a different distortion than get_disto for
lossy encoding configurations because cwebp loads the source as YUV
while get_disto directly reads it as RGB without conversion loss.

Change-Id: I5c32cf8f89eb137973dc7eebda747682d921b8e2
2020-08-17 11:37:37 +02:00
cf2f88b38f Add palette and spatial for q >= 75 and -m 5
Change-Id: I12198b7eb82a4247e606bc60342595abf4d6eee0
2020-06-17 12:51:40 +02:00
f0110baec0 Add no-color cache configuration to the cruncher
Fix another pessimization found by the pingo image compressor.

Refactoring is necessary to make LZ77 computation
common to cache or no-cache analysis.
Slower by 1.7x instead of 2x

Change-Id: I396701ea6e88543dbfe9471eb552877f6c8ce1e3
2020-06-09 19:04:44 +02:00
749a8b99f7 Better estimate of the cache cost.
Change-Id: I171a8f80f1597bbdeb724957e789b947df3c2885
2020-06-05 16:07:58 +02:00
4f9f00ccf4 Use spatial predictors on top of palette no matter what.
This is fixing another inefficiency found by the pingo image optimizer.

Change-Id: Icecb0d39fcbd17b403667e8e2095c7705b1dd493
2020-06-04 18:03:57 +02:00
7658c68613 Add spatial prediction on top of palette in cruncher.
Change-Id: I3765ab628ef915eedf2e541a80c65ce9880dff36
2020-06-04 14:38:08 +02:00
133ff0e374 webp_js: force WASM=0 option explicitly
It's apparently no longer the default.

BUG=webp:470

Change-Id: Ic3219f2df2f19783ccea116e87bbefee29fe5edc
2020-05-29 14:56:34 +02:00
e3c259a278 Fix integer overflow in EmitFancyRGB.
+ enhance the assert in WebPCopyPlane()

Change-Id: Id9b01d00a8dce6caf0d4721a6fbe8def40b8bb85
2020-05-05 14:57:19 +02:00
b3ff0bdec1 man/{gif2,img2}webp,webpmux: normalize some wording
Change-Id: Iced9d3dfdaff0356499d4e872c20255edea7bd0b
2020-05-01 10:31:39 -07:00
f9b30586eb fix ABI breakage introduced by 6a0ff358
qmin / qmax are now using the pad[] spot at the end of the struct,
 and we don't need to bump the ABI major number.

Change-Id: I41adcaf1600b29a5a05c9fe380bfd977cf425124
2020-04-21 19:17:56 +00:00
1d58dcfc17 README.webp_js: update note about emscripten version
keep the minimum, but recommend the latest so we don't need to update
this in the future.

BUG=webp:463

Change-Id: I0615039323d3c77684c6be2e890514f6973cf535
2020-04-16 17:58:26 -07:00
4407026621 README.webp_js: s/fastcomp/upstream/
the fastcomp backend is deprecated:
https://emscripten.org/docs/compiling/WebAssembly.html?highlight=fastcomp#backends

Change-Id: Ib1ea46ff97f24f5115555c76980cf837461208ba
2020-04-15 19:59:45 -07:00
2565fa8ffb README.webp_js: update cmake command
remove EMSCRIPTEN_GENERATE_BITCODE_STATIC_LIBRARIES, this option is only
supported with the deprecated fastcomp backend; the wasm version will
begin to throw an error if it's used. 1.39.12 already fails to build when
using this option.

+ fix a typo

BUG=webp:463

Change-Id: I7175df4d5b2b6cb6aaf20eb41063c09c03b9b69a
2020-04-15 19:53:12 -07:00
47309ef52d webp: WEBP_OFFSET_PTR()
Removes undefined behavior of offsetting NULL.

Change-Id: I7c83d0c913c631c091a5fb128f6d6b46b1d116db
2020-03-20 11:39:06 +01:00
687ab00e6e DC{4,8,16}_NEON: replace vmovl w/vaddl
4/8/16 fewer instructions

Change-Id: I38fe08722e7b839e3f3e0bf4df7e0fa8e7a0138f
2020-03-05 09:41:14 -08:00
1b92fe75a1 DC16_NEON,aarch64: use vaddlv
saves 3 instructions, neutral to mildly faster on a pixel 3a

Change-Id: I6ae57e8e38d4149167ea14e27cd2b32113b4f8e7
2020-03-04 23:12:20 -08:00
53f3d8cf7e dec_neon,DC8_NEON: use vaddlv instead of movl+vaddv
one fewer instruction

Change-Id: I2f599fd6f9eebbb0cab81ae9855244fc401d4323
2020-03-04 15:46:38 -08:00
27d082403c Fix integer overflow in WebPAnimDecoderGetNext()
Change-Id: Ic53263b6125ca125d5fb3791474eab78043fec18
2020-02-27 20:23:37 +01:00
69776e3832 Merge "remove call to MBAnalyzeBestIntra4Mode for method >= 5" 2020-02-08 16:15:27 +00:00
a99078c1cf remove call to MBAnalyzeBestIntra4Mode for method >= 5
this was not giving a good alpha value, making the method 5/6 a little
blurrier than method 4 (!).

Change-Id: I69b9890dea21499c1af1753e87d9f7adf8b433de
2020-02-07 14:38:13 +01:00
22e404ccbd CMakeLists.txt: fix set(CACHE) argument order
<type> comes before <docstring>

Change-Id: Iad8cfbbab452381969a7b36aaf244b6abc4fc974
2020-02-06 20:27:01 -08:00
71690b524e fix MSVC warning
"warning C4244: '=': conversion from 'const int' to 'float', possible loss of data"

Change-Id: Ie0769e50c19efd48332ffeadb026d4538fec9919
2020-01-30 09:25:26 +01:00
6a0ff35872 Enc: add a qmin / qmax range for quality factor
This is particularly useful for multi-pass search (but not only),
to prevent the search from going over or below a reasonable threshold.
E.g.: 'cwebp -qrange 50 80 ...' will prevent any unreasonable degradation.

new cwebp option: -qrange min max

Change-Id: I59f394533535fc20b6996bc0895f4301476d5eff
2020-01-29 14:52:02 +01:00
0fa56f307f Merge tag 'v1.1.0'
libwebp-1.1.0

- 12/18/2019: version 1.1.0
  * API changes:
    - libwebp:
      WebPMalloc (issue #442)
    - extras:
      WebPUnmultiplyARGB
  * alpha decode fix (issue #439)
  * toolchain updates and bug fixes
    (chromium: #1026858, #1027136, #1027409, #1028620, #1028716, #995200)
    (oss-fuzz: #19430, #19447)

* tag 'v1.1.0':
  update ChangeLog
  Makefile.vc: fix webp_quality.exe link
  update NEWS
  bump version to 1.1.0
  update AUTHORS

BUG=webp:441

Change-Id: Ie4ae80a736c795549e7f0fc8942a293fa724d475
2020-01-06 16:31:09 -08:00
6cf504d018 PNM decoding: handle max_value != 255
also add support for PAM's GRAYSCALE_ALPHA tuple (with depth = 2)

BUG=webp:449

Change-Id: I0fe4825cd1d5487b9f7af332c7d3d56c1b35c3fb
2020-01-06 23:48:40 +01:00
d7844e9762 update ChangeLog
BUG=webp:441

Change-Id: Ib401d468c677b9e598ffcec6535a846bf2456a4f
2019-12-21 05:37:43 -08:00
7f0064361a Makefile.vc: fix webp_quality.exe link
when building a dll based libwebp include the dsp private symbols that
WebPUnmultiplyARGB requires

Change-Id: I7cf7da0b20d6cf6740219c8562380926a0abd93c
(cherry picked from commit cf047e8347)
2019-12-20 16:29:22 -05:00
cf047e8347 Makefile.vc: fix webp_quality.exe link
when building a dll based libwebp include the dsp private symbols that
WebPUnmultiplyARGB requires

Change-Id: I7cf7da0b20d6cf6740219c8562380926a0abd93c
2019-12-20 08:55:37 -08:00
c074c65368 update NEWS
BUG=webp:441

Change-Id: I8586b004e28b92d8c3c146f681bc9765f8a1f361
2019-12-18 00:06:50 -08:00
30f0955160 bump version to 1.1.0
libwebp{,decoder} - 1.1.0
libwebp libtool - 8.0.1
libwebpdecoder libtool - 4.0.1

mux - 1.1.0
libtool - 3.5.0

demux - 1.1.0
libtool - 2.6.0 (no code change)

BUG=webp:441

Change-Id: I458940f407515e0d95d20bbfd670ee29255c12eb
2019-12-18 00:06:50 -08:00
a76694a1d6 update AUTHORS
BUG=webp:441

Change-Id: I844f1e4b5c32219a1e54de0c57a73822f93c7755
2019-12-18 00:06:50 -08:00
6e3ef7b326 extras: fix WEBP_SWAP_16BIT_CSP check
this is defined to 0 by dsp.h if it wasn't defined previously, since:
47178dbd extras: add WebPUnmultiplyARGB() convenience function

Change-Id: If4dd48360a95b2786410670cff5ac655227fb6dd
2019-12-18 07:15:53 +00:00
47178dbd45 extras: add WebPUnmultiplyARGB() convenience function
This is useful for converting associated to unassociated.

Change-Id: I0e6d16ec63cb5514a0f945c14a54e0d01e1fab0a
2019-12-17 17:36:37 -08:00
22cbae33e5 idec_dec: fix 0 offset of NULL pointer
in RemapMemBuffer() and AppendToMemBuffer()

BUG=chromium:1028716,chromium:1027136

Change-Id: Ibc321d233b6207be3cb5cef4d9e8a60498e32457
2019-12-14 17:14:30 -08:00
290dd0b426 muxread: fix 0 offset of NULL pointer
BUG=chromium:1028620,chromium:1027409

Change-Id: I2b5527a223a03161afbf39c297c4646954a91fbc
2019-12-14 12:57:39 -08:00
0df474ac9e Merge "lossless_(enc_|)sse2: avoid offsetting a NULL pointer" 2019-12-13 22:04:44 +00:00
c6b75a1966 lossless_(enc_|)sse2: avoid offsetting a NULL pointer
PredictorSub0_SSE2 doesn't use 'upper' (neither does
VP8LPredictorsSub_C[0]); just pass NULL when dealing with trailing
pixels to avoid undefined behavior when offsetting a NULL pointer

BUG=chromium:1026858,oss-fuzz:19430

Change-Id: I08be8899ed2e34f26aaee34defe68dbd0fe216d3
2019-12-13 18:33:10 +00:00
295e5e3801 fix UBSAN warning
"applying non-zero offset 2044 to null pointer"

  Fixes chromium bug #19447

Change-Id: I530ae27dc64e92ed0018f36469264c448329e042
2019-12-13 13:26:16 +00:00
e2575e05cb DC8_NEON,aarch64: use vaddv
results in one fewer instruction for both DC8uv_NEON and
DC8uvNoLeft_NEON

Change-Id: Ia4e6f4dbc070079cdc2496a698bd4b34198ea164
2019-12-06 09:38:48 -08:00
b0e09e346f dec_neon: Fix build failure under some toolchains
some toolchains may implement vcreate_u64 as an assignment to a vector
causing a type mismatch:
 invalid conversion between vector type 'uint64x1_t' (vector of 1
'uint64_t' value) and integer type 'unsigned int' of different size
  const uint64x1_t LKJI____ = vcreate_u64(L | (K << 8) | (J << 16) | (I << 24));
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Change-Id: I5c7b0076ad66d4b3fcdcb7ee9f59bbaa6f19b783
2019-12-06 00:06:44 -08:00
cf0e903c89 dsp/lossless: Fix non gcc ARM builds
The workaround for GCC ARM must not be applied when another toolchain
(like MSVC) is used for the build.

Change-Id: I11ec4558902063ccb085d3f435e24b3a60739dd5
2019-11-27 15:05:08 +01:00
bb7bc40b6d Remove ubsan errors.
'upper' could be NULL and it would be increased.
But that is for predictor zero that does not use 'upper'.

Change-Id: Icd4ae6792cc55ea021b4f828c3dbdb5f03e120d8
2019-11-06 14:08:14 +01:00
78881b769c CMake: fix GLUT library link
use GLUT_LIBRARIES instead of GLUT::GLUT

Change-Id: I92af90e09e00b01bd050ebeb8e9003b14c7dc144
2019-10-23 16:25:39 +02:00
9f750f7a06 cmake: fix BUILD_SHARED_LIBS build on mac
add some missing dependencies and convert utility libraries to
static only libraries to avoid creating unnecessary shared object
libraries which may fail to link due to missing symbols.

Change-Id: Iaa91a3d97fa5af6ada4b2a851cc7fc2879d871da
2019-10-22 14:42:30 -07:00
17850e74ce libwebp: Remove char-subscripts warning in pnmdec.c
Change-Id: I7a771e17fca0ba8a49a816b48cc477ad7a03a435
2019-10-16 17:58:30 +02:00
2fa2552db1 Merge "Expose WebPMalloc() in addition to WebPFree()" 2019-10-16 05:48:18 +00:00
a4df4aae73 Expose WebPMalloc() in addition to WebPFree()
and use it at various places, including for WebPData.

This is an API change!

Change-Id: Ic041323a1179c465292a4f981a86c4c34635d243
2019-10-15 23:19:50 +02:00
853ea3d846 imageio/tiff: Return error before allocating bad tile size
Change-Id: I5820b808e25beeda0fd4e755b62da0caabe48d8d
2019-10-15 10:44:17 +02:00
af650c0bd2 Fix a Wxor-used-as-pow false positive
Since people seem to write "2 ^ X" hoping that it means "1 << X", clang
recently added a warning for this pattern.

It incorrectly fires on this file. To suppress it, restructure the code
to be less clever. (Alternatively we could use "xor" instead of "^" or
write "0x2" instead of "2" but both seem worse.)

No intended behavior change.

Bug: chromium:995200
Change-Id: I64744345be5f5a8cd1f4aaeaf0982da239b378a7
2019-09-04 23:35:46 -07:00
601ef17cf6 libwebp.py: update to swig 3.0.12
fixes use with python 3

Change-Id: I4035c1c93e9f6551dd2e7e57da7d4ffd42ca06ce
2019-08-31 19:20:58 -07:00
0e48d889eb bugfix: last alpha rows were incorrectly decoded
sometimes, the last rows of the alpha plane contain more than NUM_ARGB_CACHE_ROWS
rows to process. But ExtractAlphaRows() was repeatedly calling ApplyInverseTransforms()
without updating the dec->last_row_ field, which is the starting row used as starting
point.

Fix would consist of either updating correctly dec->last_row_ before calling
ApplyInverseTransforms(). Or pass the starting row explicitly, which is simpler.

BUG=webp:439

Change-Id: Id99f2c28662d02b2b866cb79e666050be9d59e04
2019-08-30 14:13:28 +02:00
24d2ccb4e0 webp: Fix imageio ReadPNM() TUPLTYPE
It was colliding with "DEPTH" header value so ignoring "TUPLTYPE"
except for unhandled types.

Change-Id: I3c69cb6a81c5369e64b59d50567cd7fbc1756d57
2019-07-30 09:22:29 +02:00
fab8f9cfcf cosmetics: normalize '*' association
we associate '*' with types rather than variables

Change-Id: Id93ed65272a8a88e604278693e3850649639e9b6
2019-07-26 01:04:09 -07:00
94138e0e0d update .gitignore
anim_dump, webpinfo, vwebp_sdl

Change-Id: I66043c9c296fae2319ec9b0acf3031543cb070bd
2019-07-13 00:52:46 -07:00
0fe1a89dbf update ChangeLog
Change-Id: I9cc1442edb7b3fef73c07979d85417e9dcbf5a70
2019-07-04 12:32:37 -07:00
2ad0916d5a update NEWS
Change-Id: I56c8d9430f0c77e813c2dbeee866387fa7a441c5
2019-07-04 11:43:29 -07:00
1287362b9a bump version to 1.0.3
libwebp{,decoder} - 1.0.3
libwebp libtool - 7.5.0
libwebpdecoder libtool - 3.5.0

mux - 1.0.3
libtool - 3.4.0 (no code change)

demux - 1.0.3
libtool - 2.6.0 (no code change)

Change-Id: Ie0eaeff5fd6ab6f957836b50aff565843e6ca845
2019-07-04 11:07:04 -07:00
7b968cc2d5 update AUTHORS
Change-Id: Ic19305928b563110093254e6177f22bbd65b0827
2019-07-04 10:42:46 -07:00
9d6988f44d Fix the oscillating prediction problem at low quality
For some exact resonance the over-quantization was exactly
compensating the under-quantization, leading to resonance
and strange patterns.

-> we special-handle the very flat blocks, hopefully for the
greater good (and not just the bad-resonance case).

For 'fast mode' (-m 3 or less), we just pay special attention
to the border of the image, where the oscillation / instability
usually starts. For the inner part of the image, since we're not
doing rd-opt, it's harder to fix anything.

Overall, on 'regular' images, the change is written the noise,
often leading to overall faster encoding (because of the short-cut).

BUG=webp:432

Change-Id: Ifaa8286499add80fd77daecf8e347abbff7c3a15
2019-07-03 08:40:41 -07:00
312f74d010 makefile.unix: allow *_LIBS to be overridden w/EXTRA_LIBS
previously setting EXTRA_LIBS on the command line would skip any
per-target updates. this allows both EXTRA_LIBS and [CD]WEBP_LIBS,
GL_LIBS to be set together avoiding the need to add unnecessary
dependencies to EXTRA_LIBS which affects all targets.

Change-Id: I63bbc14f0ac0cd04aa50c5d5047060ac57d0c9dc
2019-07-01 19:49:18 -07:00
92dbf23775 filters_sse2,cosmetics: shorten some long lines
Change-Id: Ifd8ddec50821aba175d41237df18e41b9ac6c7d4
2019-07-01 12:17:43 -07:00
a277d197a2 filters_sse2.c: quiet integer sanitizer warnings
missed in a788b49

with clang7+ quiets conversion warnings like:
implicit conversion from type 'int' of value -114 (32-bit, signed) to
type 'uint8_t' (aka 'unsigned char') changed the value to 142 (8-bit,
unsigned)

Change-Id: I52dcd9cd613107f5424177c277785b92430bffb7
2019-07-01 11:16:50 -07:00
804540f183 Fix cpufeatures in CMake.
cpufeatures was not installed even though WebP depends on it on Android.

BUG=webp:415

Change-Id: Iba00001534ceedbf65fbb42244a6c1341eb65134
2019-07-01 10:48:54 +02:00
bf00c15b23 Add CMake option for bittrace.
Change-Id: I9f09eb2c0afdac41e94bc10dfedd1fd004c45731
2019-07-01 10:48:54 +02:00
a788b49897 filters_sse2.c: quiet integer sanitizer warnings
with clang7+ quiets conversion warnings like:
implicit conversion from type 'int' of value -114 (32-bit, signed) to
type 'uint8_t' (aka 'unsigned char') changed the value to 142 (8-bit,
unsigned)

Change-Id: I7f08a836ddcf777454dfd5b877a81b62b2abac86
2019-06-28 23:22:49 -07:00
e6a92c5e15 filters.c: quiet integer sanitizer warnings
with clang7+ quiets conversion warnings like:
implicit conversion from type 'int' of value -12 (32-bit, signed) to
type 'uint8_t' (aka 'unsigned char') changed the value to 244 (8-bit,
unsigned)

Change-Id: I053c92301e55dcb0cae89a7733636283da942176
2019-06-28 23:16:28 -07:00
ec1cc40a59 lossless.c: remove U32 -> S8 conversion warnings
Change-Id: Ica2664ea087254959391275654412141ed9472df
2019-06-28 01:34:55 -07:00
1106478f42 remove conversion U32 -> S8 warnings
using an inline U32ToS8() function

Change-Id: I45f535c6c9b5de33d69acc17b466e183fcc19a63
2019-06-24 16:42:42 -07:00
812a6b49fc lossless_enc: fix some conversion warning
object code is unchanged.

Change-Id: I40fc16056c0ab44c5c57ef6b02af14be767abe87
2019-06-24 16:16:18 +02:00
4627c1c91b lossless_enc,TransformColorBlue: quiet uint32_t conv warning
no change in object code

from clang-7 integer sanitizer:
implicit conversion from type 'uint32_t' (aka 'unsigned int') of value
1955895199 (32-bit, unsigned) to type 'uint8_t' (aka 'unsigned char')
changed the value to 159 (8-bit, unsigned)

Change-Id: I0c3022339e34b9c9af03167ab827ade677973644
2019-06-20 23:06:13 -07:00
c84673a62f lossless_enc_sse{2,41}: quiet signed conv warnings
_mm_set1_epi16 takes a short argument

from clang-7 integer sanitizer:
implicit conversion from type 'int' of value 65280 (32-bit, signed) to
type 'short' changed the value to -256 (16-bit, signed)

Change-Id: Iad64f6209a8c130a7df67515451ded45b3f91702
2019-06-15 00:22:03 -07:00
776a775709 dec_sse2: quiet signed conv warnings
_mm_set1_epi8() takes a char argument
_mm_insert_epi16 takes a short argument

from clang-7 integer sanitizer:
implicit conversion from type 'int' of value 189 (32-bit, signed) to
type 'char' changed the value to -67 (8-bit, signed)
implicit conversion from type 'int' of value 128 (32-bit, signed) to
type 'char' changed the value to -128 (8-bit, signed)
implicit conversion from type 'int' of value 33909 (32-bit, signed) to
type 'short' changed the value to -31627 (16-bit, signed)

Change-Id: Id6b191b2c06881e27d447eeb1ff5bb2c1857b6ba
2019-06-14 01:00:20 -07:00
bd39c063ce Merge "thread_utils: release mutex before signaling" 2019-06-12 06:15:22 +00:00
0550576faa Merge "(alpha_processing,enc}_sse2: quiet signed conv warnings" 2019-06-11 17:42:04 +00:00
6682f2c415 thread_utils: release mutex before signaling
holding the associated mutex while signaling a condition variable isn't
necessary and in some implementations will reduce performance as the
woken thread may test the mutex, fail and go back to sleep.

Change-Id: Id685a47b0c76fc4a1c5acedcb6623e8c55056415
2019-06-10 23:09:56 -07:00
e78dea7587 (alpha_processing,enc}_sse2: quiet signed conv warnings
_mm_set1_epi8() takes a char argument
_mm_insert_epi16 takes a short argument

from clang-7 integer sanitizer:
implicit conversion from type 'int' of value 255 (32-bit, signed) to
type 'char' changed the value to -1 (8-bit, signed)
implicit conversion from type 'int' of value 33153 (32-bit, signed) to
type 'short' changed the value to -32383 (16-bit, signed)

Change-Id: Ic88c8ef3d00146d34f53a560582db673f818370d
2019-06-10 14:23:58 -07:00
9acf18ba46 iosbuild.sh: add WebP{Demux,Mux}.framework
Change-Id: I2c16475a7bf9f63d07f4298df7c68859226669d5
2019-06-10 11:51:21 -07:00
b9be7e65f8 vwebp: remove the -fit option (and make it default)
BUG=webp:433

Change-Id: I18476ba0ada0184d4d9e94060d601002bfa006da
2019-06-05 21:43:23 +02:00
1394a2bb86 Merge "README.webp_js: update Emscripten.cmake note" 2019-05-31 08:40:50 +00:00
dd3e7f8a2f README.webp_js: update Emscripten.cmake note
recent versions of the sdk don't set the EMSCRIPTEN environment
variable; provide a workaround.

Change-Id: I1c4991cda0261a51201d27723eb69f48422c47a0
2019-05-31 01:05:55 -07:00
32cf880132 predictor_enc,GetBestGreenRedToBlue: quiet implicit conv warnings
no change in object code

from clang-7 -fsanitize=implicit-integer-truncation
implicit conversion from type 'int' of value -16 (32-bit, signed) to
type 'uint8_t' (aka 'unsigned char') changed the value to 240 (8-bit,
unsigned)

Change-Id: Ia7cbaad247ab22b505b7f98b1247219c024f6db0
2019-05-31 00:06:23 -07:00
e1c8acb5bd Merge "vwebp: add a -fit option" 2019-05-29 08:27:48 +00:00
cbd23dd5b4 vwebp: add a -fit option
This is to make the initial window be rescaled in case the image
dimension is too large to fit the display.

BUG=webp:433

Change-Id: Ib04c12962bc8c26e74c8a6193829214da636ebde
2019-05-29 08:39:47 +02:00
2e672351aa bit_writer_utils,Flush: quiet implicit conversion warnings
no change in object code

from clang-7 -fsanitize=implicit-integer-truncation
implicit conversion from type 'int32_t' (aka 'int') of value 287
(32-bit, signed) to type 'uint8_t' (aka 'unsigned char') changed the
value to 31 (8-bit, unsigned)

Change-Id: I692368bcc2f41412697b8ae51e53078831072891
2019-05-25 12:31:09 -07:00
1326988d10 swig: update libwebp_python_wrap.c
regenerated with swig 3.0.10

matches the version used to update libwebp.py in:
0e7f8548 update generated swig files

Change-Id: I976a1a6b673c8174db5e97e8316c59970582e565
2019-04-18 15:30:11 -07:00
0e7f854897 update generated swig files
regenerated with swig 3.0.10

Change-Id: Ib3a26f6ab4ba0d4a4dfbb15b89be155998f94ad9
2019-04-18 06:47:52 +02:00
17ed143879 Merge "PutLE{16,24}: quiet implicit conversion warnings" 2019-04-05 02:03:05 +00:00
24686538be PutLE{16,24}: quiet implicit conversion warnings
no change in object code

from clang-7 -fsanitize=implicit-integer-truncation
implicit conversion from type 'int' of value 39736 (32-bit, signed) to type 'uint8_t' (aka 'unsigned char') changed the value to 56 (8-bit, unsigned)

Change-Id: I0ecf24c5b1b11e056c58b3b85ea529c30cdadf57
2019-04-03 22:45:59 -07:00
153bb3a0ef fix some clang-7 warnings:
"implicit conversion from type 'uint32_t' (aka 'unsigned int') of value xxxxx (32-bit, unsigned) to type 'uint8_t' (aka 'unsigned char') changed the value to xx (8-bit, unsigned)"

and same with signed -> unsigned conversion with truncation.

Change-Id: I50cae41a9ce7edcfcc814cc3ee2556b927064f43
2019-04-03 21:25:07 +00:00
ab2dc8939f Rescaler: fix rounding error
We saturate the result to [0..255]
It's the easiest and safest, given the wide variety of scaling
range we cover: we're not using floats, so precision is always
an issue at one end or the other of the scaling spectrum.

we also use:
  round(a - floor(b))
instead of:
  floor(a - round(b))
to handle difficult cases (ratio ~= .99, e.g.)

MIPS code is still disabled (and wrong)

Change-Id: I18d3f5ddc4c524879c257b928329b1c648fa7fb5
2019-03-30 06:43:55 +00:00
aa65f89a8f HistogramCombineStochastic: fix free of uninit value
previously if the mappings allocation failed histo_queue->queue would be
uninitialized; split the conditionals

Change-Id: I1b50b987e734393893dc8a83a3f314522ccd0c83
2019-03-29 23:31:02 -07:00
af0bac643a Merge "encode.h: mention 'exact' default in WebPEncodeLossless*" 2019-03-18 18:04:55 +00:00
6d2e11ec8b encode.h: mention 'exact' default in WebPEncodeLossless*
note that config.exact defaults to 0 and point users to WebPEncode() if
the default isn't acceptable.

BUG=webp:424

Change-Id: I179c34649834aeadc1606d0856f33e8255048ea1
2019-03-17 07:02:46 +00:00
8c3f04febb AndroidCPUInfo: reorder terms in conditional
'var != constant' is the preferred style for the library

Change-Id: I226e6d5d80dddd0469808136605f49205d238341
2019-03-15 18:12:04 -07:00
fcfd9c71b4 BitTrace: if BITTRACE is > 0, record and print syntax bits used
* Bittrace decoding is ~3x slower.
* Binary is the same byte-wise if BITTRACE=0
* Example output:
=== Bit traces ===
global-header    :    174 bytes   	[ 0.69%] [count:    1850]
segments         :    246 bytes   	[ 0.98%] [count:    3072]
block-size       :    170 bytes   	[ 0.68%] [count:    1536]
pred-modes       :   3829 bytes   	[15.27%] [count:   51458]
pred-modes-uv    :    279 bytes   	[ 1.11%] [count:    2329]
coeffs           :  20370 bytes   	[81.27%] [count:  212914]
Total: 25065 bytes

Change-Id: Ie32569c4e54a7ec13264e68d2dae2ce45c8536cb
2019-03-15 07:23:50 +01:00
067031eaed Speedups for unused Huffman groups.
If we know a Huffman group is unused, do not build
it: just check that it is valid.

Change-Id: Ie8223fe1afa1e769085a23ab92e730edd9060176
2019-03-11 16:53:06 +01:00
01ac46bae6 libwebp: Display "libjpeg error:" in imageio/jpegdec
For clearer error message in cwebp.

BUG=webp:420

Change-Id: Ie60b53c4c6b77a96f81f3b5cd285b7c7003a1308
2019-03-08 19:09:41 +01:00
d9a662e1aa WebPRescalerGetScaledDimensions: round scaled dimension up
This is to prevent resizing to dimension 0

+ added some safety checks about src_width > 0 and src_height > 0

BUG=webp:418

Change-Id: Ic04a53ad26455d80538bc8681882a554fca2a340
2019-02-18 14:34:03 +01:00
62eb3f087a libwebp: Fix missing '{' in README
Change-Id: I205e9dc24450b258b416550cd3f59ce5049546c7
2019-02-15 09:45:34 +01:00
e05f785a66 Merge "unicode,INIT_WARGV: add missing cast" 2019-01-25 08:58:32 +00:00
63c9a69fbd tag the VP8LHashPix() function for potential uint roll-over
BUG=webp:412

Change-Id: I10af39b774ef8e5d138670ddeaca4e15eade4ff6
2019-01-24 16:45:02 -08:00
2b7214ab99 unicode,INIT_WARGV: add missing cast
CommandLineToArgvW() returns a LPWSTR*, storing to const LPWSTR* is
incorrect without a cast; fixes gcc -Wincompatible-pointer-types
and clang(-cl) -Wincompatible-pointer-types-discads-qualifiers warnings

Change-Id: Iad5b49c4862c7be68251272e50d3c751099559bc
2019-01-24 07:08:55 +00:00
bf424b46a3 tag the GetPixPairHash64() function for potential uint roll-over
BUG=webp:412

Change-Id: I448583d72378afc0c6fabec45d4f8a2d6164ab15
2019-01-23 21:29:54 +01:00
7d05d6ca91 Have the color cache computation be u32-bit only.
BUG=webp:412

Change-Id: I18a3acb1b7f5d64f538b5c27521bc9e8dd599f5e
2019-01-23 11:49:08 +01:00
6bcf876980 Remove BINARYEN_METHOD in wasm settings.
This was removed according to https://kripken.github.io/emscripten-site/docs/compiling/WebAssembly.html#debugging

BUG=webp:413

Change-Id: If8f1a3f1260d34cdd2b937b286e4c57fb48ed828
2019-01-23 11:12:26 +01:00
2b98df90cb update ChangeLog
Change-Id: I805c2c1791f74771d3355f8143e3a697c72b39cd
2019-01-14 20:38:05 -08:00
61e372b7e3 update NEWS
Change-Id: I179bf63a718221dab4b4335fdccd78e9b36242c7
2019-01-14 20:24:07 -08:00
7ae658a026 bump version to 1.0.2
libwebp{,decoder} - 1.0.2
libwebp libtool - 7.4.0
libwebpdecoder libtool - 3.4.0

mux - 1.0.2
libtool - 3.4.0

demux - 1.0.2
libtool - 2.6.0

Change-Id: I59b1cdd832d36355c4554361fe45e518218d4a90
2019-01-14 19:57:05 -08:00
51c4907d32 update AUTHORS
Change-Id: I3b564e47d583336647dcce30b03ce07e836af903
2019-01-14 19:43:29 -08:00
666bd6c654 man/cwebp.1: refine near-lossless text
Change-Id: Ida25a8979b689ae798b01b40c0842912631bd60c
2019-01-11 22:55:24 -08:00
561cdce5bd Clarify the doc about GetFeatures.
Taking the comments from the internal ParseHeadersInternal.
(which is called by GetFeatures).

BUG=webp:411

Change-Id: I9999b4a183805e2db1456610a30024a0d8be4d00
2019-01-09 10:25:27 +01:00
aec2cf02d1 near_lossless: fix fuzzing-detected integer overflow
It's safer to clip the passed param instead of doing 32b arithmetic
and clipping afterward.

Output is unchanged, but code no longer rely on UB.

Change-Id: Ia5b4de6e8863981753f1d17f062965a6a5da5bed
2019-01-06 08:19:04 +00:00
928a75deca webp: Fix VP8LBitWriterClone() bug
dst->cur_ was not set.
The bug occurred only with several VP8LBitWriter instances
(thread_level > 0) and in 32-bit (in 64-bit, src->cur_ was
always 0 in VP8LBitWriterClone()).

BUG=chromium:917029

Change-Id: I0d94a3d8e62b247fd616eebe1009868dc8a5ed2e
2019-01-02 09:13:36 +00:00
5173d4ee6f neon IsFlat
Move IsFlat to its own header. This allows it to continue to be
inlined. Using the RTCD and creating a distinct function slows down arm
builds.

   flower   mug
C    3.59  2.12
NEON 3.47  2.01

BUG=b/118740850

Change-Id: Id77e8f76d9e9790c498806e7070bbe37c10bc2e9
2018-12-03 22:59:12 +00:00
5b081219c9 IsFlat: inline when possible
Change-Id: Ia7471d29f73233cdc58cd11ae8bdf7ce31b9ce9f
2018-11-29 14:37:29 -08:00
381b7b54a0 IsFlat: use int for thresh
thresh is defined by FLATNESS_LIMIT_* which ranges from 2-10.

score_t is int64 which is a touch overkill.

Change-Id: I308bd440bf11643665d3642fe361495a257b6e52
2018-11-29 14:34:17 -08:00
6ed15ea1cd fix unprobable leak in webp_sdl.c
Change-Id: I26f21f4a09349bf7e7cede0d906f55f497235ff6
2018-11-27 11:59:31 +01:00
22bbb24ea8 Merge "IsFlat: return int" 2018-11-18 16:31:47 +00:00
8b3fb2389b Merge tag 'v1.0.1'
libwebp-1.0.1

- 11/2/2018: version 1.0.1
  This is a binary compatible release.
  * lossless encoder speedups
  * big-endian fix for alpha decoding (issue #393)
  * gif2webp fix for loop count=65535 transcode (issue #382)
  * further security related hardening in libwebp & libwebpmux
    (issues #383, #385, #386, #387, #388, #391)
    (oss-fuzz #9099, #9100, #9105, #9106, #9111, #9112, #9119, #9123, #9170,
              #9178, #9179, #9183, #9186, #9191, #9364, #9417, #9496, #10349,
              #10423, #10634, #10700, #10838, #10922, #11021, #11088, #11152)
  * miscellaneous bug & build fixes (issues #381, #394, #396, #397, #400)

* tag 'v1.0.1':
  update ChangeLog
  Fix pair update in stochastic entropy merging.
  README.mux: add a reference to the AnimDecoder API
  CMake: fix webp_js compilation
  update NEWS
  bump version to 1.0.1
  Speed-up: Make sure we only initialize histograms when needed.
  update AUTHORS
  img2webp: add help note about arguments from a file
  Speedups for empty histograms.
  Split HistogramAdd to only have the high level logic in C.
  Fix compilation on windows and clang-cl+ninja.

Change-Id: I4b58eee66b25da184ac4bf4c70e43e43682b3a23
2018-11-16 23:14:29 -08:00
f435de9575 IsFlat: return int
IsFlat is a boolean function. Don't use a specialized return type.

Change-Id: I070395082023ceb50251c44f5f4253b90394710c
2018-11-16 11:22:41 -05:00
41521aed47 utils.h: only define WEBP_NEED_LOG_TABLE_8BIT when needed
Change-Id: I6ba7a4288034decc5235f07013bd7877545a8b61
2018-11-16 01:45:08 -08:00
9f4d4a3f49 neon: GetResidualCost
Direct copy of sse2. Slight improvement because neon has
abs().

flower.ppm had minimal improvement. Somewhat expected because
GetResidualCost_C is only ~3.6%

mug.ppm had a better improvement because GetResidualCost_C is
almost 9%.

C    2.150
NEON 2.130

BUG=b/118740850

Change-Id: Ibc0dd97a81596635f5599cf568205974b4fd2597
2018-11-14 11:46:58 -08:00
0fd7514b55 neon: SetResidualCoeffs
Much faster with aarch64. Still somewhat faster without vmaxv.

C: 3.700s
ArmV7: 3.675
aarch64: 3.600

BUG=b/118740850

Change-Id: I3be852da89633eca4bddce443c87f5e4a2f55868
2018-11-14 11:46:40 -08:00
f95a996c64 Simpler histogram clustering.
Instead of re-organizing the list of histograms, set
the unused ones to NULL.

Change-Id: I8d25e1bb8f78ae9486ff358cc647ba1821cd5fcf
2018-11-11 10:59:34 +01:00
e85d3313d6 update ChangeLog
Change-Id: I39043d4986664312947a0668cb1b7bfbcf5a2477
2018-11-08 15:29:51 -08:00
fa8210e43c Fix pair update in stochastic entropy merging.
The old code simply did not make sense.
The effect is that the pair would be popped from the
queue no matter what; as the queue is small, it does
not matter that much on the results.
But it will matter for a later CL.

Change-Id: If50c9fa9d7f3ac3c48bb7336d81479287d4944c4
(cherry picked from commit 485ff86fbb)
2018-11-07 23:07:24 -08:00
fd198f7370 add codereview.settings
Allow uploading changes with 'git cl upload'

Change-Id: I5c96ff42a00656978980624a863f78fb10de033b
2018-11-07 19:12:35 -08:00
825389acba README.mux: add a reference to the AnimDecoder API
this balances the AnimEncoder section

Change-Id: I205c8d0bd6104509e06737dcbf9a7651fd4bc6a3
2018-11-06 18:47:38 -08:00
3be698c3d3 CMake: fix webp_js compilation
Stick to the strict necessary for running webp_js,
and avoid building sub-lib or examples with heavy dependencies.

Change-Id: Ife4170a7839fb3201b2cf158d98d17bebe10008f
(cherry picked from commit 4cd0582d50)
2018-11-06 17:20:43 -08:00
485ff86fbb Fix pair update in stochastic entropy merging.
The old code simply did not make sense.
The effect is that the pair would be popped from the
queue no matter what; as the queue is small, it does
not matter that much on the results.
But it will matter for a later CL.

Change-Id: If50c9fa9d7f3ac3c48bb7336d81479287d4944c4
2018-11-07 00:33:14 +01:00
4cd0582d50 CMake: fix webp_js compilation
Stick to the strict necessary for running webp_js,
and avoid building sub-lib or examples with heavy dependencies.

Change-Id: Ife4170a7839fb3201b2cf158d98d17bebe10008f
2018-11-06 16:07:05 +01:00
4cbb4caf49 update NEWS
Change-Id: I4a97342d47247724f12da9d8a7d8f22047c2a179
2018-11-03 11:27:07 -07:00
f5a5918d13 bump version to 1.0.1
libwebp{,decoder} - 1.0.1
libwebp libtool - 7.3.0
libwebpdecoder libtool - 3.3.0

mux - 1.0.1
libtool - 3.3.0

demux - 1.0.1
libtool - 2.5.0

Change-Id: I4310caed27d1e53cc8c1b534571e3d653ad434c8
2018-11-02 20:36:14 -07:00
d61385db35 Speed-up: Make sure we only initialize histograms when needed.
Also, histograms in a HistogramSet can be initialized all
at once.

Change-Id: Ibbfa6034dce58dca8bb9113487e2ae507222ce7d
(cherry picked from commit 6752904b2f)
2018-11-02 17:40:00 -07:00
6752904b2f Speed-up: Make sure we only initialize histograms when needed.
Also, histograms in a HistogramSet can be initialized all
at once.

Change-Id: Ibbfa6034dce58dca8bb9113487e2ae507222ce7d
2018-10-31 11:54:09 +00:00
0c57031629 update AUTHORS
Change-Id: Ie7731464088d985a7398401c8ef45bd26c536fe5
2018-10-27 12:40:29 -07:00
301a2ddae5 img2webp: add help note about arguments from a file
this was added in:
94a8377b extract the command-line parsing helpers to example_util

and matches the help in webpmux

https://groups.google.com/a/webmproject.org/d/msg/webp-discuss/DJs-w_-Id6o/svFXs2CqBgAJ

BUG=webp:101

Change-Id: I2944d1fb1ed3030c356960be2a6c8de15a79311f
(cherry picked from commit b6284d8247)
2018-10-26 22:53:15 -07:00
f0abab9217 Speedups for empty histograms.
When histograms are empty, it is easy to add them.
They should also not be considered when merging histograms
(it is a waste of CPU).
This does not change the compression performance,
just the speed.

Change-Id: I42c721ca0f9c5ea067e73b792aa3db6d5e71d01f
(cherry picked from commit decf6f6b87)
2018-10-26 22:53:05 -07:00
f2dfd92557 Split HistogramAdd to only have the high level logic in C.
Change-Id: Ic9eaebf7128ca0215b49d2a13bde1f5b94a28061
(cherry picked from commit dea3e89983)
2018-10-26 22:52:50 -07:00
06b7bc7dec Fix compilation on windows and clang-cl+ninja.
Change-Id: I4e468519e1bcb99da5057f3b6646b077a1e0e7f1
(cherry picked from commit a376e7b96a)
2018-10-26 22:52:35 -07:00
b6284d8247 img2webp: add help note about arguments from a file
this was added in:
94a8377b extract the command-line parsing helpers to example_util

and matches the help in webpmux

https://groups.google.com/a/webmproject.org/d/msg/webp-discuss/DJs-w_-Id6o/svFXs2CqBgAJ

BUG=webp:101

Change-Id: I2944d1fb1ed3030c356960be2a6c8de15a79311f
2018-10-26 06:16:56 +00:00
decf6f6b87 Speedups for empty histograms.
When histograms are empty, it is easy to add them.
They should also not be considered when merging histograms
(it is a waste of CPU).
This does not change the compression performance,
just the speed.

Change-Id: I42c721ca0f9c5ea067e73b792aa3db6d5e71d01f
2018-10-20 13:23:50 +02:00
dea3e89983 Split HistogramAdd to only have the high level logic in C.
Change-Id: Ic9eaebf7128ca0215b49d2a13bde1f5b94a28061
2018-10-19 14:03:28 +02:00
632798ae6f Merge "Fix compilation on windows and clang-cl+ninja." 2018-10-17 13:02:19 +00:00
dc1a9518bc Merge "libwebp: Unicode command tools on Windows" 2018-10-17 11:55:49 +00:00
9cf9841b5e libwebp: Unicode command tools on Windows
Define macros in examples/unicode.h to use Unicode argv
on Windows. Keep char everywhere on Unix since it handles
UTF-8 without any change.

Impact:
 - All fopen () and SHCreateStreamOnFile(),
 - All fprintf() printing file paths,
 - All strcmp() used with "-",
 - File path parsing,
 - Gif reading.

Concerned executables from examples/ and extras/:
  anim_diff, anim_dump, vwebp, vwebp_sdl,
  cwebp, dwebp, gif2webp, img2webp,
  webpmux, webpinfo, webp_quality, get_disto

When compiled on Windows with Unicode enabled, webpmux and
img2webp will not work when used with an argument file and
will print "Reading arguments from a file is a feature
unavailable with Unicode binaries."

BUG=webp:398

Change-Id: Ic55d222a3ce1a715f9c4cce57ecbe2705d5ce317
2018-10-17 13:19:40 +02:00
981794958b remove some minor TODOs
if we didn't do these, they were probably non vital.

Change-Id: I952d2351f5c71934247d4d6631cfdfe070f76bf5
2018-10-17 10:48:19 +02:00
a376e7b96a Fix compilation on windows and clang-cl+ninja.
Change-Id: I4e468519e1bcb99da5057f3b6646b077a1e0e7f1
2018-10-16 16:20:47 +02:00
cbf82cc04d Remove AVX2 files.
There is only enc_avx2.c and we never managed to get
something fast enough.

Change-Id: I7465b5d8ccf47d9aa612173b8f80f96060cdb366
2018-10-16 14:12:03 +02:00
5030e90278 Merge "TIFF decoder: remove unused KINV definition" 2018-10-15 18:16:24 +00:00
ac5433118a Remove a few more useless #defines
Change-Id: I211e9bcb1c37d0ebc108896f109b23ce915e22b4
2018-10-15 16:26:10 +02:00
123d330699 TIFF decoder: remove unused KINV definition
+ some #undef

Change-Id: Ib8b8357ad3a6458ca421a59d9ad625656dd54afe
2018-10-14 08:24:43 +02:00
ef1094b0fe Merge "- install pkg-config files during the CMake build" 2018-10-10 03:25:02 +00:00
b911fbc980 libwebp: Remove duplicate GIFDisplayError in anim_util
GIFDisplayError() is already defined exactly the same way
in gifdec. Remove it from anim_util.c and add dependency.

Change-Id: Iec01b41c44d0b61b3a279b8cd754d9917d64f804
2018-10-09 17:29:54 +02:00
eee00b6627 - install pkg-config files during the CMake build
Signed-off-by: Konstantin Ivlev <tomskside@gmail.com>
Change-Id: I88b1a22b19dd9ecdb2ae38082fa9580dbc66d98c
2018-10-08 16:02:12 -07:00
ac3ec8c91d Merge "Clean-up the common sources in dsp." 2018-10-08 15:19:40 +00:00
3e13da7b4f Clean-up the common sources in dsp.
Change-Id: I1b995e6517e8437127a433dccbb5b2db63e7c3a3
2018-10-08 15:00:01 +02:00
5c395f1d71 libwebp: cmake-format all
https://github.com/cheshirekow/cmake_format
A complete row of # is replaced by only one,
so add a space after the first one to keep it.

Change-Id: I367749353a555c89c717f1939220699e43ecab2c
2018-10-05 14:23:06 +02:00
e7a697297b libwebp: Add extras targets in CMakeLists.txt
To be compiled with Visual Studio on Windows through CMake.
Targets are get_disto, vwebp_sdl, webp_quality.

Change-Id: Idec1e19b61b6a661011effee42f7440264afd3ed
2018-10-04 18:58:43 +02:00
e52485d6db libwebp: Rename macros in webpmux.c
For clarity and to avoid:
  webpmux -info
  ERROR: Too many arguments for '-info'.

Change-Id: Iae8e62ed8997f7a4ea183d1b3505373255c3c73a
2018-10-03 21:39:38 +02:00
92dc0f0937 clean-up MakeInputImageCopy()
use pointer increments.

Change-Id: I269412d41a58ab9ffd7fc0f3d479fe73a3d07b9e
2018-10-02 14:46:35 +00:00
39952de265 VP8IteratorImport: add missing 'const'
Change-Id: I0b259e2979de787b5e4606ae93f23df1b49e4c8f
2018-10-02 14:46:27 +00:00
382af7a2dd clean-up WebPBlendAlpha
use pointers instead of ptr + y * stride
+ misc re-org

Change-Id: I29fca781aa44f3bed3f8c1e956c5387705c80ed1
2018-10-02 13:57:12 +00:00
14d020f6e6 libwebp: Use ExUtilGet*() in anim_diff
Instead of strtod() or strtol().

Change-Id: I320373cd969c6969cf4b1491391a95668d1b0beb
2018-10-02 13:55:57 +02:00
0d92ff25f2 libwebp: remove useless variable in gif2webp
"out" is never used.

Change-Id: I4441308ef2267b2a9443add240d2fccabfb817f6
2018-10-02 11:39:48 +02:00
556cb1b45e Merge "CMake: Set WEBP_BUILD_GIF2WEBP to off" 2018-10-01 13:14:46 +00:00
da26ee49a6 CMake: Set WEBP_BUILD_GIF2WEBP to off
Instead of unsetting WEBP_BUILD_GIF2WEBP,
disable it to keep it displayed in ccmake.
Disable WEBP_BUILD_GIF2WEBP before it's tested.
Do the same for WEBP_BUILD_ANIM_UTILS.

Change-Id: I91920814fbda4825ced9a801bb005f8d44bfe09c
2018-10-01 13:48:22 +02:00
b2a867c038 cwebp: Don't premultiply during -resize if -exact
Fix issue where color data is discarded in fully transparent
areas when -resize -exact.
BUG=webp:397

Change-Id: I58ce8d5ae172d5d0f0138e07c7df3a3c6cbd0019
2018-10-01 10:14:51 +02:00
637141bc7c pngdec: fix build w/libpng < 1.4.x
after:
bc5092b1 pngdec: set memory functions

png_alloc_size_t was added in 1.4 use png_size_t in earlier versions

Change-Id: If65ac1c501e2d497b1be480095bf21f06ea7026a
2018-09-28 17:42:27 -07:00
bc5092b162 pngdec: set memory functions
use png_create_read_struct_2 to set a malloc function allowing the code
to fail on large allocations while fuzzing

Change-Id: Iaca1b93ecc6570067708f3ae2db07fbca74386ee
2018-09-28 00:35:47 -07:00
50d8345ae6 Fix CMake math library.
Just in case we have a warning.

Change-Id: I5f2aabf5f4adaaf9ba6c4fbbbf352603259e8081
2018-09-21 15:40:40 +02:00
6aa3e8aaf3 Fix math library on Visual Studio.
The code was compiled but optimized, and no math function
was used.

Change-Id: Ib2ab262c072761ec41df8f9260a1e0fe57d01cef
2018-09-11 18:28:44 +02:00
d71df4e2ee Fix math library finding in CMake.
BUG=webp:396

Change-Id: I8ca35573c242cba24f1e82997b4fb289a48a3005
2018-09-03 14:35:50 +00:00
de08d72741 cosmetics: normalize include guard comment
Change-Id: I0e08ec604aad8412cfe3d3670d773f4ae5650375
2018-08-22 14:46:53 -07:00
009562b403 vwebp: Fix bug when Dispose then NoBlend frames
The graphical bug happens when there is a frame disposed to background
color, followed by another frame that does not blend, and their areas
don't fully overlap. Only the previous frame clears its part of the
viewport. The fix consists in clearing the screen for the previous and
the current frame if needed.

Change-Id: I3425cf7297f0c7b2cf13a3a61b517cc0b1c031d8
2018-08-03 14:15:13 -07:00
423f257930 Fix up CMake to create targets.
Change-Id: I4b0b71d0ab7e49e237bd928de690915cc3b86be2
2018-07-25 14:04:18 +02:00
907208f97e Wait for all threads to be done in DecodeRemaining.
This could lead to a race condition.

BUG=oss-fuzz:9417

Change-Id: Ifef4001115888541cb76095e1c0226487d497b78
2018-07-20 17:03:01 -07:00
4649b3c422 vwebp: Add background color display option
Option -usebgcolor may be used to display ANIM background color (or white if no ANIM chunk), blended on top of checkerboard. By default this is disabled (old behavior) to easily see transparent areas. Spec says that "background color MAY be used", so it's an option.
Key b may be pressed to toggle ANIM background color display. There are visual artifacts (leftovers) when toggling during an animation. This is already the case for rescaling, toggling info etc. (fixing it implies storing viewport render or rendering whole animation from start till current frame).

BUG=webp:394

Change-Id: If9ab898b2eac77226f30f062d522f9861789ef8f
2018-07-20 12:54:30 +02:00
78ad57a36a Fix bad glClearColor parameters
Container spec indicates that background color is written
in BGRA byte order, but glClearColor() parameters are RGBA.
Anyway the checkerboard is displayed right after glClear()
calls so it replaces background color.

In response to webp-discuss/TkLHALGaHaM

Change-Id: Ief5435fadfd6a422b881a9dc240b5e8dc6546e19
2018-07-18 10:50:33 +02:00
da96d8d9ab Allow for a non-initialized alpha decompressor in DoRemap.
BUG=oss-fuzz:9364

Change-Id: Ib1a1c6b0ccfcc255505f019e3e8fd15db73bc4b6
2018-07-13 22:09:06 +02:00
2563db4759 fix rescaling rounding inaccuracy
We should be using 'floor' when doing the final divide.

-> new MACRO is MULT_FIX_FLOOR()

     XXX*** Mips code is DISABLED for now ***XXX

I'll update and re-enable it in a later
patch, since this code needs some refactoring first.

BUG=oss-fuzz:9179

Change-Id: Ic0693cdca4e71f5beab1029475e35c4d06b12d13
2018-07-10 22:45:50 -07:00
211f37ee63 fix endian problems in pattern copy
CopyBlock8b() was over-using memcpy() of 16b values.

BUG=webp:393

Change-Id: Id56f10d334b9a453fbcf50dabfaa63529bcff7e5
2018-07-10 05:15:26 +00:00
5f0f5c07c4 Make sure partition #0 is read before VP8 data in IDecode.
Change-Id: Ie0b264b6422774343206ddba3c2820a0cf37ffc0
2018-07-09 20:20:52 +02:00
de98732b04 fix GetColorf() bug
We should only use the lower 8 bits, masking was missing.

Change-Id: I3072168e100b242356ad57b5a73b7f4d6ebfbb9e
2018-07-06 21:25:41 -07:00
4338cd36fe misc fixes in libwebpmux
* Assert chunklist
  * fix potential memory leak and
  * fix null pointer access

There should not be several alpha_ or img_ chunks in SynthesizeBitstream. Use ChunkListDelete in MuxImageRelease to be safe.
A null pointer accessed in WebPMuxPushFrame triggered a harmless runtime error.

Change-Id: I3027f8752093652bd41f55e667d041c0de77ab6e
2018-07-04 19:03:21 +00:00
e00af13ef4 fix signatures after a9ceda7ff1
fixes vs10_x64 build.

Change-Id: I636e6a5bea1239bacdaa4d160be1d645636c3ae8
2018-07-04 06:03:37 +00:00
a9ceda7ff1 Speed-up chunk list operations.
The chunk list only has two operations: append and set
to one element. The two operations are split and the append
one is sped up by storing the last element.
Corrupted data could make a very long list to search through.

BUG=oss-fuzz:9190

Change-Id: I1aa813ca629df29efaa3b46dbd4c4c42dbeaa34c
2018-07-03 16:36:34 +02:00
2281bbf6f7 Merge "Better handling of bogus Huffman codes." 2018-07-03 08:33:35 +00:00
39cb9aad85 Better handling of bogus Huffman codes.
The standard allows for Huffman images with any coefficients.
Hence potentially big memory allocations. The previous workaround
was "trying" things out, the new one is more rigorous and
only allocates what is needed, modifying the Huffman image
to contain the minimal set of coefficients.

BUG=oss-fuzz:8623,oss-fuzz:9111,oss-fuzz:9134

Change-Id: I6a972e90e4ae509c15cb41ee22c58b775fa3f4aa
2018-07-03 10:00:52 +02:00
89cc9d3787 Merge "fix read-overflow while parsing VP8X chunk" 2018-07-03 03:06:42 +00:00
95fd650706 fix read-overflow while parsing VP8X chunk
The available size was not checked before parsing the VP8X data

BUG=oss-fuzz:9100,oss-fuzz:9123

Change-Id: I0143cc4554883c1015e2f084a0e371229e04a8ca
2018-07-03 02:36:25 +00:00
9e729fe19b Fix VP8IoTeardownHook being called twice on worker sync failure
idec_dec.c, DecodeRemaining: Set decoder state to ERROR to prevent VP8ExitCritical to be called again

Change-Id: Id5f893f45c348e1c529680d930e640f780a73d4c
2018-07-02 13:37:46 +02:00
29fb8562c6 Merge "muxread,anmf: fail on multiple image chunks" 2018-06-30 04:25:20 +00:00
eb82ce76dd muxread,anmf: fail on multiple image chunks
treat an ANMF chunk containing multiple VP8/VP8L file as malformed.
fixes a WebPMuxImage::img_ leak.

Though the invalid free in #9106 was avoided in (ubsan):
be738c6d muxread,ChunkVerifyAndAssign: validate chunk_size
that file would still cause a leak similar to #9099.

BUG=oss-fuzz:9099,oss-fuzz:9106

Change-Id: Ib873446a1188afeeb2fe5d53a86b75e0c5de9573
2018-06-29 17:52:58 -07:00
1344a2e947 fix alpha-filtering crash when image width is larger than radius
(we also limit radius based on height too, for good measure, although it's not an asan bug)

fixes oss-fuzz issue #9105

Change-Id: Ie0d79dd81480dc4e2b653b7e992e5cdcd3dfa834
2018-06-29 11:02:17 -07:00
be738c6d39 muxread,ChunkVerifyAndAssign: validate chunk_size
before accounting for padding which might overflow if chunk_size is >
MAX_CHUNK_PAYLOAD.

BUG=webp:387,webp:388

Change-Id: I3985b8817ed4faaec0629102c5333c228a0e9c98
2018-06-20 18:21:48 -07:00
2c70ad76c9 muxread,CreateInternal: fix riff size checks
previously when adjusting size down based on a smaller riff_size the
checks were insufficient to prevent 'size -= RIFF_HEADER_SIZE' from
rolling over causing ChunkVerifyAndAssign to over read. the new checks
are imported from demux.c.

BUG=webp:386

Change-Id: If863c4a9892977b9ade7dd894392a0ecae13775c
2018-06-14 18:06:44 -07:00
569001f19f Fix for thread race heap-use-after-free
BUG=webp:384

Change-Id: I3a300b45ccae33470888cf2e35a7e937579c9409
2018-06-13 10:45:12 +02:00
c56a02d971 Android.mk: use LOCAL_EXPORT_C_INCLUDES w/public libs
dependents can then pickup the include path for webp/ automatically

Change-Id: Ie768a93d0054f8ebc1720f16fbb550c0b10ef61d
2018-06-07 16:12:58 -07:00
1579559662 CMakeLists.txt,cosmetics: normalize if() formatting
+ break a long line

Change-Id: Ia508d517e89dd2109b655c220b66d8aa834a3b52
2018-06-05 09:27:08 -07:00
1a44c233b9 Merge "cmake: add support for webpmux" 2018-06-05 12:54:53 +00:00
e9569ad708 Merge "configure,*am,cosmetics: s/WANT_/BUILD_/" 2018-06-04 23:23:36 +00:00
35c7de6fc4 cmake: add support for webpmux
Change-Id: Ia694ba49549c43956f6552e6981a46df0fe7e686
2018-06-04 15:44:04 -07:00
0f25e61c13 WebpToSDL(): fix the return value in case of error
spotted Diego Casorran

Change-Id: I48822ade22eb8fcef85043a84d712e892324476d
2018-06-04 09:51:53 +02:00
5d8985de47 configure,*am,cosmetics: s/WANT_/BUILD_/
'BUILD_' is more common across the build files

Change-Id: Id302dba2e9e567c186a9da1da0fba44517e85d07
2018-06-02 10:41:49 -07:00
895fd28f9b Merge "man/Makefile.am: add img2webp.1" 2018-06-02 17:37:04 +00:00
5cf3e2afb5 man/Makefile.am: add img2webp.1
Change-Id: I83ed6e85d36b79e6a97b93221fadb7d35e2305c5
2018-06-01 19:25:53 -07:00
2a9de5b9d3 Add build rules for anim_diff & anim_dump utils.
Change-Id: I2697a6dc3c419a19909262003a6d6a263d3c2747
2018-06-01 19:23:47 -07:00
71ed73cf86 fix invalid check for buffer size
BUG=webp:383

Change-Id: I8ebbb5ca4860d73c3b59b12e238b54a89184bed0
2018-05-25 13:25:39 +02:00
af0e4fbb06 gif2webp: fix transcode of loop count=65535
with loop_compatibility disabled (the default), non-zero loop counts
will be incremented by 1 for browser rendering compatibility. the max,
65535, is a special case as the muxer will fail if it is exceeded; avoid
increasing the limit in this case. this isn't 100% correct, but should
be close enough given the high number of iterations.

BUG=webp:382

Change-Id: Icde3e98a58e9ee89604a72fafda30ab71060dec5
2018-05-11 12:10:25 -07:00
dce5d76431 Limit memory allocation when reading invalid Huffman codes.
BUG=webp:381

Change-Id: I6b68a33689a3309691eba582b759131b81b612c1
2018-05-03 13:53:44 +02:00
f9df0081a7 Merge "cmake: quiet glut deprecation warnings on OS X" 2018-04-25 18:45:52 +00:00
dc39b16fe4 webpmux.1: correct grammar
argument -> arguments

Change-Id: I57132c942150f18dccc5ef84c4c09a6dcc054ffa
2018-04-23 16:06:54 -07:00
c7aa1264f0 cwebp.c: fix a missing \n
+ lot more coverage of exotic options and combinations

Change-Id: I4d8e571a6d94023af9848a2bbd98edda05a54f33
2018-04-23 15:45:41 -07:00
53aa51e9a3 Merge tag 'v1.0.0'
libwebp-1.0.0

- 4/2/2018: version 1.0.0
  This is a binary compatible release.
  * lossy encoder improvements to avoid chroma shifts in various circumstances
    (issues #308, #340)
  * big-endian fixes for decode, RGBA import and WebPPictureDistortion
  Tool updates:
    gifwebp, anim_diff - default duration behavior (<= 10ms) changed to match
                         web browsers, transcoding tools (issue #379)
    img2webp, webpmux - allow options to be passed in via a file (issue #355)

* tag 'v1.0.0': (23 commits)
  update ChangeLog
  webp-container-spec: correct frame duration=0 note
  vwebp: Copy Chrome's behavior w/frame duration == 0
  update ChangeLog
  add WEBP_DSP_INIT / WEBP_DSP_INIT_FUNC
  fix 16b overflow in SSE2
  makefile.unix: add DEBUG flag for compiling w/ debug-symbol
  cwebp,get_disto: fix bpp output
  cmake: Make sure we use near-lossless by default.
  fix bug in WebPImport565: alpha value was not set
  update ChangeLog
  Revert "Use proper targets for CMake."
  Use proper targets for CMake.
  Remove some very hard TODOs.
  {de,}mux/Makefile.am: add missing headers
  makefile.unix,dist: use ascii for text output
  add -version option to anim_dump,anim_diff and img2webp
  webp_js: fix webp_js demo html
  update ChangeLog
  update AUTHORS
  ...

Change-Id: I5659406c022a0964f728ce2eb35338fd9c195466
2018-04-23 14:54:39 -07:00
698b8844e3 update ChangeLog
Change-Id: Ica00314a3dfacad89ec62a3dc2df0d476e6397af
2018-04-20 20:04:55 -07:00
8d510751da webp-container-spec: correct frame duration=0 note
the interpretation of a 0 duration depends on the implementation;
merging of multiple frames isn't guaranteed, some may enforce a minimum
duration.

BUG=webp:380

Change-Id: Idf592049d2092e4cc5cfb2e4c59ddbc91bd52f9c
(cherry picked from commit 71c39a06c8)
2018-04-20 19:59:21 -07:00
e6b2164e3a vwebp: Copy Chrome's behavior w/frame duration == 0
BUG=webp:380

Change-Id: Ia0b108d7da755ff91cf6c84581412e47a3a6e5d9
(cherry picked from commit fd3d5756cb)
2018-04-20 19:59:15 -07:00
094b3b285b cmake: quiet glut deprecation warnings on OS X
BUG=webp:187

Change-Id: I652b474dc8389b2219a424d43dec80c3bf9ba62c
2018-04-20 19:57:16 -07:00
71c39a06c8 webp-container-spec: correct frame duration=0 note
the interpretation of a 0 duration depends on the implementation;
merging of multiple frames isn't guaranteed, some may enforce a minimum
duration.

BUG=webp:380

Change-Id: Idf592049d2092e4cc5cfb2e4c59ddbc91bd52f9c
2018-04-20 15:23:12 -07:00
fd3d5756cb vwebp: Copy Chrome's behavior w/frame duration == 0
BUG=webp:380

Change-Id: Ia0b108d7da755ff91cf6c84581412e47a3a6e5d9
2018-04-20 12:53:10 -07:00
b0c966fb66 Build vwebp from CMake.
Change-Id: I428fd563964a72d58bee75e651c581fbbdb0eb26
2018-04-20 11:13:09 +02:00
d20b770713 update ChangeLog
Change-Id: I809f4b9581802d43503cba85f03c90e3a98627a4
2018-04-17 18:37:49 -07:00
0d5fad46cf add WEBP_DSP_INIT / WEBP_DSP_INIT_FUNC
this internalizes the init checks and provides stronger synchronization
with pthreads when available while still allowing VP8GetCPUInfo to be
modified (mostly for testing purposes). windows is left as is since a
critical section or mutex would cause a leak.

Change-Id: Ieb997e014f2805c0ae39c16f13337663521356f4
(cherry picked from commit d77bf512bd)
2018-04-17 18:01:34 -07:00
d77bf512bd add WEBP_DSP_INIT / WEBP_DSP_INIT_FUNC
this internalizes the init checks and provides stronger synchronization
with pthreads when available while still allowing VP8GetCPUInfo to be
modified (mostly for testing purposes). windows is left as is since a
critical section or mutex would cause a leak.

Change-Id: Ieb997e014f2805c0ae39c16f13337663521356f4
2018-04-17 11:45:34 +00:00
c1cb86af5f fix 16b overflow in SSE2
the 'accum' variable can be larger than 15b for large
rescale values.

Assert triggered:
 src/dsp/rescaler_sse2.c:249: RescalerExportRowExpand_SSE2: Assertion `v >= 0 && v <= 255' failed.
 src/dsp/rescaler_sse2.c:350: RescalerExportRowShrink_SSE2: Assertion `v >= 0 && v <= 255' failed.

-> fall back to C implementation in this case for now

Change-Id: I7ea1cb72301cafc1459be403f6a6f4e3cbc89bb1
2018-04-11 21:25:06 +00:00
e577feb7c2 makefile.unix: add DEBUG flag for compiling w/ debug-symbol
usage example: make -f makefile.unix DEBUG=

Change-Id: I5aefe026a3364e5db5e0220b9fa506687cb98a8d
2018-04-11 20:51:04 +00:00
99be34b3a8 cwebp,get_disto: fix bpp output
bits-per-pixel were intended, not bytes-per-pixel

Change-Id: I023349013ac5956154ab4526bd1e195dfe95b8ab
(cherry picked from commit e122e511cf)
2018-04-10 18:00:23 -07:00
e122e511cf cwebp,get_disto: fix bpp output
bits-per-pixel were intended, not bytes-per-pixel

Change-Id: I023349013ac5956154ab4526bd1e195dfe95b8ab
2018-04-10 15:51:23 -07:00
f5565ca84a cmake: Make sure we use near-lossless by default.
The name of the CMake variable needs to be the same
as the C define used in cmake/config.h.in.

Change-Id: Id56d338617f6e4ed5f1da7ce01006d324ef4989f
2018-04-10 14:40:33 -07:00
d898dc14a5 fix bug in WebPImport565: alpha value was not set
Change-Id: I2af4efb3c6ed49800bc16dbd4a997f7a95931918
2018-04-09 18:39:45 +00:00
1c8f358df4 Fix CMake with WASM.
Change-Id: I21c78999484815c58b5b2c9795310da9d04888e9
2018-04-05 16:25:15 +02:00
a0215fb7dc webp_js: fix webp_js demo html
We need to export 'Module.cwrap' method.

Change-Id: I2986c5a4c06630ae3f95086a114e727a86c99a2b
2018-04-05 16:25:15 +02:00
882784b03d update ChangeLog
Change-Id: I7e38d9beb2d733b85f56a44add8481cb45faf698
2018-04-03 20:22:31 -07:00
2f930e0872 Revert "Use proper targets for CMake."
This reverts commit 8165e8fb3b.

breaks webp_js builds: missing includes, multiply defined symbols

Change-Id: I8df7eda3974e708c2a96b98600ec69981ec7aacb
2018-04-03 19:53:20 -07:00
8165e8fb3b Use proper targets for CMake.
Also fix the bug where near lossless was not used
and allow examples to be built by default.

Change-Id: Ieb5ef77fafe83f3776ff4fd27a6d26534c7a51f3
(cherry picked from commit e155dda0cc)
2018-04-03 18:38:09 -07:00
3f157dd5e7 Remove some very hard TODOs.
Change-Id: I3d1b0072e0ac9125840fbbd76e91d151c82489ec
(cherry picked from commit 4033e1d70d)
2018-04-03 18:38:00 -07:00
abb4776006 Merge "Use proper targets for CMake." 2018-04-04 01:35:03 +00:00
cd758a1745 {de,}mux/Makefile.am: add missing headers
demux + mux: format_constants.h
demux: decode.h (included by demux.h for anim_decode)

Change-Id: I290a3416d4e47b4b6ebc14e99775d9db1ce5aec2
2018-04-03 18:02:27 -07:00
e155dda0cc Use proper targets for CMake.
Also fix the bug where near lossless was not used
and allow examples to be built by default.

Change-Id: Ieb5ef77fafe83f3776ff4fd27a6d26534c7a51f3
2018-04-03 17:49:08 -07:00
b892b8ba8b makefile.unix,dist: use ascii for text output
this prevents unknown escapes containing '-'s getting stripped on OS X
when a tty targeted font is used

Change-Id: I11d77f2984d9fd67a8b22948fb21e4c11396aec4
2018-04-03 12:55:01 -07:00
64a57d0587 add -version option to anim_dump,anim_diff and img2webp
This is to harmonize the -h/-version options on all our examples.

+ added GetAnimatedImageVersions() method to anim_util.*

Change-Id: I2304a1c29e310682e97f236d3867274a192a7a09
2018-04-03 11:46:17 -07:00
994be82d00 Merge "Remove some very hard TODOs." 2018-04-03 14:10:50 +00:00
4033e1d70d Remove some very hard TODOs.
Change-Id: I3d1b0072e0ac9125840fbbd76e91d151c82489ec
2018-04-03 15:17:21 +02:00
fc1b8e3a8b webp_js: fix webp_js demo html
We need to export 'Module.cwrap' method.

Change-Id: I2986c5a4c06630ae3f95086a114e727a86c99a2b
2018-04-03 13:56:53 +02:00
15aa48d905 update ChangeLog
Change-Id: I4a34bfa69c203bec92b42f91d6e7d79a46780584
2018-04-02 17:38:41 -07:00
e607dabcf2 update AUTHORS
Change-Id: I51c52f4f9b37dee36a9201893d7acf1fde46a78e
2018-04-02 16:57:46 -07:00
38410c082f [CFI] Remove function pointer casts
Control Flow Integrity [1] indirect call checking verifies that function
pointers only call valid functions with a matching type signature. This
change eliminates function pointer casts that were causing cfi-icall
failures.

[1] https://www.chromium.org/developers/testing/control-flow-integrity

BUG=chromium:827826

Change-Id: I5db021d06390a6cefd670fdd2f0d34c9e530465e
(cherry picked from commit 978eec2507)
2018-04-02 16:57:14 -07:00
978eec2507 [CFI] Remove function pointer casts
Control Flow Integrity [1] indirect call checking verifies that function
pointers only call valid functions with a matching type signature. This
change eliminates function pointer casts that were causing cfi-icall
failures.

[1] https://www.chromium.org/developers/testing/control-flow-integrity

BUG=chromium:827826

Change-Id: I5db021d06390a6cefd670fdd2f0d34c9e530465e
2018-04-02 16:04:47 -07:00
c57b273698 bump version to 1.0.0
libwebp{,decoder} - 1.0.0
libwebp libtool - 7.2.0
libwebpdecoder libtool - 3.2.0

mux - 1.0.0
libtool - 3.2.0

demux - 1.0.0
libtool - 2.4.0

Change-Id: I4310caed27d1e53cc8c1b534571e3d653ad434c8
2018-04-02 15:36:15 -07:00
cba2885375 update NEWS
Change-Id: I3470bf02d20f87e17bbabcb3e415a7c2dd5804ed
2018-04-02 15:36:15 -07:00
c909d53182 Merge "remove some deprecation warning on MacOSX" 2018-03-31 08:09:41 +00:00
217443c71a remove some deprecation warning on MacOSX
Change-Id: I3e6de5ae6d84aa7906049eb55b6373c5123b0158
2018-03-31 09:30:00 +02:00
b672bdfaad configure: quiet glut deprecation warnings on OS X
BUG=webp:187

Change-Id: Iad88b5fe417289f00dedcc32e7672fc0898e9ed1
2018-03-31 00:24:53 -07:00
daa9fcaf5b configure: use sdl-config if available
+ do a full link to ensure SDL_main is resolved if needed

fixes detection on OS X

BUG=webp:366

Change-Id: Id53329f5d1c2536c4584be61c6379fa76ff0e5de
2018-03-30 23:30:43 -07:00
dd174caeff Merge "imagedec: support metadata reading for WebP image decoding" 2018-03-30 03:18:39 +00:00
641cedccd3 imagedec: support metadata reading for WebP image decoding
Needs to link imagedec.a to demux/libwebpdemux.a

Change-Id: Id8f4068718b0e4a1e84607bccd5af5419120c231
2018-03-28 16:36:37 -07:00
065b2ce10e anim_diff: add a couple missing newlines in Help()
Change-Id: Iad2a4ad2555718f1822b82d38219940ed49385b8
2018-03-26 21:37:29 -07:00
c4cc114785 Merge "gif2webp: force low duration frames to 100ms" 2018-03-27 03:11:48 +00:00
09333097ed gif2webp: force low duration frames to 100ms
this is consistent with web browser behavior as well as various
transcoding tools (ffmpeg, gif2apng, etc).

also: update anim_diff to account for this new behaviour.

BUG=webp:379

Change-Id: I70cc72a6b401ef32b73cd182a3f12d993d495bf4
2018-03-24 08:26:53 +01:00
e03f0ec319 sharp_yuv: use 14b fixed-point precision for gamma
Output is <.1% difference in size, randomly.

Speed is 30-50% faster (-m 0 -sharp_yuv).
It also gives the exact same output on ARM and x86, because floats
are no longer used.

Change-Id: Id0f0aa748cc4fc0b82bac1fc5ca954775a0a1b7c
2018-03-23 20:19:28 +01:00
b2db361ca6 image_enc,WebPWritePNG: move locals after setjmp
this quiets a -Wclobbered warning on const has_alpha under gcc-7 and
brings the variables closer to their first use.

Change-Id: I8a24f275b7ff34a94d47b576bcf276dbedac2121
2018-03-08 22:58:11 -08:00
74e82ec64a Merge "WebPPictureDistortion: fix big-endian results order" 2018-02-20 21:20:45 +00:00
645d04ca7f Merge "cwebp,get_disto: report bpp" 2018-02-20 19:56:57 +00:00
120f58c3aa Merge "lossless*sse2: improve non-const 16-bit vector creation" 2018-02-20 19:56:07 +00:00
a7fe9412d0 WebPPictureDistortion: fix big-endian results order
match the little-endian BGRA order

Change-Id: Ie8f1ae3100fac478bae13e53121a6af5b2443374
2018-02-20 11:52:41 -08:00
e26fe06680 cwebp,get_disto: report bpp
Change-Id: Iefbd834baa4f70eb862071a8e4b87f7d30736aa3
2018-02-19 13:38:29 -08:00
9df64e28dd Merge changes Id5b4a1a4,Ia20ce844
* changes:
  Import: extract condition from loop
  Import,RGBA: fix for BigEndian import
2018-02-19 04:28:22 +00:00
8043504f95 lossless*sse2: improve non-const 16-bit vector creation
use _mm_set1_epi32 instead of _mm_set_epi16 with non-const values;
reduces shifts and ors.

Change-Id: Ie2cb2ab815f642855d03c6f3001223bcac4bd35c
2018-02-17 17:59:20 -08:00
1e3dfc48fb Import: extract condition from loop
do_copy is a loop invariant, but based on a variable parameter; it would
only be extracted if Import was inlined.

Change-Id: Id5b4a1a4a83a4f2083444da4934e4c994df65b44
2018-02-17 13:30:28 -08:00
3b07d32712 Import,RGBA: fix for BigEndian import
+ simplification of the logic

Change-Id: Ia20ce844793ed35ea03a17cef45838f3d0ae4afa
2018-02-17 13:07:58 -08:00
551948e45f Remove unused argument in VP8LBitsEntropy.
The function is only used once and does not use the extra argument.

Change-Id: I9735383784746cb02b5a643b7a4a2037f2874bf9
2018-02-16 16:05:28 +01:00
3005237a5d ReadWebP: fix for big-endian
Change-Id: I36b3c12ccf02eb5dad350c460387c0528fff8df3
2018-02-14 23:39:26 -08:00
499c395a35 Merge "anim_diff: expose the -max_diff option" 2018-02-09 19:39:03 +00:00
f69dcd692a Merge "remove WEBP_EXPERIMENTAL_FEATURES" 2018-02-09 18:53:59 +00:00
07d884d59b anim_diff: expose the -max_diff option
this removes the last remnant of WEBP_EXPERIMENTAL_FEATURES

Change-Id: I5952107b5aae60b865f0745e0bb4a7e1663af5aa
2018-02-09 10:32:09 -08:00
f4dd92565e remove WEBP_EXPERIMENTAL_FEATURES
the webp bitstream is considered stable at this point

Change-Id: I4b13f9ed4c45f63785474b097e96cb7bf651be7b
2018-02-09 10:25:11 -08:00
94a8377b3e extract the command-line parsing helpers to example_util
+ make img2webp tool use the text-file parsing option too.

Change-Id: I1976e651bbe8b4701abceba89e054b4fb3c35696
2018-02-08 08:11:31 +00:00
fc09e6e252 PNM decoder: prevent unsupported depth=2 PAM case.
Change-Id: I8476818908d71498dd80b07dc255aa008ffd16f5
2018-02-07 18:24:01 -08:00
6de58603b7 MIPS64: Fix defined-but-not-used errors with WEBP_REDUCE_CSP
BUG=webp:372

Change-Id: Ided3fae748face18138a8050eaced5e0f58120d4
2018-01-30 17:40:09 -08:00
cbde5728c8 gif2webp: add support for reading from stdin
output to stdout is already supported; this matches [cd]webp

BUG=webp:371

Change-Id: Ib1ce1661b16ea792943bca2980f779584e90cc86
2018-01-26 03:13:44 -08:00
cf1c5054c7 Add an SSE4 version of some lossless color transforms.
Change-Id: Ieac094f684116d1292793b2ca321f6f1a69565b5
2018-01-24 14:33:25 +01:00
45a8b5eb59 Fix lint error with man page.
LC_ALL=en_US.UTF-8 MANROFFSEQ='' MANWIDTH=80 \
     man --warnings -E UTF-8 -l -Tutf8 -Z img2webp.1 >/dev/null
would trigger it.

BUG=webp:370

Change-Id: I9543112bc58ac424af86bb65f7d894707a5646c7
2018-01-23 21:18:30 +01:00
cff38e8f4d Merge "PNG decoder: handle gAMA chunk" 2018-01-06 00:07:58 +00:00
59cb1a48c1 Merge "enable dc error-diffusion always" 2018-01-05 22:51:58 +00:00
78318b30e5 PNG decoder: handle gAMA chunk
Apply gamma correction to the decoded RGB values.

This handles corner cases where the PNG file doesn't have
a standard 1/2.2 gamma value.

BUG=webp:369

Change-Id: I9907b6e2c458002de7c26d0b9e416278cca33990
2018-01-05 10:56:52 -08:00
664c21dd01 Merge "remove some TODOs" 2017-12-28 14:39:35 +00:00
815652de03 enable dc error-diffusion always
for q<=98, we always enable error diffusion.

+ reduce storage 2x by using int8_t
+ make the error diffusion more robust

BUG=webp:340,308

Change-Id: I0608df839ff7b64d6843005a0f81d2577143af9e
2017-12-27 20:11:57 +00:00
aec45cec33 remove some TODOs
* regarding alpha_data_ used for testing.
   alpha_data_!=NULL is as close a good test as we'll get.
* regarding filter-strength / sharpness forcing
   no practical use (can be done during encode cycles,
   for experimentation)
* regarding a 'less-complex' filtering:
   no practical use so far. Next version!

Change-Id: If2dfff5818552a7d3e7c23ac08d64fe6d270229c
2017-12-27 17:40:18 +01:00
5715dfce2e fix block-count[] increment in case of large image
For large images overflowing the partition0, we re-do a number
of passes but were forgetting to reset the block_count[].
This was leading to incorrect summary.

+ some cosmetic fixes here and there

BUG=webp:355

Change-Id: Ie87158d7f177f8efdca429b146cfcd0e81652d2f
2017-12-27 17:12:58 +01:00
c2d04f3eb2 enable DC error-diffusion always for multi-pass
We can't predict if the quality is going to be below the threshold
eventually, so we might as well enable it always.

Change-Id: I30aedecc8c6d4daf159f6ef152697df0206d1e93
2017-12-12 15:00:45 +01:00
96bf07c560 use DC error diffusion for U/V at low-quality
This fixes some color smearing due to heavy quantization.
This is only enabled for q <= 30 (cf ERROR_DIFFUSION_QUALITY)

Change-Id: I07e83a4d38461357a32c9e214f7eadc6db73baa9
2017-12-11 06:37:40 -08:00
1c59020b93 fix missing sse41 targets in makefile.unix
Change-Id: I8c7a39746594caea160c40e25ea22d756ca44e11
2017-12-11 00:00:19 -08:00
7a8e814b57 cosmetics: s/color_space/colorspace/
in webpinfo.c, quality_estimate.c.
this form is used elsewhere in the codebase

Change-Id: I40c8202db51a7356e6a14d7e9b25c68153548438
2017-12-08 12:40:18 -08:00
05f6fe24c3 upsampling: rm asserts w/REDUCE_CSP+OMIT_C_CODE
with WEBP_NEON_OMIT_C_CODE the default _C functions won't be set and
with WEBP_REDUCE_CSP the NEON functions won't be either triggering an
assert for an empty table member.

BUG=chromium:792627

Change-Id: I8d2d430eaa37bb92885b61a3dd39f961924a8def
2017-12-06 17:09:26 -08:00
b4cf5597f4 Merge "Upsampling SSE2/SSE4 speedup." 2017-12-06 10:10:12 +00:00
ccbeb32c04 Makefile.vc: add missing sse41 files
upsampling_sse41.c and yuv_sse41.c added in:
807b53c4 Implement the upsampling/yuv functions in SSE41

Change-Id: I186cb6f6c296ba26b8e9b42d88da7f58c55710a9
2017-12-05 23:27:16 -08:00
55403a9a5a Upsampling SSE2/SSE4 speedup.
RGB to YUV conversion was not using SSE to finish up the row.
End data is now copied to a buffer big enough to fit in a
SSE register.
(UPSAMPLE_LAST_BLOCK was already using that trick).

Change-Id: Ie539bcbe570a643a774aa88263503c0d2c41890f
2017-12-05 23:37:06 +01:00
807b53c47e Implement the upsampling/yuv functions in SSE41
Change-Id: If122da22b74a974262063d232f6ca0ab902ff64e
2017-12-04 22:29:43 +01:00
84101a8165 Fix wasm WebP compilation
Change-Id: I6638628fbf3b7ae310bc892c9ca49678d1098b9b
2017-12-04 13:39:50 +01:00
8bebd2a32e fix warning on MSVC
'function' : different 'const' qualifiers

Change-Id: I855e94e8734a7e9a6156c771a7bad41b19a450d7
2017-12-01 22:46:48 -08:00
a7f93fe32d webpmux: allow reading argument from a file
if a single text file name is supplied as argument
(e.g.: 'webpmux my_long_list_of_frames.txt'), the command
line arguments are actually parsed from this file.
Tokenizer will remove space, tabs, LF, CR, returns, etc.

+ changed ImgIoUtilReadFile() to return a null-terminated
data, for convenience.

+ misc clean-up in the code

BUG=webp:355

Change-Id: I76796305641d660933de5881763d723006712fa9
---
2017-12-01 01:42:22 -08:00
b69f18a73a gif2webp.1: fix -loop_compatibility layout
Change-Id: Ia29b7a9e3b72605d2bb8c13ad3e37b88094444f5
2017-11-29 22:59:30 -08:00
72d530c01d Merge "fix lossless decoding w/WEBP_REDUCE_SIZE" 2017-11-30 06:42:20 +00:00
296c7dc4ac fix lossless decoding w/WEBP_REDUCE_SIZE
alpha processing is still required when requesting premultiplied output

since:
1b27bf8b WEBP_REDUCE_SIZE: disable all rescaler code

Change-Id: Id1b03256c4c04b8db31527e60cd31dd20ce6f3ad
2017-11-29 17:01:40 -08:00
0d5d029c18 Merge "ImgIoUtilReadFile: fix file leak upon error" 2017-11-30 00:24:51 +00:00
ae568ce7c4 ImgIoUtilReadFile: fix file leak upon error
the file was not closed in case of malloc error.

Change-Id: I5f8b22d7d0da6d2c8c2dd245cdd57994e3ddea3a
2017-11-29 21:30:22 +01:00
796b5a8a8a Merge tag 'v0.6.1'
libwebp-0.6.1

- 11/24/2017: version 0.6.1
  This is a binary compatible release.
  * lossless performance and compression improvements + a new 'cruncher' mode
    (-m 6 -q 100)
  * ARM performance improvements with clang (15-20% w/ndk r15c, issue #339)
  * webp-js: emscripten/webassembly based javascript decoder
  * miscellaneous bug & build fixes (issue #329, #332, #343, #353, #360, #361,
    #363)
  Tool updates / additions:
    added webpinfo - prints file format information (issue #330)
    gif2webp - loop behavior modified to match Chrome M63+ (crbug.com/649264);
               '-loop_compatibility' can be used for the old behavior

* tag 'v0.6.1':
  update ChangeLog
  WEBP_REDUCE_CSP: restrict colorspace support
  update ChangeLog
  vwebp: disable double buffering on windows & mac
  webp_to_sdl.c: fix file mode
  WEBP_REDUCE_SIZE: disable all rescaler code
  webpinfo: add -version option
  bump version to 0.6.1
  update NEWS
  README: add webpinfo section

Change-Id: Iab2153fae38da3c99daccdf57fec816e07b7909a
2017-11-28 15:03:15 -08:00
6b7a95fd83 update ChangeLog
Change-Id: I868b7680164ddc712233acc8607a8dfb6b3a4cbe
2017-11-28 12:01:56 -08:00
f66955de5f WEBP_REDUCE_CSP: restrict colorspace support
only supported ones are: RGBA/BGRA/rgbA/bgrA (decoder)
as well as: WebPPictureImportRGB/RGBX/RGBA (encoder).

(note: extras/get_disto is affected too)

Change-Id: If6c4f95054ca15759c4e289fb3b4c352b3521c2c
(cherry picked from commit 6de20df02c)
2017-11-28 00:15:15 -08:00
1af0df7662 Merge "WEBP_REDUCE_CSP: restrict colorspace support" 2017-11-27 20:08:55 +00:00
6de20df02c WEBP_REDUCE_CSP: restrict colorspace support
only supported ones are: RGBA/BGRA/rgbA/bgrA (decoder)
as well as: WebPPictureImportRGB/RGBX/RGBA (encoder).

(note: extras/get_disto is affected too)

Change-Id: If6c4f95054ca15759c4e289fb3b4c352b3521c2c
2017-11-26 08:44:08 +00:00
a289d8e774 update ChangeLog
Change-Id: Ia1e4669e6270faa6daae6306f47baa31488f119d
2017-11-25 19:01:58 -08:00
c10a493caf vwebp: disable double buffering on windows & mac
this results in flickering with animated webp + alpha. disabling the
option is a workaround to restore the behavior to the previous release.

BUG=webp:365

Change-Id: Iac7fcc0d483837e76cc54ad3f26c4e0e5511e31d
2017-11-25 18:22:39 -08:00
0d4466c2b4 webp_to_sdl.c: fix file mode
Change-Id: I1ca8506d40a60cd6db7f6f0d63a4431848bb0ea9
2017-11-25 13:52:03 -08:00
1b27bf8b76 WEBP_REDUCE_SIZE: disable all rescaler code
BUG=webp:355

Change-Id: Id87cb11902e3fb8544a214308526ea9665ce8440
(cherry picked from commit 0df22b9eed)
2017-11-24 22:40:15 -08:00
126be10950 webpinfo: add -version option
Change-Id: I5861d5ccd2119dd6749dc70b65fd145b5a732f98
2017-11-24 14:21:05 -08:00
0df22b9eed WEBP_REDUCE_SIZE: disable all rescaler code
BUG=webp:355

Change-Id: Id87cb11902e3fb8544a214308526ea9665ce8440
2017-11-24 22:08:32 +00:00
9add62b581 bump version to 0.6.1
libwebp{,decoder} - 0.6.1
libwebp libtool - 7.1.0
libwebpdecoder libtool - 3.1.0

mux - 0.4.1
libtool - 3.1.0

demux - 0.3.3
libtool - 2.3.0

Change-Id: If4a95c6e9829d4a608028ee9258b5c2b7af60c37
2017-11-24 21:03:05 +00:00
d3e2614493 update NEWS
Change-Id: I66c8abe05b54558030a8555d80010506730ecbe9
2017-11-24 12:21:44 +00:00
2edda639b2 README: add webpinfo section
Change-Id: Iee4a4ecbe562d6154f627ba62524cd1871a06564
2017-11-23 23:58:22 -08:00
9ca568ef82 Merge "right-size some tables" 2017-11-24 06:28:02 +00:00
31f1995cc5 Merge "SSE2 implementation of HasAlphaXXX" 2017-11-24 06:25:58 +00:00
a80c46bd87 SSE2 implementation of HasAlphaXXX
Change-Id: I2548d9a0c252e20ee3cf5f4be736a3703671ecb4
HasAlpha32b: ~3-4x faster
HasAlpha8b: ~7-8x faster
2017-11-23 15:02:21 +01:00
083507f244 right-size some tables
Change-Id: I5e894fd3f0f4b666512108495d8cecb34f65e119
2017-11-23 08:40:58 +00:00
2e5785b233 anim_utils.c: remove warning when !defined(WEBP_HAVE_GIF)
BUG=webp:355
Change-Id: I57d77672260771bb0c2ab3c802388f2d62b1f187
2017-11-23 00:22:33 -08:00
b299c47eac add WEBP_REDUCE_SIZE
remove auto-filter (-af) support and make WebPPictureCopy,
WebPPictureIsView, WebPPictureView, WebPPictureCrop, and
WebPPictureRescale noops.

Change-Id: If39d512cc268a0015298a1138dbc94feb86575e5
2017-11-22 17:35:39 -08:00
f593d71a64 enc: disable pic->stats/extra_info w/WEBP_DISABLE_STATS
Change-Id: I4ca3fa45710bd6bbe131b2ae047b1e268241657c
2017-11-22 17:04:01 -08:00
541179a9a5 Merge "predictor_enc: fix build w/--disable-near-lossless" 2017-11-23 01:02:59 +00:00
5755a7ec53 predictor_enc: fix build w/--disable-near-lossless
Change-Id: I0d01cdc77e72663f1cf778e3cf3066cd54aa5439
2017-11-22 15:02:21 -08:00
eab5bab74f add WEBP_DISABLE_STATS
use to to make WebPPictureDistortion & WebPPlaneDistortion noops and
clear some ssim code.

Change-Id: I9b50b2318b7a114632e5a237a4002f64e95afbbc
2017-11-22 12:41:17 -08:00
8052c585b3 remove some petty TODOs from vwebp.
they're rather low-prio anyway.

Change-Id: I76dd74fcfb1c974c6f8a074472455d3f0b202e01
2017-11-22 19:22:52 +00:00
c245343dcb move LOAD8x4 and STORE8x2 closer to their use location
Change-Id: I674821732d3e607123070e4bbba87d9359c9a4ec
2017-11-21 23:44:39 -08:00
b9e734fd5c dec,cosmetics: normalize function naming style
Change-Id: I33a2d1b4133db7a6d56d506f5c19670f0268cecd
2017-11-21 14:31:34 -08:00
c188d546b3 dec: harmonize function suffixes
BUG=webp:355

Change-Id: Iabdfd3fbde906c2e35a7d7c080a8512425eb8ccb
2017-11-21 13:00:25 -08:00
28c5ac8104 dec_sse41: harmonize function suffixes
BUG=webp:355

Change-Id: Id55f7b2e6288d1d0885d8451fbc59771222073d6
2017-11-21 12:47:06 -08:00
e65b72a368 Merge "introduce WebPHasAlpha8b and WebPHasAlpha32b" 2017-11-21 06:21:44 +00:00
b94cee98fb dec_sse2: remove HE8uv_SSE2
with gcc-4.8, clang-4.0.1/5 this is no faster (actually up to 2x slower)
than the code generated for memset (0x01010... * dst[-1]). shuffles in
sse4 recover a bit, but performance is still down.

Change-Id: Ie85e8353f8ede559d0b05a1d388787fd18ecc80f
2017-11-20 20:34:05 -08:00
44a0ee3fa7 introduce WebPHasAlpha8b and WebPHasAlpha32b
Rewrote WebPPictureHasTransparency() to use them (even for argb).
This is 10% faster, for some reasons.

SSE2 version should be straightforward.
Removes a TODO.

Change-Id: I7ad5848fc5e355e2df505dbcd5a0f42fb6cbab41
2017-11-20 15:20:29 +01:00
aebf59ac50 Merge "WebPPictureAllocARGB: align argb allocation" 2017-11-17 07:27:41 +00:00
c184665ecd WebPPictureAllocARGB: align argb allocation
Change-Id: Ib390e8bbb97b38316a38af6a33e8a26bd050ee16
2017-11-16 20:19:09 -08:00
3daf7509c2 WebPParseHeaders: remove obsolete animation TODO
The WebPDemux and WebPAnimDecoder APIs are provided for the purpose of
animated webp parsing and decoding. No major changes are currently
planned for the libwebp API.

Change-Id: I2758ecda195b0c4091572d5731a0a85fa3716303
2017-11-16 20:18:21 -08:00
80285d97ad cmake: avoid security warnings under msvc
fopen, sscanf are error checked and only used in the examples. this
matches Makefile.vc.

Change-Id: I411c3ace6b5db092656d6b03dc5b438bd70616fc
2017-11-15 18:41:41 -08:00
650eac5542 cmake: don't set -Wall with MSVC
take the generator default (/W3); /Wall produces too many warnings that
can't be acted on.

Change-Id: I112d0f46456af2758ddfee6becc098447ca50b6f
2017-11-15 18:29:15 -08:00
c462cd0065 Remove useless code.
The casts are to the same type and the #define not used.

Change-Id: I8d69c3b9dde7a1c53c2ba5a026a653d8c2e1d2a7
2017-11-08 10:52:49 +01:00
01a98217ad Merge "remove WebPWorkerImpl declaration from the header" 2017-11-06 20:37:08 +00:00
3c49fc47e7 Merge "thread_utils: fix potentially bad call to Execute" 2017-11-06 20:36:13 +00:00
fde2782ecb thread_utils: fix potentially bad call to Execute
We must use the Interface, and avoid fwd decl.

Change-Id: I18d77a009a29921b6e3694de4df494952b11a83f
2017-11-05 16:39:29 -08:00
2a270c1df5 remove WebPWorkerImpl declaration from the header
BUG=webp:355

Change-Id: Ia4efce4e8f3745e5cdcac495f4a79a8c03062d88
2017-11-05 12:31:48 -08:00
f1f437cc89 remove mention of 'lossy-only parameters' from the doc
it's confusing and mildly accurate.

BUG=webp:355

Change-Id: Ie9667bcdf429f1092b8a523a473391b741164523
2017-11-05 19:38:24 +00:00
3879074d99 Merge "WebPMemToUint32: remove ptr cast to int" 2017-10-31 06:41:05 +00:00
04b029d236 WebPMemToUint32: remove ptr cast to int
this can result in an alignment hint on arm causing a SIGBUS. casting
the input ptr to anything aside from its type is unnecessary for memcpy
and is contrary to the intent of this function.

Change-Id: I9a4d3f4be90f80cd8c3e96ccbe557e51e34cf7a5
2017-10-30 17:08:46 -07:00
b7971d0e22 dsp: avoid defining _C functions w/NEON builds
when targeting NEON C functions with NEON equivalents won't be used, but
will contribute to binary size. the same goes for sse2, etc., but this
change is primarily concerned with binary sizes for android arm targets.

note '-noasm' or otherwise modifying VP8GetCPUInfo will have no effect
on the use of NEON functions.

this decision can be overridden by defining WEBP_DSP_OMIT_C_CODE to 0.

Change-Id: I47bd453c84a3d341ca39bc986a39eb9c785aface
2017-10-27 10:54:56 -07:00
6ba98764e8 webpdec: correct alloc size check w/use_argb
the allocation is always 4 x width regardless of the presence of alpha

Change-Id: I154bd7e5c0190d37abd669e17e18911ebb7e066c
2017-10-26 23:17:11 -07:00
5cfb3b0f6c normalize include guards
some fell out of sync after:
668e1dd4 src/{dec,enc,utils}: give filenames a unique suffix

Change-Id: I280d3b3f44797f3bfb4835784add50a41cdd3793
2017-10-21 00:06:23 -07:00
f433205ee3 Merge changes Ia17c7dfc,I75423abb,Ia2f716b4,I161caa14,I4210081a, ...
* changes:
  {dec,enc}_neon: harmonize function suffixes x2
  upsampling_neon: harmonize function suffixes
  yuv_neon: harmonize function suffixes
  rescaler_neon: harmonize function suffixes
  lossless_neon: harmonize function suffixes
  lossless_enc_neon: harmonize function suffixes
  filters_neon,cosmetics: fix indent
  enc_neon: harmonize function suffixes
  dec_neon: harmonize function suffixes
2017-10-21 06:34:14 +00:00
8d033b14d7 {dec,enc}_neon: harmonize function suffixes x2
+ neon.h

BUG=webp:355

Change-Id: Ia17c7dfc7d61742a4758823675a2d556a739c389
2017-10-20 19:00:53 -07:00
0295e9815d upsampling_neon: harmonize function suffixes
BUG=webp:355

Change-Id: I75423abbe0bcea3c98a42e412cc2116be81b5d08
2017-10-20 19:00:53 -07:00
d572c4e52b yuv_neon: harmonize function suffixes
BUG=webp:355

Change-Id: Ia2f716b459950c18717b062175197d1e6419bf2a
2017-10-20 19:00:53 -07:00
ab9c2500db rescaler_neon: harmonize function suffixes
BUG=webp:355

Change-Id: I161caa14f7ebbc3ae978b1722472625a77d0a4a4
2017-10-20 19:00:53 -07:00
93e0ce27f4 lossless_neon: harmonize function suffixes
BUG=webp:355

Change-Id: I4210081a39800b5c2589c443da237269908af666
2017-10-20 19:00:53 -07:00
22fbc50edd lossless_enc_neon: harmonize function suffixes
BUG=webp:355

Change-Id: I462facaeade4f0f4fc1e96895493306d095a6a9a
2017-10-20 19:00:53 -07:00
447875b47b filters_neon,cosmetics: fix indent
BUG=webp:355

Change-Id: I9df1119f1ea94868f75253a92c2e878c9290f744
2017-10-20 19:00:29 -07:00
e51bdd439c remove unused VP8TokenToStats() function
BUG=webp:355

Change-Id: I0ad6f13003ef7201431c54c7db395254191de67c
2017-10-20 04:29:45 -07:00
785da7eadd enc_neon: harmonize function suffixes
BUG=webp:355

Change-Id: Ie59efd271d16f12d21f3c800667dfc0980dc2e68
2017-10-20 00:18:32 -07:00
bc1a251fcf dec_neon: harmonize function suffixes
BUG=webp:355

Change-Id: I61c9a0c9e24515322955e04afd8c4ea6a44b9319
2017-10-20 00:14:18 -07:00
61e535f1ac dsp/lossless: workaround gcc-4.8 bug on arm
and all older versions.
force Sub3() to not be inlined, otherwise the code in Select() will be
incorrect.

extends the check add previously in:
637b3888 dsp/lossless: workaround gcc-4.9 bug on arm

BUG=webp:363

Change-Id: I1403b558f8660b764f3a570a3326822d5ef0be29
2017-10-19 13:05:48 -07:00
68b2eab7df cwebp: fix alpha reporting w/lossless & metadata
the incorrect bit was being extracted from the lossless bitstream header
causing the alpha flag in VP8X to be misreported. previously the
signature byte was ignored in the calculation of the offset.

since:
8ba1bf61 Stricter check for presence of alpha when writing lossless
images

BUG=webp:361

Change-Id: I7c618b5f01a37f5e4b799dee11a7949efaf88046
2017-10-18 12:35:56 -07:00
30042faa9a WebPDemuxGetI: add doc details around WebPFormatFeature
Change-Id: Id5f17686a8dbd6a6a0ba354d9216a8b89a51597c
2017-10-17 19:59:16 +00:00
0a17f4712c Merge "WIP: list includes as descendants of the project dir" 2017-10-11 08:21:42 +00:00
a439972175 WIP: list includes as descendants of the project dir
#include "(.|..)/..." -> #include "src/..."

Change-Id: I772880aa097a770722043c8a4393552ba38a89b6
2017-10-10 23:04:05 -07:00
0827570873 Merge "Make sure we reach the full range for alpha blending." 2017-10-09 09:21:21 +00:00
d361a6a733 yuv_sse2: harmonize function suffixes
BUG=webp:355

Change-Id: I02a66f7446c75a10c3ce4766235e5767617d0dce
2017-10-08 14:06:34 -07:00
6921aa6f0c upsampling_sse2: harmonize function suffixes
BUG=webp:355

Change-Id: I3a02cc717eb7506bd87511d6a17ab1691e84f72c
2017-10-08 14:06:30 -07:00
08c67d3ed1 ssim_sse2: harmonize function suffixes
BUG=webp:355

Change-Id: I1282559888118b8cb0a46b7f0aa627d26b8838f5
2017-10-08 14:06:24 -07:00
582a1b572a rescaler_sse2: harmonize function suffixes
BUG=webp:355

Change-Id: I978fd826ff90149c0ffd9d7607dcc6f88082d3e6
2017-10-08 14:06:19 -07:00
2c1b18ba2f lossless_sse2: harmonize function suffixes
BUG=webp:355

Change-Id: I59d828800c2ab2a36e0ea90f629b74bd57207411
2017-10-08 14:06:14 -07:00
0ac46e818b lossless_enc_sse2: harmonize function suffixes
BUG=webp:355

Change-Id: I06c64416103c3f3fc0519dd46d64b0a35f9798e4
2017-10-08 14:06:05 -07:00
bc634d57c2 enc_sse2: harmonize function suffixes
BUG=webp:355

Change-Id: Idd2f289fcf99f12bf36494111b07a8906c99c826
2017-10-08 14:05:59 -07:00
bcb7347c2b dec_sse2: harmonize function suffixes
BUG=webp:355

Change-Id: Ic0390a4a24a5d8caff5b8af9fc9d59769ec533b1
2017-10-07 15:14:03 -07:00
e14ad93c0a Make sure we reach the full range for alpha blending.
255*255*257>>16 == 254 while we want 255.

BUG=webp:360

Change-Id: I2b9ac18f8802145f5a3d500c149ad9eceacbd75b
2017-10-05 16:53:57 +02:00
7038ca8d52 demux,StoreFrame: restore hdr size check to min req
avoids over reading if the reported ANMF payload is < 8 bytes.

likely broken since:
81b8a741 Design change in ANMF and FRGM chunks:

Change-Id: I3e267bafea348a50545587dea8fafb2199c6b650
2017-10-03 23:18:18 -07:00
fb3daad604 cpu: fix ssse3 check
ssse3 is bit #9 in ecx, bit 1 is sse3. this only controls the check for
slow ssse3 and likely had no ill effect.

Change-Id: I84ce73dc480e1cdbd085e37be06f3f402116c201
2017-09-29 16:27:47 -07:00
be590e0644 Merge "Fix CMake redefinition for HAVE_CPU_FEATURES_H" 2017-09-26 05:59:05 +00:00
35f736e1ec Fix CMake redefinition for HAVE_CPU_FEATURES_H
It is still redefined, but to the same constant,
hence no more warning as mentioned on BUG=webp:358

Change-Id: I80a834c139d5d60cd693d468b0e2ea399729ab3e
2017-09-25 14:43:20 +02:00
a5216efc8c Fix integer overflow warning.
Though the overflow could happen, it does not change the
end results.

Change-Id: I1b84e022a0776d35eab5c5c4fb7d3563f5667bfa
2017-09-25 11:02:22 +02:00
a9c8916b87 decode.h,WebPIDecGetRGB: clarify output ptr validity
*last_y, *width, *height, *stride are only valid on non-NULL return

Change-Id: Iee2eeb29dd36392e2e7876d47df182a81dbb41ce
2017-09-22 16:58:33 -07:00
3c74c645ca gif2webp: handle 1-frame case properly + fix anim_diff
follow-up to commit b4e046778

Change-Id: I3c7617d09682262ca7929e6a3e56777b163cce45
2017-09-20 22:21:15 +00:00
c7f295d30c Merge "gif2webp: introduce -loop_compatibility option" 2017-09-20 09:13:37 +00:00
b4e046778d gif2webp: introduce -loop_compatibility option
This patch fixes the compatibility for loop-count handling.
This aims at addressing the change in Chrome handling of loop-count
prior to M63.

Before M63: loop-count interpretation was aligned to GIF's behaviour in
Chrome, but incompatible with WebP's spec. In particular, you couldn't
loop exactly once.

Post-M63: loop-count in WebP is really the total number of loops. Gif2webp
will convert correctly from a GIF source by adjusting the loop count.

Note: The Chrome version can be retrieved from the User-Agent
string (chrome://version).
An M63 version will contain the pattern:
   Chrome/63.x.xxxx.xx
for instance.

Change-Id: Ie6dc13227e6498f4d7af2f09247913648997648a
2017-09-20 07:37:49 +00:00
f78da3dea6 add LOCAL_CLANG_PREREQ and avoid WORK_AROUND_GCC w/3.8+
this results in a 15-20% speedup for lossy decoding on a N5/S6/CM1

BUG=webp:339

Change-Id: Icdeb84c3e0b8908147ac276b4d8f76c3d565b735
2017-09-19 20:59:49 -07:00
01c426f1e7 define WEBP_USE_INTRINSICS w/gcc-4.9+
32-bit builds are neutral to slightly faster using ndk r15c on a
N5/S6/CM1

BUG=webp:339

Change-Id: I94b9442e0ceaf2f5edb2b4026bc8b99cd77c918b
2017-09-19 20:59:43 -07:00
8635973dc3 use sdl-config (if available) to determine the link flags
this fixes the compilation of vwebp_sdl on MacOS.

BUG=webp:355

Change-Id: I48c5607f31965b220db6bf707cff22b7157e0bb6
2017-09-06 20:35:48 +00:00
e9459382b0 use CPPFLAGS before CFLAGS
this way, -Isrc/ is used *before* system-wide -I locations
like /opt/local/include/ for instance.

Change-Id: I83c97775aff87695720a0ff3fca5c3cf2bb62a09
2017-09-03 21:13:33 -07:00
4a9d788e40 Merge "Android.mk,mips: fix clang build with r15" 2017-09-01 06:32:06 +00:00
4fbdc9fb12 Android.mk,mips: fix clang build with r15
-integrated-as is now required, the opposite of r14

Change-Id: Ic478b2b3b933e66e7d159030eac29f58743eecda
2017-08-31 22:42:14 -07:00
a80fcc4ae1 ifdef code not used by Chrome/Android.
Change-Id: Id086f6fd602b1fe3dc9034764b6a920a696ff1d2
2017-08-31 14:02:05 +02:00
3993af127e Fix signed integer overflows.
Change-Id: I62c9949f0edac58d69d991d6be5f85ae9e4d62a9
2017-08-31 11:56:42 +02:00
f66f94ef36 anim_dump: small tool to dump frames from animated WebP
dumps frames to PNG, PAM or TIFF files.


Change-Id: I86a4d7e235cb7040cf5bbcae28270cb5a84be087
2017-08-30 06:12:03 +00:00
6eba857b75 Merge "rationalize the Makefile.am" 2017-08-29 21:05:20 +00:00
c5e34fba66 function definition cleanup
Change-Id: I1f6bb4405f09c0c863d0bd1c77340636abdbae69
2017-08-29 14:09:35 +02:00
3822762a6c rationalize the Makefile.am
one library addition per line, etc...

BUG=webp:355

Change-Id: I95761dea598a382db5632c5187210937e129ff75
2017-08-29 00:00:14 -07:00
501ef6e4e9 configure style fix: animdiff -> anim_diff
BUG=webp:355

Change-Id: I4a90a11e075bf30aaa34a0b4c08c9038b0eb8f60
2017-08-29 05:41:33 +00:00
f8bdc26821 Merge "protect against NULL dump_folder[] value in ReadAnimatedImage()" 2017-08-29 05:41:16 +00:00
23bfc652fe protect against NULL dump_folder[] value in ReadAnimatedImage()
BUG=webp:355

Change-Id: If449ed4b0bd7a11ce7c646eabe2a7b58a1abf009
2017-08-28 20:57:22 +00:00
8dc3d71ba0 cosmetics,ReadAnimatedWebP: correct function comment
BUG=webp:355

Change-Id: If671b67067ee6ebaa63e9710ddbb7d59b33dbc3b
2017-08-28 11:43:26 -07:00
5bd40066cc Merge changes I66a64a0a,I4d2e520f
* changes:
  cosmetics,webpinfo: remove an else after a return
  cosmetics,cwebp: remove an else after a return
2017-08-27 06:03:09 +00:00
7945575c92 cosmetics,webpinfo: remove an else after a return
this is redundant with an if block that returns

BUG=webp:355

Change-Id: I66a64a0a4932c5f419f6171684b72088c43e7136
2017-08-26 14:22:39 -07:00
8729fa1102 cosmetics,cwebp: remove an else after a return
this is redundant with an if block that returns

BUG=webp:355

Change-Id: I4d2e520f89a8e144ab13aa3696f305365e584a0e
2017-08-26 14:22:32 -07:00
f324b7f9ba cosmetics: normalize fn proto & decl param names
BUG=webp:355

Change-Id: If020eb3b064cdb11853d1fa47058acae34752ce3
2017-08-26 14:17:31 -07:00
869eb36983 CMake cleanups.
Change-Id: I177c856eb06e8fb2847a0d483114198a2a0a5dae
2017-08-25 14:01:56 +02:00
289e62a313 Remove declaration of unimplemented VP8ApplyNearLosslessPredict
Change-Id: I1bebea099a06bccfdd103ba0557320d6ad68af38
2017-08-23 17:16:29 +02:00
20a94186ce pnmdec,PAM: validate depth before calculating bytes_per_px
fixes potential integer overflow with corrupt files.

Change-Id: I03e27fb14ad559dcd47e2704afdb6be9a163e02e
2017-08-19 13:56:06 -07:00
34130afe8b anim_encode: fix integer overflow
calculate the file duration using unsigned math. this could still result
in an incorrect average duration calculation if there were multiple
rollovers. caching the duration is an option if it was desirable to
support such an extreme case.

Change-Id: I3875d94d081fec947c03a857055df6e27ff5351d
2017-08-18 16:52:57 -07:00
42c79aa66b Merge "Encoder: harmonize function suffixes" 2017-08-09 18:13:57 +00:00
b09307dcde Encoder: harmonize function suffixes
BUG=webp:355

Change-Id: Ia2fe95db7dfb303f3f64e390d43bc41b8933256c
2017-08-09 02:41:01 +00:00
bed0456d58 Merge "SSIM: harmonize the function suffix" 2017-08-09 02:37:39 +00:00
54f6a3cf3a lossless_sse2.c: fix some missed suffix changes
BUG=webp:355

Change-Id: If830e3169a4021899ed850aa7edfd94b81fa2cf9
2017-08-08 14:19:05 -07:00
088f1dcce8 SSIM: harmonize the function suffix
BUG=webp:355

Change-Id: I751852ddb2abb7319e41e6c7d022ac4f288b4d08
2017-08-08 08:52:06 -07:00
86fc4dd9f4 webpdec: use ImgIoUtilCheckSizeArgumentsOverflow
...prior to allocating a Picture. this is consistent with the other
readers and allows the allocation size to be limited at compile time

BUG=webp:355

Change-Id: Ib8e027ef863489b1e0f9e2a1403c3836da3ef48d
2017-08-08 07:02:02 -07:00
08ea9ecde3 imageio: add ability restrict max image size
WEBP_MAX_IMAGE_SIZE can be defined to control this limit.
Set it to 1.5GiB w/--config=asan-fuzzer to avoid OOM with large resolution
images. This limit leaves some headroom over the single image max of 2^14 *
2^14 * 4

BUG=webp:355

Change-Id: I4d48eb0a063638297a842582e0229dfd5a54df5f
2017-08-08 07:02:02 -07:00
6f9daa4a3a jpegdec,ReadError: fix leaks on error
everything post jpeg decoder creation should go through the error path
to ensure it's cleaned up properly

Change-Id: If78b4529e40797c67c3d0e624af1c036badea674
2017-08-08 07:02:00 -07:00
a0f72a4fe0 VP8LTransformColorFunc: drop an non-respected 'const' from the signature.
BUG=webp:355

Change-Id: Ie99bf377a55db2950bfbac9423bfe0967623ea5d
2017-08-07 19:05:01 -07:00
8c934902cd Merge "Lossess dec: harmonize the function suffixes" 2017-08-08 02:04:10 +00:00
622242aaba Lossess dec: harmonize the function suffixes
BUG=webp:355

Change-Id: I445d64df6aa2e347f41e7af306be12a77e2ac6a5
2017-08-07 18:22:41 -07:00
1411f02761 Lossless Enc: harmonize the function suffixes
BUG=webp:355

Change-Id: I8baf506bd2a27095b956ef22a862b071f60c0d72
2017-08-07 18:02:07 -07:00
24ad2e3c99 add const to two variables
Change-Id: I97374ccbf118baa59425346ffc439036a4482bf4
2017-08-07 23:02:15 +02:00
46efe062b8 Merge "Allow the lossless cruncher to work for alpha." 2017-08-07 21:00:02 +00:00
8c3f9a4706 Speed-up LZ77.
No need to look for a bigger maximum reach if we reach the end
of the image.

Change-Id: I56b166f9266f15cdff5aa59a75559972db19858f
2017-08-07 21:01:27 +02:00
1aef4c710b Allow the lossless cruncher to work for alpha.
Change-Id: I7185e75404fae8c739e0536026f4687d25decad7
2017-08-07 20:58:05 +02:00
b8821dbd81 Improve the box LZ77 speed.
For a pixel, we look for the longest match starting in a window around it.
For the following pixel, the previous result can be used and smaller
search window is used.

Change-Id: Ice16f9a7c8754099d068380848f0d77de3f756ac
2017-08-06 20:15:20 +02:00
7beed2807b add missing ()s to macro parameters
BUG=webp:355

Change-Id: I616c6d3540d6551edd1b1cfdb5bffcf0a044c90f
2017-08-04 17:02:53 -07:00
6473d20b3e Merge "fix Android standalone toolchain build" 2017-08-04 18:25:21 +00:00
dcefed950b Merge "build.gradle: fix arm64 build" 2017-08-03 02:21:26 +00:00
0c83a8bc69 Merge "yuv: harmonize suffix naming" 2017-08-02 06:35:36 +00:00
c6d1db4b36 fix Android standalone toolchain build
add a check for cpu-features.h and rework some of the ifdef's around
android + neon. for android builds with cpu-features enabled the
*_neon.c files will still need to be flagged correctly (with e.g.,
.c.neon in Android.mk) to properly build them.

BUG=webp:353

Change-Id: I905ce305af0a204e560b915d8665093a3edaceb9
2017-08-01 22:59:03 -07:00
663a6d9d2e unify the ALTERNATE_CODE flag usage
Pattern is now:
 #if !defined(FLAG)
 #define FLAG 0   // ALTERNATE_CODE
 #endif
...
 #if (FLAG == 1)
 ...
 #else
  ...
 #endif    // FLAG
...

Removed some unused code / flags:
  WEBP_YUV_USE_TABLE, WEBP_REFERENCE_IMPLEMENTATION,
  experimental code,  VP8YUVInit(), ...

BUG=webp:355

Change-Id: I98deb9189446a4cfd665c13ea8aa1ce6a308c63f
2017-08-01 20:49:29 -07:00
73ea9f2702 yuv: harmonize suffix naming
BUG=webp:355

Change-Id: I403c4b3cdfc55b3b1648f98a1d189326a3e660a3
2017-08-01 20:40:00 -07:00
c71b68ac45 build.gradle: fix arm64 build
only armv7-a uses .c.neon, arm64 has NEON by default; this matches the
Android.mk

Change-Id: Iee2bcf6a532cf54e31866d9db6923c3f0a1d88ba
2017-08-01 18:31:13 -07:00
c4568b47fd Rescaler: harmonize the suffix naming
BUG=webp:355

Change-Id: I7720502c62f96c780793d3d881eac7b3afae1418
2017-08-01 23:49:44 +00:00
6cb13b0532 Merge "alpha_processing: harmonize the naming suffixes to be _C()" 2017-08-01 03:38:03 +00:00
83a3e69a20 Merge "simplify WEBP_EXTERN macro" 2017-08-01 03:29:12 +00:00
7295fde2e6 Merge "filters: harmonize the suffixes naming to _SSE2(), _C(), etc." 2017-08-01 01:55:48 +00:00
8e42ba4c80 simplify WEBP_EXTERN macro
including the type in the macro doesn't bring much benefit to ordering,
current platforms work with a prefix, this would be insufficient if the
attribute needed to follow the function prototype. this form makes it
easier to override on the command line.

BUG=webp:355

Change-Id: Iba41ec0bb319403054be0e899c4cc472dd932fd9
2017-07-31 18:27:52 -07:00
331ab34bcd cost*.c: harmonize the suffix namings
BUG=webp:355

Change-Id: Ic2e60eaab71cdffe1ebf93fc36aaa3eb25bbf08d
2017-07-31 17:18:32 -07:00
b161f670f8 filters: harmonize the suffixes naming to _SSE2(), _C(), etc.
BUG=webp:355

Change-Id: I28f464eb13444c3046332cdda3c547f81700ecf4
2017-08-01 00:09:05 +00:00
dec5e4d330 alpha_processing: harmonize the naming suffixes to be _C()
BUG=webp:355

Change-Id: Iae8221cd34957764ead21aa46abfc320e5514a4b
2017-07-31 23:34:24 +00:00
6878d42720 fix memory leak in SDL_Init()
we use a static guard to only call SDL_Init() once.

Another option would be to call SDL_Quit(), but it doesn't seem to be
doing anything.

Also, fix the HTML code and add 'use strict' directive.

BUG=webp:354

Change-Id: I3c6421e2c1c8cc200556cd4092a0ead9a8b054ef
2017-07-31 12:47:02 -07:00
461ae5551b Merge "configure: fix warnings in sdl check" 2017-07-18 07:48:34 +00:00
62486a2206 configure: test for -Wundef
Change-Id: Ia4bcde5276ae9572c5b3152e578d59a4e3552988
2017-07-11 16:12:36 -07:00
92982609bc dsp.h: fix -Wundef w/__mips_dsp_rev
Change-Id: I552a543c7b039774041b43ace75b0cbea566b119
2017-07-11 16:12:32 -07:00
0265cede89 configure: fix warnings in sdl check
correct shell syntax, drop trailing ','

Change-Id: I0535bdf92f03e17902a844d8e7d742b351ce4822
2017-07-11 15:38:18 -07:00
88c73d8a7a backward_references_enc.h: fix WINDOW_SIZE_BITS check
this check was relocated in:
b903b80c Split cost-based backward references in its own file.

quiets -Wundef

Change-Id: I7f7a4773fb8cc77ca9f671b11f50d5db2275d415
2017-07-11 15:36:14 -07:00
4ea49f6b82 rescaler_sse2.c: fix WEBP_RESCALER_FIX -> _RFIX typo
quiets -Wundef

Change-Id: I8f1facf401b6f1ab393005c93086ac3e2ae354d5
2017-07-11 15:35:27 -07:00
1b526638b8 Clean-up some CMake
- some image libraries define _INCLUDE_DIR and not INCLUDE_DIRS.
- CMakePushCheckState is a non-destructive way of changing the
CMAKE_REQUIRED_* variables.

Change-Id: I7d318a0ddf9754a5c047f47ba1713f9f94e1ec1c
2017-07-10 16:29:33 +02:00
87f57a4b62 Merge "cmake: fix gif lib detection when cross compiling" 2017-07-07 07:55:48 +00:00
b34a9db1a1 cosmetics,dec_sse2: remove some redundant comments
Change-Id: I5a59d6dde9b6638b318f36d51d0d53870a3de273
2017-07-06 23:19:18 -07:00
471c5755fc cmake: fix gif lib detection when cross compiling
GIF find_package only locates the header and library, it doesn't fail
compile tests when detecting the version, but falls back to 3 (as of at
least cmake 3.7.2). Make sure the library links to avoid incorrect
detection when cross compiling.

Change-Id: I0224180bbdf800ab261a9333236730b23c006e69
2017-07-06 15:33:31 -07:00
c793417a3c cmake: disable gif2webp if gif lib isn't found
Change-Id: I218d5c0e3f4a82905c743705382cf02d26b29e6d
2017-07-06 15:33:01 -07:00
dcbc1c881a cmake: split gif detection from IMG deps
gifdec isn't part of imageio lib, it's only used by gif2webp.

Change-Id: I70bff378a32f8fb2ebb8a5a7701049ffff7f7992
2017-07-06 15:32:55 -07:00
66ad84f0f9 Merge "muxread: remove unreachable code" 2017-07-05 23:48:45 +00:00
50ec3ab790 muxread: remove unreachable code
IDX_UNKNOWN chunks are handled separately in WebPMuxGetChunk()

Change-Id: Iaa0d3a1cd1080264c27671637551f52f71d73b07
2017-07-05 15:47:50 -07:00
7d67a1646d Lossy encoding: smoothen transparent areas to improve compression
If "exact" is false, we can modify the luma samples in fully transparent
areas to facilitate lossy compression. Experiments on some PNG images
show compression improvement of more than 20%.

Change-Id: I1a728cfa920a6652bc1f600d87c01f7f648c4942
2017-07-05 10:03:01 -07:00
e50650c77f Merge "fix signature for DISABLE_TOKEN_BUFFER compilation" 2017-07-02 07:33:52 +00:00
671d2567d4 fix signature for DISABLE_TOKEN_BUFFER compilation
Change-Id: Idb7aa2503c7870ef3b15a23325832428d47ae7c6
2017-07-01 14:46:28 -07:00
d67555809f cpu.cmake: use unique flag to test simd disable flags
this avoids the result being cached in a common variable causing
potentially incorrect results in future tests and improves the logging
output

BUG=webp:351

Change-Id: I4b3110beec38f505fc8f835c3ea689a7d81a36bb
2017-06-28 19:13:34 -07:00
28914528e1 Merge "Remove the argb* files." 2017-06-25 15:57:17 +00:00
8acb4942f7 Remove the argb* files.
Half of the functionality was duplicated.
The rest is about the alpha channel handling so we
might as well put it in the appropriate file.

Change-Id: I8d5ef0afce82cc4842ab7132fd97995c42e6140a
2017-06-25 14:44:33 +02:00
3b62347b0f README: correct cmake invocation note
the default invocation given generates makefiles, not a configure script

Change-Id: Ia65b120289b497c2f2981fec330456682d11162a
2017-06-21 16:36:09 -07:00
7ca0df1363 Have the SSE2 version of PackARGB use common code.
The common code actually got sped-up by 25% by using the code
from PackARGB.

Change-Id: I94be6ccff2bfe02fff13c8e2698669e6a0d8fc74
2017-06-20 17:41:14 +02:00
7b250459d6 Merge "Re-use the transformed image when trying several LZ77 in lossless." 2017-06-20 11:53:01 +00:00
e132072f0b Re-use the transformed image when trying several LZ77 in lossless.
Change-Id: If879b960131ba26859f8e4719a4c74cec1e0aaa8
2017-06-19 17:30:01 +02:00
5d7a50efee Get code to compile in C++.
Change-Id: I2f56e6b71e33ffecdba9e4fa9ef8f891c88f850f
2017-06-19 17:12:29 +02:00
7b012987a2 configure: test for -Wparentheses-equality
Change-Id: Id91d581781f77e6cc92cc33dfd3c8ea37e130164
2017-06-15 16:07:07 -07:00
f0569adb93 Fix man pages for multi-threading.
BUG=webp:336

Change-Id: I70d3dfb8a532c1f2b80bd08cc62e833962cb4b34
2017-06-15 08:49:04 +00:00
f1d5a397db multithread cruncher: only copy stats when picture->stats != NULL
BUG=webp:336

Change-Id: I6dfbbdcf61a6cb455f6cbf3dcd7f4c46578f42aa
2017-06-14 21:49:13 +02:00
f8c2ac15af Multi-thread the lossless cruncher.
BUG=webp:336

Change-Id: I8e861d6a61d51a5cdc4bbd00cd4f17d4ff006d2f
2017-06-14 16:50:36 +02:00
a88c6522f6 Merge "Integrate a new LZ77 looking for matches in the neighborhood of a pixel only." 2017-06-13 13:15:48 +00:00
8f6df1d0b9 Unroll Predictors 10, 11 and 12.
We see the following speed-ups:
10 -> 13%
11 -> 13%
12 -> 13%

Change-Id: I4734fd388d0f4e508884d0b123976bf2cbe69d2f
2017-06-08 20:37:47 +02:00
355c3d1bc7 Integrate a new LZ77 looking for matches in the neighborhood of a pixel only.
Change-Id: Ie2bbfee0a8d154b58f4a3068f3f634b7dad4c12d
2017-06-08 15:19:40 +02:00
a1779a017b Refactor LZ77 handling in preparation for a new method.
Change-Id: If305c328c8f508bd778d1af108e4eb979fbd2eca
2017-06-07 16:43:04 +02:00
67de68b5d9 Android.mk/build.gradle: fix mips build with clang from r14b
fixes unknown instruction errors for e.g.,
usw    $15, 0($8)

BUG=webp:343

Change-Id: I71d00527fecd2370a40f6bd12f4e361fb525477f
2017-06-03 13:06:54 -07:00
f209a5481e Use the plane code and not the distance when computing statistics.
As backward references use the plane code when checking the cost
of a distance, statistics used to compute the cost should use it too.
This provides a small compression improvement at no speed cost.

Change-Id: Icade150929ee39ef6dc0d8b1fc85973086ecf41d
2017-06-01 17:08:43 +02:00
b903b80c30 Split cost-based backward references in its own file.
Change-Id: I4d8281e69b0e41f7c90337e5be70a6c65b044086
2017-06-01 16:22:31 +02:00
498cad34be Cosmetic changes in backward reference.
Change-Id: Ieb3dd65a647c034f67cf029e7b03f843b4650b0f
2017-06-01 14:20:16 +02:00
e4eb458741 lossless, VP8LTransformColor_C: make sure no overflow happens with colors.
Change-Id: Iec0d07cf1188ba96391cdb1b62131fc1469dfac6
2017-05-24 11:34:40 +02:00
af6deaffa0 webpinfo: handle alpha flag mismatch
Throw a warning for false positive vp8x alpha flag;
throw an error for false negative vp8x alpha flag.

BUG=webp:330

Change-Id: I3933588c9d6d76ecaf515517f7506dea299af638
2017-05-23 10:28:25 -07:00
7caef29b86 Fix typo that creeped in.
Change-Id: I600725721d9df80d6deddc65e00663649a47c941
2017-05-23 17:10:34 +02:00
39e19f927c Merge "near lossless: fix unsigned int overflow warnings." 2017-05-23 14:47:47 +00:00
9bbc0891c6 near lossless: fix unsigned int overflow warnings.
Change-Id: Ic1111a66761b5821cbbea1c91b038b2327dd20b5
2017-05-23 13:43:08 +02:00
e1118d624d Merge "cosmetics,FindClosestDiscretized: use uint in mask creation" 2017-05-23 05:47:20 +00:00
186bc9b735 Merge "webpinfo: tolerate ALPH+VP8L" 2017-05-22 17:17:09 +00:00
b588729740 cosmetics,FindClosestDiscretized: use uint in mask creation
Change-Id: Ib1edd74be1c051c10cfe2defadbea48cabe15135
2017-05-22 08:21:44 -07:00
f1784aee04 near_lossless,FindClosestDiscretized: use unsigned ops
quiets undefined sanitizer warnings of the form:
left shift of 128 by 24 places cannot be represented in type 'int'

Change-Id: I8a389f2ac9238513517180f302f759425eeb7262
2017-05-22 03:11:03 -07:00
0d20abb36f webpinfo: tolerate ALPH+VP8L
Change-Id: I63cec2d021c0bfaa188017813813bddaadfbeacb
2017-05-19 14:58:44 -07:00
972104b34b webpmux: tolerate false positive Alpha flag
Change-Id: I390aebdda31f5320e83b7d7012735947a234650b
2017-05-19 11:26:37 -07:00
dd7e83cca7 tiffdec,ReadTIFF: ensure data_size is < tsize_t max
Change-Id: I0ad9589a7f994294100e1c5a38abf6ebe417f8a9
2017-05-17 13:02:06 -07:00
d988eb7b39 tiffdec,MyRead: quiet -Wshorten-64-to-32 warning
Change-Id: I7e2c7a9b80278b3056151c74a939b0f55bbbc90c
2017-05-17 12:06:53 -07:00
dabda70733 webpinfo: add support to parse Alpha bitstream
BUG=webp:330

Change-Id: I9ed0923d19558052d63bdbe93a542c51595fdce7
2017-05-17 09:35:58 -07:00
4c1176432a webpinfo: correct background color output, BGRA->ARGB
bgcolor is stored little-endian, byte order is BGRA, with A being the
high byte

Change-Id: I8327380c039634120ee2313044781a5651513dcb
2017-05-16 11:51:44 -07:00
defc98d72c Doc: clarify the role of quality in WebPConfig.
Change-Id: I13706847f6263b9bb91eaf3c9284dd2d42ea7a85
2017-05-15 18:01:35 +02:00
d78ff78095 Merge "Fix code to compile with C++." 2017-05-15 15:11:11 +00:00
c8f14093ac Fix code to compile with C++.
Change-Id: I324236440cb853cb3c8fb278ef22449cd9772ad7
2017-05-15 16:22:03 +02:00
497dc6a70d pnmdec: sanitize invalid header output
Change-Id: I034cb00047f725e1cd106d3677db567f1efa0847
2017-05-15 04:57:45 -07:00
d78e5867ff Merge "configure: test for -Wconstant-conversion" 2017-05-13 06:10:21 +00:00
481e91eb86 Merge "pnmdec,PAM: set bytes_per_px based on depth when missing" 2017-05-13 00:47:36 +00:00
93b1275373 configure: test for -Wconstant-conversion
Change-Id: Idf442e35dd8b414c30b8f53ade6f32dfa6f74d39
2017-05-12 17:02:06 +02:00
645f0c53de pnmdec,PAM: set bytes_per_px based on depth when missing
this avoids setting bytes_per_px < depth causing an undersized
allocation for rgb import resulting in a crash.

BUG=b/37930872

Change-Id: I32a86f91528acc084a53d08c9fde9f2f1270a603
2017-05-10 19:15:50 -04:00
e91546054d Merge "vwebp: activate GLUT double-buffering" 2017-05-10 05:46:20 +00:00
818d795b09 vwebp: activate GLUT double-buffering
This prevents the flickering of animated webp + alpha.

Change-Id: I335a434ccc6c90e32528c9832555a38cc0f71cc4
2017-05-10 05:16:47 +00:00
d63e6f4b23 Add a man page for webpinfo
BUG=webp:330

Change-Id: I7b02274401c935affa173a49a883a39272b6dcc3
2017-05-09 16:14:44 -07:00
4d7084350e Merge "NEON: implement ConvertRGB24ToY/BGR24/ARGB/RGBA32ToUV/ARGBToUV" 2017-05-09 15:33:34 +00:00
faf42213f4 NEON: implement ConvertRGB24ToY/BGR24/ARGB/RGBA32ToUV/ARGBToUV
Change-Id: Ie68aaed36d17f56d998c1b284514860cf5d28b8a
2017-05-09 15:57:20 +02:00
b4d576fa9c Install man pages with CMake.
Change-Id: I58a91ea00d45e1ce95250bd73613cf53e3af8401
2017-05-09 11:41:48 +02:00
cbc1b92117 webpinfo: add features to parse bitstream header
BUG=webp:330

Change-Id: If2a6ff010219fa25a2b5843725c616ee4dce65a7
2017-05-04 09:18:11 -07:00
e644c556c5 Fix bad bit writer initialization.
When re-initializing a bit writer, we could set invalid values because
the bit writer was not big enough.

Change-Id: Id25ab6712603245a5a12d5f4a86fe35a9a799a5d
2017-05-02 18:59:01 +02:00
b62cdad287 Merge "Implement a cruncher for lossless at method 6." 2017-04-28 14:37:57 +00:00
da3e4dfb6f use the exact constant for the gamma transfer function
As found in BT2020 reference:
https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2020-2-201510-I!!PDF-E.pdf

The difference in output-size/PSNR are under the noise level.

Change-Id: I42c12000b61dca791226f3af772c5bd9d58201b8
2017-04-27 11:53:15 -07:00
a9c701e04f Merge "tiffdec: fix EXTRASAMPLES check" 2017-04-27 17:39:34 +00:00
adab8ce020 Implement a cruncher for lossless at method 6.
Go over the whole compression step for each of the
transforms and pick the best one.

Change-Id: I3a1b1458348c468558be0fcf491038a5724c9364
2017-04-27 18:16:04 +02:00
1b92b237ac Merge "Fix VP8ApplyNearLossless to respect const and stride." 2017-04-27 15:56:47 +00:00
1923ff0222 tiffdec: fix EXTRASAMPLES check
the TIFFGetField() return for TIFFTAG_EXTRASAMPLES is defined as (count,
types array) [1]. previously the count was being checked rather than the
first element of the array to determine whether the alpha was associated
(pre-multiplied) and the result needed to be unmultiplied.

since:
9273e441 fix TIFF encoder regarding rgbA/RGBA

[1] http://www.libtiff.org/man/TIFFSetField.3t.html

Change-Id: I6e41be9d038fe8afb6d0aa3c8048925dc901113b
2017-04-26 22:49:11 -07:00
97cce5ba83 tiffdec: only request EXTRASAMPLES w/> 3 samples/px
Change-Id: I820e7de34e500c42ab51c97a70f25319807d58eb
2017-04-25 19:10:08 -07:00
0dcd85b6c4 Fix VP8ApplyNearLossless to respect const and stride.
Change-Id: I94a90220b5a175228fc48a4b299847b60cf5081b
2017-04-25 19:04:52 +02:00
f768218966 yuv: rationalize the C/SSE2 function naming
+ implement some easy missing targets in SSE2 (565/4444)

Change-Id: Ib575f7ada2a0ed7309cddd238f8bfc0e8999f145
2017-04-21 13:52:25 +02:00
52245424b0 NEON implementation of some Sharp-YUV420 functions
Change-Id: I449ef9c76b06f971f6e2ad7f9db96bf906d8fe1f
new-file: dsp/yuv_neon.c
2017-04-18 19:22:37 +02:00
690efd82f8 Avoid several backward reference copies.
An extra VP8LBackwardRefs struct is used but it was used internally anyway.

Change-Id: Ifcb36ce42b8c21ef3c7a1daf38cb7f714687fcb2
2017-04-14 15:34:50 +02:00
4bb1f607d7 src/dec/vp8_dec.h, cosmetics: fix comments
Change-Id: If076cdf63965bad9b00cbe19c922320638b65f46
2017-04-07 15:29:57 -07:00
285748be78 cmake: build/install webpinfo
Change-Id: Ia3dd24aec0c985855865f32280de1799d4bb8e9e
2017-03-23 20:37:52 -07:00
78fd199c3b backward_references_enc.c: clear -Wshadow warnings
index -> position

similar to: 2f5e8934 remove -Wshadow warnings

Change-Id: Ieaf8363d726a8fdf4e799845a81364e1dfae438a
2017-03-22 23:52:19 -07:00
ae836410bb WebPLog2FloorC: clear -Wshadow warning
log -> log_value

Change-Id: Iae7cea7e0875e59b0806de41eb0b58815307495e
2017-03-22 23:50:31 -07:00
d0b7404e00 Merge "WASM support" 2017-03-21 13:27:55 +00:00
134e314fd8 WASM support
demo page: webp_js/index_wasm.html

Change-Id: I9e6bde205c2730f96c5f30ec01f4bfacf1f5d128
2017-03-21 14:07:22 +01:00
c08adb6fbc Merge "VP8LEnc: remove use of BitsLog2Ceiling()" 2017-03-20 13:12:19 +00:00
28c37ebd5a VP8LEnc: remove use of BitsLog2Ceiling()
was only used once. Better fall back for Log2Floor.

Change-Id: Ibcc26505440971bffe62ba6aca3d179ca85791d4
2017-03-20 02:58:16 -07:00
2cb58ab2d7 webpinfo: output format as a human readable string
Change-Id: I3a3d95bae049ee1053c9d92a364cf1b75f277f81
2017-03-17 00:23:11 -07:00
bb175a935e Merge "rename some symbols clashing with MSVC headers" 2017-03-16 17:53:37 +00:00
39eda6584f Remove a duplicated pixel hash implementation.
Change-Id: If0df61add2fdf404f9baf0820ca83faa50f2791c
2017-03-16 16:15:40 +01:00
36b8274deb rename some symbols clashing with MSVC headers
This is to prepare the inclusion of <windows.h>

FrameRect => FrameRectangle
CLIP_MASK => CLIP_8b_MASK

Change-Id: Ia4b1fa4ac06137b4102c91e232206a1fb7159ce0
2017-03-16 10:42:00 +01:00
274daf5415 Add webpinfo tool.
A command line tool to print out the chunk level structure of
WebP files along with basic integrity checks.

BUG=webp:330

Change-Id: Ic69f646f649abb655b1854621d99afedeed158d7
2017-03-14 11:41:17 +01:00
ec5036e475 add explicit reference to /usr/local/{lib,inc}
Change-Id: Idf0450bc715c476950f23b2f9db383a5b9936890
2017-03-08 09:14:15 +01:00
18f0dfac82 Merge "fix TIFF encoder regarding rgbA/RGBA" 2017-03-08 08:07:43 +00:00
4e2b0b50ea Merge "webpdec.h: fix a doc typo" 2017-03-06 22:48:02 +00:00
e2eeabff12 Merge "Install binaries, libraries and headers in CMake." 2017-03-06 08:22:08 +00:00
836607e68a webpdec.h: fix a doc typo
Change-Id: Ie1c4c2f0008904bfc37c838d2bd168e982155308
2017-03-05 09:38:51 +00:00
9273e441da fix TIFF encoder regarding rgbA/RGBA
Encoder:
We were always using ExtraSamples=1, which means associated-alpha.
But we don't need the (lossy) excursion to rgbA format. We can save
the samples as RGBA directly, by changing ExtraSamples to '2'.
The TIFF encoder now checks the colorspace properly, to handle
premultiplied format as well as non-premultiplied.

Decoder:
The result of TIFFReadRGBAImageOriented() is always pre-multiply.
So, in case an alpha channel is present, we need to unmultiply it before
calling WebPPictureImportRGBA().

See:
https://www.itu.int/itudoc/itu-t/com16/tiff-fx/docs/tiff6.pdf (page 31)
and also http://www.asmail.be/msg0055469184.html

Change-Id: I3258bfdb0eb2e1a53d6c04414f55edb2926c938c
2017-03-03 10:36:29 -08:00
17e3c11f99 Add limited PAM decoding support
Should support RGB / RGB_ALPHA / GRAYSCALE correctly, though

Change-Id: Idb1470581ebdfc6efee73009b2abd53889e901cb
2017-03-03 11:19:48 +01:00
5f62487189 Install binaries, libraries and headers in CMake.
Change-Id: Iaf32c716e0252f9a0e9f5d663f02b8fad98096e2
2017-03-03 09:35:02 +01:00
976adac1ce Merge "lossless incremental decoding: fix missing eos_ test" 2017-03-01 02:54:13 +00:00
f8fad4fac1 lossless incremental decoding: fix missing eos_ test
The patch  21735e0 introduced a bug where a goto path was not testing
the eos_ state.  If this happened just before a row_sync, a SaveState()
would be called that would store the eos_ state as '1' till the end
of the loop.  This usually was not a problem, except for the very last
chunk where we disable the incremental decoding altogether (we have all
the data). The termination tests were then going wrong.
The fix is to add a proper eos_ test and avoid falling in this inconsistent
state.

(21735e06f7)

BUG=webp:332

Change-Id: Ib16773aee26bfd068fbf4e9db3d2313bd978b269
2017-02-28 15:17:33 -08:00
27415d4102 Merge "vwebp_sdl: fix the makefile.unix" 2017-02-28 23:05:21 +00:00
4956618276 Merge "ImgIoUtilWriteFile(): use ImgIoUtilSetBinaryMode" 2017-02-28 23:05:12 +00:00
6f75a51b58 Analyze the transform entropy on the whole image.
The first column was skipped before.

Change-Id: I11521a6a48288d771e8fb83869fda08753f0fbcb
2017-02-28 15:48:59 +01:00
a5e4e3aff1 Use palette only if we can in entropy analysis.
Change-Id: I2be74b4d5fe48e059d5ced619d76fd030db79f74
2017-02-28 11:43:13 +01:00
75a9c3c452 Improve compression by better entropy analysis.
Change-Id: I6b56ca8d7d9a046a581baa0e85504136685d1161
2017-02-27 21:58:22 +01:00
39cf6f4f36 vwebp_sdl: fix the makefile.unix
The FLAGS_LIBS was dropped at some point.
There is still an SDL_Main / main problem though, but it's a
separate topic.

Change-Id: Ief4d79624e94e7904134df8d84a4ac7c77c48ce7
2017-02-27 08:46:44 -08:00
699b04161a ImgIoUtilWriteFile(): use ImgIoUtilSetBinaryMode
this matches what's done in cwebp.c:977

Change-Id: I0a05d03c97a073b8aa1e01430f20d6cc3c5ffc91
2017-02-26 14:05:42 -08:00
7d985bd1d0 Fix small entropy analysis bug.
Change-Id: I70554b5a898b38930dfd03ca1ed78a075261e84b
2017-02-24 13:38:41 +01:00
6e7caf06ee Optimize the color cache size.
Before, the color cache size was chosen optimally for LZ77 and
the same value was used for RLE. Now, we optimize its value
taking both LZ77 and RLE into account.

Unfortunately, that comes with a small CPU hit.

Change-Id: I6261f04af78cf0784bb8e8fc4b4af5f566a0e071
2017-02-23 18:20:00 +01:00
833c92198c More efficient stochastic histogram merge.
Between each iteration we keep track of the previously found
potential merge hence less work to do.

Change-Id: I2b6237447e79443516a6111727d96c24f10bd98a
2017-02-23 14:35:33 +01:00
5183326ba8 Refactor the greedy histogram merge.
This is preparatory work for an upcoming commit.
No impact on speed or compression.

Change-Id: I62488ae6d2dbb5398f1604068c212ab8e26e82bc
2017-02-22 15:47:47 +01:00
99f6f462f5 Merge "histogram_enc.c,MyRand: s/ul/u/ for unsigned constants" 2017-02-22 06:29:40 +00:00
80a2218668 ssim.c: remove dead include
Change-Id: Ia4be534b3b95d5d9f712ff53e530c98b942df860
2017-02-21 20:17:19 -08:00
a128dfff51 histogram_enc.c,MyRand: s/ul/u/ for unsigned constants
this is more consistent with the rest of the code base

Change-Id: Ifcf5d2729b2ebf32ffa12017db0106166829c77e
2017-02-21 20:12:17 -08:00
693bf74ec0 move the SSIM calculation code in ssim.c / ssim_sse2.c
Change-Id: I63a63fa7f44f257f2e17e45358b206c23069c448
2017-02-21 12:53:35 +01:00
10d791ca70 Merge "Fix the random generator in HistogramCombineStochastic." 2017-02-19 10:11:48 +00:00
fa63a96603 Fix the random generator in HistogramCombineStochastic.
It was a bad implementation of a Lehmer random number generator
(the saturation was done wrong and mostly & was used instead of % .....).

That lead to "for" loop stuck with the same values given a specific seed,
hence wasted "for" loops (e.g. seed getting at 374988608 and modulo of 64
later leads to 0 even when updating the seed with the old formula).

As the "for" loops now always return a proper pair of histograms, their
number can greatly be reduced, hence a speedup.

Change-Id: I9f5b44d66cc96fd4824189d92276c3756c8ead5b
2017-02-19 10:49:16 +01:00
16be192f47 VP8LSetBitPos: remove the eos_ setting
This code is ultra-critical for lossless decoding, especially on ARM.
The extra call VP8LIsEndOfStream() was causing unnecessary slow-down.

Now, we check for bitstream-end separately in the main loop.

Change-Id: I739b5d74cc29578e2b712ba99b544fd995ef0e0d
2017-02-11 02:35:02 -08:00
027151ca6c don't erase the surface before blitting.
It's done at HTML level with canvas.clearRect()

BUG=webp:261

Change-Id: I83c73791f5922cd1f426f19faf856fa1cf8f0311
2017-02-08 16:07:08 +00:00
4105d565d3 disable WEBP_USE_XXX optimisations when EMSCRIPTEN is defined
Currently, none are available. If WEBP_HAVE_SSE2 eventually works,
we'll have to refine this conditionals.

BUG=webp:261

Change-Id: Ibc63ee1c013f2a4169eeb85cc8b6317b6420c2ad
2017-02-08 15:44:20 +00:00
9ee32a7506 Merge "WebP-JS: emscripten-based Javascript decoder" 2017-02-07 20:20:20 +00:00
ca9f7b7dd6 WebP-JS: emscripten-based Javascript decoder
The build is based on CMake.

There is a demo HTML page under webp_js/index.html

See README.webp_js file.

BUG=webp:261

Change-Id: I6612378b89907efd7b863720c6becf98385fc406
2017-02-07 11:02:42 +00:00
868aa6901f Perform greedy histogram merge in a unified way.
Previously, the stochastic method for histogram
combination could finish in a greedy way
if the number of iterations to perform so was smaller.

Except that another greedy combination was performed
afterwards ... hence wasted CPU in some cases.

Change-Id: Ic0f26873e6dc746679486b91cb35d73efee91931
2017-02-07 11:57:20 +01:00
5b393f2d2a Merge "fix path typo for vwebp_sdl in Makefile.vc" 2017-02-04 20:41:48 +00:00
e0012bea23 CMake: only use libwebpdecoder for building dwebp
Change-Id: Ia972c063711529d1e9a7fa79cf250d0764840e6f
2017-02-04 00:04:23 -08:00
84c2a7b01c fix path typo for vwebp_sdl in Makefile.vc
Change-Id: Ia9656f1627ecbb58512927e234d18816941b3c9c
2017-02-04 00:01:23 -08:00
1b0e4abf08 Merge "Add a flag to disable SIMD optimizations." 2017-02-03 20:30:32 +00:00
3226325016 Add a flag to disable SIMD optimizations.
Change-Id: I83c33076e8afd1b20de1e9b191bdad6669998a0b
2017-02-03 16:56:37 +01:00
b494fdec45 optimize the ARGB->ARGB Import to use memcpy
(instead of the generic VP8PackARGB call)

Change-Id: I86edeb5934e7c062593f0248de7607cca5f1027c
2017-02-03 16:54:52 +01:00
f153603900 Merge "ReadWebP: decode directly into a pre-allocated buffer" 2017-02-03 14:04:41 +00:00
e69ed29105 ReadWebP: decode directly into a pre-allocated buffer
This simplifies things a bit.

Change-Id: Ib128c7630ef727284f3467c3216cc536143edd66
2017-02-03 14:41:46 +01:00
57d8de8a79 Merge "vwebp_sdl: simple viewer based on SDL" 2017-02-03 09:43:57 +00:00
5cfd4ebc5e LZ77 interval speedups. Faster, smaller, simpler.
The initial re-writing of this part of the code with intervals
had to be done with a complex logic (mostly intervals with a
lower and upper bound, not a constant value like now) to properly
deal with the inefficiencies of the then LZ77 algorithm.
The improvements made to LZ77 since, now allow for a simpler logic.

There were also small errors in the interval insertion logic
that lead to small inefficiencies (hence a slightly better
compression rate).

Change-Id: If079a0cafaae7be8e3f253485d9015a7177cf973
2017-02-02 11:51:30 +01:00
1e7ad88b85 PNM header decoder: add some basic numerical validation
see spec: http://netpbm.sourceforge.net/doc/ppm.html

Change-Id: I55e01f8cec79f9124e72d5f3d05be4ad0deae315
2017-02-01 15:03:11 +01:00
17c7890cba Merge "Add a decoder only library for WebP in CMake." 2017-02-01 12:49:32 +00:00
be73378684 Merge "Add clang build fix for MSA" 2017-02-01 12:43:09 +00:00
03cda0e494 Add a decoder only library for WebP in CMake.
Other libraries are also cleaned to automatically read the Makefile.am.
Dependencies also got cleaned.

Change-Id: I5d1ff0a4010d59e8c929ed0c9c30c05d83c271f8
2017-02-01 13:32:15 +01:00
aa893914fc Add clang build fix for MSA
Change-Id: If139f4ecbdce756c69ba4ae032a70f81179683f8
2017-02-01 17:45:17 +05:30
31a92e972e Merge "imageio: add limited PNM support for reading" 2017-02-01 10:49:57 +00:00
dcf9d82a95 imageio: add limited PNM support for reading
see: http://netpbm.sourceforge.net/

Only reads P5 and P6 pnm files for now.

Change-Id: I2332a623f803df67455047f570f1cff9f464480a
2017-02-01 07:41:56 +00:00
6524fcd614 vwebp_sdl: simple viewer based on SDL
Uses WebPToSDL() generic function defined in vwebp_sdl.[ch].
This function is not included in the libextras library, because it
would bring in an SDL dependency. Probably too heavy for now.

WebPToSDL() is separate, because it will be called used by the javascript
version of libwebp (through emscripten build rules)

Change-Id: Ic85b36f8ce4784f46023656278f6480be6802834
2017-01-31 10:23:03 +01:00
6cf24a247d get_disto: fix reference file read
previously this was reading the first file a second time, since:
b0450139 ReadImage(): restore size reporting

BUG=webp:329

Change-Id: Ie75192e36a06102b7617841768a18d4dfb02d1f5
2017-01-30 18:45:29 -08:00
43d472aa18 Merge tag 'v0.6.0'
libwebp-0.6.0

- 1/26/2017: version 0.6.0
  * lossless performance and compression improvements
  * miscellaneous performance improvements (SSE2, NEON, MSA)
  * webpmux gained a -duration option allowing for frame timing modification
  * new img2webp utility allowing a sequence of images to be converted to
    animated webp
  * API changes:
    - libwebp:
      WebPPictureSharpARGBToYUVA
      WebPPlaneDistortion
    - libwebpmux / gif2webp:
      WebPAnimEncoderOptions: kmax <= 0 now disables keyframes, kmax == 1
                              forces all keyframes. See mux.h and the gif2webp
                              manpage for details.

* tag 'v0.6.0':
  update ChangeLog
  extras/Makefile.am: fix libwebpextras.la reference
  update ChangeLog
  update NEWS
  update AUTHORS
  Fix "all|no frames are keyframes" settings.
  disable GradientUnfilter_NEON
  img2webp: treat -loop as a no-op w/single images
  ReadImage(): restore size reporting
  update ChangeLog
  img2webp,get_disto: fix image decode w/WIC builds
  get_disto: make ReadPicture() return a bool
  update NEWS
  man/img2webp.1: fix formatting warning
  update NEWS
  bump version to 0.6.0
  update AUTHORS

Change-Id: I682fd7821ad51174e4772d84a4445e58d0cebd22
2017-01-30 16:20:52 -08:00
1c3190b6ed Merge "Fix "all|no frames are keyframes" settings." 2017-01-27 00:02:04 +00:00
4f3e3bbd44 disable GradientUnfilter_NEON
Compile with XCode, it appears quite slower than the C-version,
especially for arm64.

Change-Id: Ic46dba184a36be454fef674129d2f909003788fc
2017-01-25 16:33:26 -08:00
2dc0bdcaee Fix "all|no frames are keyframes" settings.
Documentation says: "if kmin == 0, then key-frame insertion is disabled;
and if kmax == 0, then all frames will be key-frames."
Reading this, you'd expect that if kmax == 0, then with any kmin <= 0
all frames will be key-frames. But actually the kmin <= 0 test is caught
first and you get the opposite (no keyframes but the first). You'd have
instead to set kmax == 0 and any value kmin > 0, which is absolutely
counter-intuitive (reversing order).
Moreover kmax == 1 has no valid kmin (kmin == 1 conflicts with the
`kmax > kmin` rule and kmin == 0 conflicts with `kmin >= kmax / 2 + 1`).
So it should be considered an exception too.

Instead I propose this new logic:
- kmax == 1 means that all frames are keyframes (you are explicitly
  requesting a keyframe every 1 frame at most, i.e. all frames).
- kmax == 0 means no keyframes (you ask for a keyframe every 0 frames,
  i.e. never).
This is more "logical" language-wise, and also does not involve any
conflicts about what if both kmax and kmin are 0, since now a single
property value is meaningful for the 2 exceptional cases.

Change-Id: Ia90fb963bc26904ff078d2e4ef9f74b22b13a0fd
2017-01-25 13:12:52 -08:00
306 changed files with 31249 additions and 11906 deletions

1
.gitattributes vendored
View File

@ -1,5 +1,6 @@
.gitattributes export-ignore
.gitignore export-ignore
.mailmap export-ignore
*.bat text eol=crlf
*.pdf -text -diff
*.ppm -text -diff

17
.gitignore vendored
View File

@ -1,8 +1,11 @@
*.l[ao]
*.[ao]
*.pc
.DS_Store
.deps
.idea
.libs
.vscode
/aclocal.m4
/ar-lib
/autom4te.cache
@ -20,9 +23,11 @@
Makefile
Makefile.in
examples/anim_diff
examples/anim_dump
examples/[cdv]webp
examples/gif2webp
examples/img2webp
examples/webpinfo
examples/webpmux
src/webp/config.h*
src/webp/stamp-h1
@ -31,11 +36,21 @@ src/webp/stamp-h1
*.idb
*.pdb
/iosbuild
/WebP.framework
/xcframeworkbuild
/WebP*.*framework
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
.gradle
/build
extras/get_disto
extras/vwebp_sdl
extras/webp_quality
tests/fuzzer/advanced_api_fuzzer
tests/fuzzer/animation_api_fuzzer
tests/fuzzer/animdecoder_fuzzer
tests/fuzzer/animencoder_fuzzer
tests/fuzzer/demux_api_fuzzer
tests/fuzzer/enc_dec_fuzzer
tests/fuzzer/mux_demux_api_fuzzer
tests/fuzzer/simple_api_fuzzer

View File

@ -1,12 +1,18 @@
<johann.koenig@duck.com> <johannkoenig@google.com>
Johann Koenig <johann.koenig@duck.com>
Johann Koenig <johann.koenig@duck.com> <johannkoenig@google.com>
Mikołaj Zalewski <mikolajz@google.com>
Pascal Massimino <pascal.massimino@gmail.com>
<pascal.massimino@gmail.com> <skal@google.com>
Pascal Massimino <pascal.massimino@gmail.com> <skal@google.com>
Vikas Arora <vikasa@google.com>
<vikasa@google.com> <vikasa@gmail.com>
<vikasa@google.com> <vikaas.arora@gmail.com>
<slobodan.prijic@imgtec.com> <Slobodan.Prijic@imgtec.com>
<vrabaud@google.com> <vincent.rabaud@gmail.com>
Vincent Rabaud <vrabaud@google.com>
Tamar Levy <tamar.levy@intel.com>
<qrczak@google.com> <qrczak>
Hui Su <huisu@google.com>
James Zern <jzern@google.com>
Roberto Alanis <alanisbaez@google.com>
Brian Ledger <brianpl@google.com>
Maryla Ustarroz-Calonge <maryla@google.com>

441
.pylintrc Normal file
View File

@ -0,0 +1,441 @@
# This Pylint rcfile contains a best-effort configuration to uphold the
# best-practices and style described in the Google Python style guide:
# https://google.github.io/styleguide/pyguide.html
#
# Its canonical open-source location is:
# https://google.github.io/styleguide/pylintrc
[MASTER]
# Files or directories to be skipped. They should be base names, not paths.
ignore=third_party
# Files or directories matching the regex patterns are skipped. The regex
# matches against base names, not paths.
ignore-patterns=
# Pickle collected data for later comparisons.
persistent=no
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
# Use multiple processes to speed up Pylint.
jobs=4
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
confidence=
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once). See also the "--disable" option for examples.
#enable=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=abstract-method,
apply-builtin,
arguments-differ,
attribute-defined-outside-init,
backtick,
bad-option-value,
basestring-builtin,
buffer-builtin,
c-extension-no-member,
consider-using-enumerate,
cmp-builtin,
cmp-method,
coerce-builtin,
coerce-method,
delslice-method,
div-method,
duplicate-code,
eq-without-hash,
execfile-builtin,
file-builtin,
filter-builtin-not-iterating,
fixme,
getslice-method,
global-statement,
hex-method,
idiv-method,
implicit-str-concat-in-sequence,
import-error,
import-self,
import-star-module-level,
inconsistent-return-statements,
input-builtin,
intern-builtin,
invalid-str-codec,
locally-disabled,
long-builtin,
long-suffix,
map-builtin-not-iterating,
misplaced-comparison-constant,
missing-function-docstring,
metaclass-assignment,
next-method-called,
next-method-defined,
no-absolute-import,
no-else-break,
no-else-continue,
no-else-raise,
no-else-return,
no-init, # added
no-member,
no-name-in-module,
no-self-use,
nonzero-method,
oct-method,
old-division,
old-ne-operator,
old-octal-literal,
old-raise-syntax,
parameter-unpacking,
print-statement,
raising-string,
range-builtin-not-iterating,
raw_input-builtin,
rdiv-method,
reduce-builtin,
relative-import,
reload-builtin,
round-builtin,
setslice-method,
signature-differs,
standarderror-builtin,
suppressed-message,
sys-max-int,
too-few-public-methods,
too-many-ancestors,
too-many-arguments,
too-many-boolean-expressions,
too-many-branches,
too-many-instance-attributes,
too-many-locals,
too-many-nested-blocks,
too-many-public-methods,
too-many-return-statements,
too-many-statements,
trailing-newlines,
unichr-builtin,
unicode-builtin,
unnecessary-pass,
unpacking-in-except,
useless-else-on-loop,
useless-object-inheritance,
useless-suppression,
using-cmp-argument,
wrong-import-order,
xrange-builtin,
zip-builtin-not-iterating,
[REPORTS]
# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html. You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=text
# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]". This option is deprecated
# and it will be removed in Pylint 2.0.
files-output=no
# Tells whether to display a full report or only the messages
reports=no
# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=
[BASIC]
# Good variable names which should always be accepted, separated by a comma
good-names=main,_,PRESUBMIT
# Bad variable names which should always be refused, separated by a comma
bad-names=
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Include a hint for the correct naming format with invalid-name
include-naming-hint=no
# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
property-classes=abc.abstractproperty,cached_property.cached_property,cached_property.threaded_cached_property,cached_property.cached_property_with_ttl,cached_property.threaded_cached_property_with_ttl
# Regular expression matching correct function names
function-rgx=^(?:(?P<exempt>setUp|tearDown|setUpModule|tearDownModule)|(?P<camel_case>_?[A-Z][a-zA-Z0-9]*)|(?P<snake_case>_?[a-z][a-z0-9_]*))$
# Regular expression matching correct variable names
variable-rgx=^[a-z][a-z0-9_]*$
# Regular expression matching correct constant names
const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
# Regular expression matching correct attribute names
attr-rgx=^_{0,2}[a-z][a-z0-9_]*$
# Regular expression matching correct argument names
argument-rgx=^[a-z][a-z0-9_]*$
# Regular expression matching correct class attribute names
class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
# Regular expression matching correct inline iteration names
inlinevar-rgx=^[a-z][a-z0-9_]*$
# Regular expression matching correct class names
class-rgx=^_?[A-Z][a-zA-Z0-9]*$
# Regular expression matching correct module names
module-rgx=^(_?[a-z][a-z0-9_]*|__init__)$
# Regular expression matching correct method names
method-rgx=(?x)^(?:(?P<exempt>_[a-z0-9_]+__|runTest|setUp|tearDown|setUpTestCase|tearDownTestCase|setupSelf|tearDownClass|setUpClass|(test|assert)_*[A-Z0-9][a-zA-Z0-9_]*|next)|(?P<camel_case>_{0,2}[A-Z][a-zA-Z0-9_]*)|(?P<snake_case>_{0,2}[a-z][a-z0-9_]*))$
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=(__.*__|main|test.*|.*test|.*Test)$
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=10
[TYPECHECK]
# List of decorators that produce context managers, such as
# contextlib.contextmanager. Add to this list to register other decorators that
# produce valid context managers.
contextmanager-decorators=contextlib.contextmanager,contextlib2.contextmanager
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=
# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=optparse.Values,thread._local,_thread._local
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=
[FORMAT]
# Maximum number of characters on a single line.
max-line-length=80
# TODO(https://github.com/PyCQA/pylint/issues/3352): Direct pylint to exempt
# lines made too long by directives to pytype.
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=(?x)(
^\s*(\#\ )?<?https?://\S+>?$|
^\s*(from\s+\S+\s+)?import\s+.+$)
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=yes
# List of optional constructs for which whitespace checking is disabled. `dict-
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
# `empty-line` allows space-only lines.
no-space-check=
# Maximum number of lines in a module
max-module-lines=99999
# String used as indentation unit. The internal Google style guide mandates 2
# spaces. Google's externaly-published style guide says 4, consistent with
# PEP 8. Here, we use 2 spaces, for conformity with many open-sourced Google
# projects (like TensorFlow).
indent-string=' '
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=TODO
[STRING]
# This flag controls whether inconsistent-quotes generates a warning when the
# character used as a quote delimiter is used inconsistently within a module.
check-quote-consistency=yes
[VARIABLES]
# Tells whether we should check for unused import in __init__ files.
init-import=no
# A regular expression matching the name of dummy variables (i.e. expectedly
# not used).
dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_)
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=
# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,_cb
# List of qualified module names which can have objects that can redefine
# builtins.
redefining-builtins-modules=six,six.moves,past.builtins,future.builtins,functools
[LOGGING]
# Logging modules to check that the string format arguments are in logging
# function parameter format
logging-modules=logging,absl.logging,tensorflow.io.logging
[SIMILARITIES]
# Minimum lines number of a similarity.
min-similarity-lines=4
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
# Ignore imports when computing similarities.
ignore-imports=no
[SPELLING]
# Spelling dictionary name. Available dictionaries: none. To make it working
# install python-enchant package.
spelling-dict=
# List of comma separated words that should not be checked.
spelling-ignore-words=
# A path to a file that contains private dictionary; one word per line.
spelling-private-dict-file=
# Tells whether to store unknown words to indicated private dictionary in
# --spelling-private-dict-file option instead of raising a message.
spelling-store-unknown-words=no
[IMPORTS]
# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,
TERMIOS,
Bastion,
rexec,
sets
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=
# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=
# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=
# Force import order to recognize a module as part of a third party library.
known-third-party=enchant, absl
# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no
[CLASSES]
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,
__new__,
setUp
# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,
_fields,
_replace,
_source,
_make
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls,
class_
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=StandardError,
Exception,
BaseException

2
.style.yapf Normal file
View File

@ -0,0 +1,2 @@
[style]
based_on_style = chromium

20
AUTHORS
View File

@ -1,28 +1,42 @@
Contributors:
- Aidan O'Loan (aidanol at gmail dot com)
- Alan Browning (browning at google dot com)
- Alexandru Ardelean (ardeleanalex at gmail dot com)
- Brian Ledger (brianpl at google dot com)
- Charles Munger (clm at google dot com)
- Cheng Yi (cyi at google dot com)
- Christian Duvivier (cduvivier at google dot com)
- Christopher Degawa (ccom at randomderp dot com)
- Clement Courbet (courbet at google dot com)
- Djordje Pesut (djordje dot pesut at imgtec dot com)
- Frank Barchard (fbarchard at google dot com)
- Hui Su (huisu at google dot com)
- Ilya Kurdyukov (jpegqs at gmail dot com)
- Ingvar Stepanyan (rreverser at google dot com)
- James Zern (jzern at google dot com)
- Jan Engelhardt (jengelh at medozas dot de)
- Jehan (jehan at girinstud dot io)
- Johann (johann dot koenig at duck dot com)
- Johann Koenig (johann dot koenig at duck dot com)
- Jovan Zelincevic (jovan dot zelincevic at imgtec dot com)
- Jyrki Alakuijala (jyrki at google dot com)
- Konstantin Ivlev (tomskside at gmail dot com)
- Lode Vandevenne (lode at google dot com)
- Lou Quillio (louquillio at google dot com)
- Mans Rullgard (mans at mansr dot com)
- Marcin Kowalczyk (qrczak at google dot com)
- Martin Olsson (mnemo at minimum dot se)
- Maryla Ustarroz-Calonge (maryla at google dot com)
- Mikołaj Zalewski (mikolajz at google dot com)
- Mislav Bradac (mislavm at google dot com)
- Nico Weber (thakis at chromium dot org)
- Noel Chromium (noel at chromium dot org)
- Oliver Wolff (oliver dot wolff at qt dot io)
- Owen Rodley (orodley at google dot com)
- Parag Salasakar (img dot mips1 at gmail dot com)
- Pascal Massimino (pascal dot massimino at gmail dot com)
- Paweł Hajdan, Jr (phajdan dot jr at chromium dot org)
- Pierre Joye (pierre dot php at gmail dot com)
- Roberto Alanis (alanisbaez at google dot com)
- Sam Clegg (sbc at chromium dot org)
- Scott Hancher (seh at google dot com)
- Scott LaVarnway (slavarnway at google dot com)
@ -35,4 +49,8 @@ Contributors:
- Urvang Joshi (urvang at google dot com)
- Vikas Arora (vikasa at google dot com)
- Vincent Rabaud (vrabaud at google dot com)
- Vlad Tsyrklevich (vtsyrklevich at chromium dot org)
- Wan-Teh Chang (wtc at google dot com)
- Yang Zhang (yang dot zhang at arm dot com)
- Yannis Guyon (yguyon at google dot com)
- Zhi An Ng (zhin at chromium dot org)

View File

@ -11,16 +11,36 @@ ifeq ($(APP_OPTIM),release)
endif
endif
# mips32 fails to build with clang from r14b
# https://bugs.chromium.org/p/webp/issues/detail?id=343
ifeq ($(findstring clang,$(NDK_TOOLCHAIN_VERSION)),clang)
ifeq ($(TARGET_ARCH),mips)
clang_version := $(shell $(TARGET_CC) --version)
ifneq ($(findstring clang version 3,$(clang_version)),)
WEBP_CFLAGS += -no-integrated-as
endif
endif
endif
ifneq ($(findstring armeabi-v7a, $(TARGET_ARCH_ABI)),)
# Setting LOCAL_ARM_NEON will enable -mfpu=neon which may cause illegal
# instructions to be generated for armv7a code. Instead target the neon code
# specifically.
NEON := c.neon
USE_CPUFEATURES := yes
WEBP_CFLAGS += -DHAVE_CPU_FEATURES_H
else
NEON := c
endif
sharpyuv_srcs := \
sharpyuv/sharpyuv.c \
sharpyuv/sharpyuv_csp.c \
sharpyuv/sharpyuv_dsp.c \
sharpyuv/sharpyuv_gamma.c \
sharpyuv/sharpyuv_neon.$(NEON) \
sharpyuv/sharpyuv_sse2.c \
dec_srcs := \
src/dec/alpha_dec.c \
src/dec/buffer_dec.c \
@ -43,9 +63,6 @@ dsp_dec_srcs := \
src/dsp/alpha_processing_neon.$(NEON) \
src/dsp/alpha_processing_sse2.c \
src/dsp/alpha_processing_sse41.c \
src/dsp/argb.c \
src/dsp/argb_mips_dsp_r2.c \
src/dsp/argb_sse2.c \
src/dsp/cpu.c \
src/dsp/dec.c \
src/dsp/dec_clip_tables.c \
@ -65,6 +82,7 @@ dsp_dec_srcs := \
src/dsp/lossless_msa.c \
src/dsp/lossless_neon.$(NEON) \
src/dsp/lossless_sse2.c \
src/dsp/lossless_sse41.c \
src/dsp/rescaler.c \
src/dsp/rescaler_mips32.c \
src/dsp/rescaler_mips_dsp_r2.c \
@ -76,18 +94,21 @@ dsp_dec_srcs := \
src/dsp/upsampling_msa.c \
src/dsp/upsampling_neon.$(NEON) \
src/dsp/upsampling_sse2.c \
src/dsp/upsampling_sse41.c \
src/dsp/yuv.c \
src/dsp/yuv_mips32.c \
src/dsp/yuv_mips_dsp_r2.c \
src/dsp/yuv_neon.$(NEON) \
src/dsp/yuv_sse2.c \
src/dsp/yuv_sse41.c \
dsp_enc_srcs := \
src/dsp/cost.c \
src/dsp/cost_mips32.c \
src/dsp/cost_mips_dsp_r2.c \
src/dsp/cost_neon.$(NEON) \
src/dsp/cost_sse2.c \
src/dsp/enc.c \
src/dsp/enc_avx2.c \
src/dsp/enc_mips32.c \
src/dsp/enc_mips_dsp_r2.c \
src/dsp/enc_msa.c \
@ -101,14 +122,16 @@ dsp_enc_srcs := \
src/dsp/lossless_enc_neon.$(NEON) \
src/dsp/lossless_enc_sse2.c \
src/dsp/lossless_enc_sse41.c \
src/dsp/ssim.c \
src/dsp/ssim_sse2.c \
enc_srcs := \
src/enc/alpha_enc.c \
src/enc/analysis_enc.c \
src/enc/backward_references_cost_enc.c \
src/enc/backward_references_enc.c \
src/enc/config_enc.c \
src/enc/cost_enc.c \
src/enc/delta_palettization_enc.c \
src/enc/filter_enc.c \
src/enc/frame_enc.c \
src/enc/histogram_enc.c \
@ -160,7 +183,7 @@ LOCAL_SRC_FILES := \
$(utils_dec_srcs) \
LOCAL_CFLAGS := $(WEBP_CFLAGS)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src
# prefer arm over thumb mode for performance gains
LOCAL_ARM_MODE := arm
@ -189,12 +212,13 @@ endif # ENABLE_SHARED=1
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
$(sharpyuv_srcs) \
$(dsp_enc_srcs) \
$(enc_srcs) \
$(utils_enc_srcs) \
LOCAL_CFLAGS := $(WEBP_CFLAGS)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src
# prefer arm over thumb mode for performance gains
LOCAL_ARM_MODE := arm
@ -217,7 +241,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(demux_srcs)
LOCAL_CFLAGS := $(WEBP_CFLAGS)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src
# prefer arm over thumb mode for performance gains
LOCAL_ARM_MODE := arm
@ -240,7 +264,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(mux_srcs)
LOCAL_CFLAGS := $(WEBP_CFLAGS)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src
# prefer arm over thumb mode for performance gains
LOCAL_ARM_MODE := arm

View File

@ -1,189 +1,783 @@
cmake_minimum_required(VERSION 2.8.7)
# Copyright (c) 2020 Google LLC.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
project(libwebp C)
cmake_minimum_required(VERSION 3.7)
if(POLICY CMP0072)
cmake_policy(SET CMP0072 NEW)
endif()
project(WebP C)
# Options for coder / decoder executables.
option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." OFF)
option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." OFF)
option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." OFF)
option(WEBP_BUILD_IMG2WEBP "Build the img2webp animation tool." OFF)
option(WEBP_EXPERIMENTAL_FEATURES "Build with experimental features." OFF)
option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces." OFF)
if(BUILD_SHARED_LIBS)
set(WEBP_LINK_STATIC_DEFAULT OFF)
else()
set(WEBP_LINK_STATIC_DEFAULT ON)
endif()
option(WEBP_LINK_STATIC
"Link using static libraries. If OFF, use dynamic libraries."
${WEBP_LINK_STATIC_DEFAULT})
if(NOT EMSCRIPTEN)
# Disable SIMD on Emscripten by default, as it's a new unstable Wasm feature.
# Users can still explicitly opt-in to make a SIMD-enabled build.
set(WEBP_ENABLE_SIMD_DEFAULT ON)
endif()
option(WEBP_ENABLE_SIMD "Enable any SIMD optimization."
${WEBP_ENABLE_SIMD_DEFAULT})
option(WEBP_BUILD_ANIM_UTILS "Build animation utilities." ON)
option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." ON)
option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." ON)
option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." ON)
option(WEBP_BUILD_IMG2WEBP "Build the img2webp animation tool." ON)
option(WEBP_BUILD_VWEBP "Build the vwebp viewer tool." ON)
option(WEBP_BUILD_WEBPINFO "Build the webpinfo command line tool." ON)
option(WEBP_BUILD_LIBWEBPMUX "Build the libwebpmux library." ON)
option(WEBP_BUILD_WEBPMUX "Build the webpmux command line tool." ON)
option(WEBP_BUILD_EXTRAS "Build extras." ON)
option(WEBP_BUILD_WEBP_JS "Emscripten build of webp.js." OFF)
option(WEBP_USE_THREAD "Enable threading support" ON)
option(WEBP_NEAR_LOSSLESS "Enable near-lossless encoding" ON)
option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces."
OFF)
set(WEBP_BITTRACE "0" CACHE STRING "Bit trace mode (0=none, 1=bit, 2=bytes)")
set_property(CACHE WEBP_BITTRACE PROPERTY STRINGS 0 1 2)
if(WEBP_LINK_STATIC)
if(WIN32)
SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
else()
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# vwebp does not compile on Ubuntu with static libraries so disabling it for
# now.
set(WEBP_BUILD_VWEBP OFF)
endif()
# Option needed for handling Unicode file names on Windows.
if(WIN32)
option(WEBP_UNICODE "Build Unicode executables." ON)
endif()
if(WEBP_BUILD_WEBP_JS)
set(WEBP_BUILD_ANIM_UTILS OFF)
set(WEBP_BUILD_CWEBP OFF)
set(WEBP_BUILD_DWEBP OFF)
set(WEBP_BUILD_GIF2WEBP OFF)
set(WEBP_BUILD_IMG2WEBP OFF)
set(WEBP_BUILD_VWEBP OFF)
set(WEBP_BUILD_WEBPINFO OFF)
set(WEBP_BUILD_WEBPMUX OFF)
set(WEBP_BUILD_EXTRAS OFF)
set(WEBP_USE_THREAD OFF)
if(WEBP_ENABLE_SIMD)
message("wasm2js does not support SIMD, disabling webp.js generation.")
endif()
endif()
set(WEBP_DEP_LIBRARIES)
set(WEBP_DEP_INCLUDE_DIRS)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE
"Build type: Release, Debug or RelWithDebInfo" STRING FORCE
)
set(CMAKE_BUILD_TYPE "Release"
CACHE STRING "Build type: Release, Debug, MinSizeRel or RelWithDebInfo"
FORCE)
endif()
include(cmake/config.h.cmake)
# Include dependencies.
include(cmake/deps.cmake)
include(GNUInstallDirs)
################################################################################
# ##############################################################################
# Options.
if(WEBP_ENABLE_SWAP_16BIT_CSP)
add_definitions(-DWEBP_SWAP_16BIT_CSP)
add_definitions(-DWEBP_SWAP_16BIT_CSP=1)
endif()
################################################################################
if(NOT WEBP_BITTRACE STREQUAL "0")
add_definitions(-DBITTRACE=${WEBP_BITTRACE})
endif()
if(WEBP_UNICODE)
# Windows recommends setting both UNICODE and _UNICODE.
add_definitions(-DUNICODE -D_UNICODE)
endif()
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix "\$\{prefix\}")
set(libdir "\$\{prefix\}/lib")
set(includedir "\$\{prefix\}/include")
set(PTHREAD_LIBS ${CMAKE_THREAD_LIBS_INIT})
set(INSTALLED_LIBRARIES)
set(CMAKE_C_VISIBILITY_PRESET hidden)
# ##############################################################################
# Android only.
if(ANDROID)
include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
add_library(cpufeatures STATIC
${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c
)
${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
list(APPEND INSTALLED_LIBRARIES cpufeatures)
target_link_libraries(cpufeatures dl)
set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} cpufeatures)
set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS}
${ANDROID_NDK}/sources/android/cpufeatures
)
${ANDROID_NDK}/sources/android/cpufeatures)
add_definitions(-DHAVE_CPU_FEATURES_H=1)
set(HAVE_CPU_FEATURES_H 1)
else()
set(HAVE_CPU_FEATURES_H 0)
endif()
################################################################################
# WebP source files.
# Read the Makefile.am to get the source files.
function(configure_pkg_config FILE)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${FILE}.in"
"${CMAKE_CURRENT_BINARY_DIR}/${FILE}")
function(parse_Makefile_am FOLDER VAR)
file(READ ${FOLDER}/Makefile.am MAKEFILE_AM)
string(REGEX MATCHALL "_SOURCES \\+= [^\n]*"
FILES_PER_LINE ${MAKEFILE_AM}
if(HAVE_MATH_LIBRARY)
# MSVC doesn't have libm
file(READ ${CMAKE_CURRENT_BINARY_DIR}/${FILE} data)
string(REPLACE "-lm" "" data ${data})
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${FILE} ${data})
endif()
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/${FILE}"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
)
endfunction()
# ##############################################################################
# WebP source files. Read the Makefile.am to get the source files.
# We expect the Makefiles to define the sources as defined in the first regex.
# E.g.: libimagedec_la_SOURCES = image_dec.c image_dec.h
function(parse_Makefile_am FOLDER VAR SRC_REGEX)
file(READ ${FOLDER}/Makefile.am MAKEFILE_AM)
string(REGEX MATCHALL
"${SRC_REGEX}_SOURCES[ ]*\\+?=[ ]+[0-9a-z\\._ ]*"
FILES_PER_LINE
${MAKEFILE_AM})
set(SRCS ${${VAR}})
foreach(FILES ${FILES_PER_LINE})
string(SUBSTRING ${FILES} 12 -1 FILES)
string(REGEX MATCHALL "[0-9a-z\\._]+"
FILES ${FILES}
)
foreach(FILE ${FILES})
list(APPEND SRCS ${FOLDER}/${FILE})
endforeach()
string(FIND ${FILES} "=" OFFSET)
math(EXPR OFFSET "${OFFSET} + 2")
string(SUBSTRING ${FILES}
${OFFSET}
-1
FILES)
if(FILES)
string(REGEX MATCHALL
"[0-9a-z\\._]+"
FILES
${FILES})
foreach(FILE ${FILES})
list(APPEND SRCS ${FOLDER}/${FILE})
endforeach()
endif()
endforeach()
set(${VAR} ${SRCS} PARENT_SCOPE)
endfunction()
set(WEBP_SRCS)
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/dec "WEBP_SRCS")
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/demux "WEBP_SRCS")
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/dsp "WEBP_SRCS")
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/enc "WEBP_SRCS")
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/utils "WEBP_SRCS")
set(WEBP_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
parse_makefile_am(${WEBP_SRC_DIR}/dec "WEBP_DEC_SRCS" "")
parse_makefile_am(${WEBP_SRC_DIR}/demux "WEBP_DEMUX_SRCS" "")
parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_COMMON_SRCS" "COMMON")
parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_ENC_SRCS" "ENC")
parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_ENC_SRCS" "dsp_[^ ]*")
parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_DEC_SRCS" "decode_[^ ]*")
parse_makefile_am(${WEBP_SRC_DIR}/enc "WEBP_ENC_SRCS" "")
parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_COMMON_SRCS" "COMMON")
parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_ENC_SRCS" "ENC")
parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_DEC_SRCS" "decode_[^ ]*")
# Remove the files specific to SIMD we don't use.
foreach(FILE ${WEBP_SIMD_FILES_NOT_TO_INCLUDE})
list(REMOVE_ITEM WEBP_SRCS ${FILE})
list(REMOVE_ITEM WEBP_DSP_ENC_SRCS ${FILE})
list(REMOVE_ITEM WEBP_DSP_DEC_SRCS ${FILE})
endforeach()
# Build the library.
add_definitions(-Wall)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/ ${WEBP_DEP_INCLUDE_DIRS})
add_library(webp ${WEBP_SRCS})
target_link_libraries(webp ${WEBP_DEP_LIBRARIES})
# Generate the config.h file.
configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in
${CMAKE_CURRENT_BINARY_DIR}/src/webp/config.h)
add_definitions(-DHAVE_CONFIG_H)
# Change the compile flags for SIMD files we use.
# ##############################################################################
# Build the webpdecoder library.
# Creates a source file with an unused stub function in $CMAKE_BINARY_DIR and
# adds it to the specified target. Currently used only with Xcode.
#
# See also:
# https://cmake.org/cmake/help/v3.18/command/add_library.html#object-libraries
# "Some native build systems (such as Xcode) may not like targets that have
# only object files, so consider adding at least one real source file to any
# target that references $<TARGET_OBJECTS:objlib>."
function(libwebp_add_stub_file TARGET)
set(stub_source_dir "${CMAKE_BINARY_DIR}")
set(stub_source_file
"${stub_source_dir}/libwebp_${TARGET}_stub.c")
set(stub_source_code
"// Generated file. DO NOT EDIT!\n"
"// C source file created for target ${TARGET}.\n"
"void libwebp_${TARGET}_stub_function(void)\;\n"
"void libwebp_${TARGET}_stub_function(void) {}\n")
file(WRITE "${stub_source_file}" ${stub_source_code})
target_sources(${TARGET} PRIVATE ${stub_source_file})
endfunction()
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv "WEBP_SHARPYUV_SRCS"
"")
add_library(sharpyuv OBJECT ${WEBP_SHARPYUV_SRCS})
target_include_directories(sharpyuv
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(
sharpyuv
PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv/sharpyuv.h;\
${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv/sharpyuv_csp.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
if(MSVC)
# avoid security warnings for e.g., fopen() used in the examples.
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
else()
add_definitions(-Wall)
endif()
include_directories(${WEBP_DEP_INCLUDE_DIRS})
add_library(webpdecode OBJECT ${WEBP_DEC_SRCS})
target_include_directories(webpdecode
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR})
add_library(webpdspdecode OBJECT ${WEBP_DSP_COMMON_SRCS} ${WEBP_DSP_DEC_SRCS})
target_include_directories(webpdspdecode
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR})
add_library(webputilsdecode
OBJECT
${WEBP_UTILS_COMMON_SRCS}
${WEBP_UTILS_DEC_SRCS})
target_include_directories(webputilsdecode
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR})
add_library(webpdecoder
$<TARGET_OBJECTS:webpdecode>
$<TARGET_OBJECTS:webpdspdecode>
$<TARGET_OBJECTS:webputilsdecode>)
if(XCODE)
libwebp_add_stub_file(webpdecoder)
endif()
target_link_libraries(webpdecoder ${WEBP_DEP_LIBRARIES})
target_include_directories(
webpdecoder
PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
set_target_properties(
webpdecoder
PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
configure_pkg_config("src/libwebpdecoder.pc")
# Build the webp library.
add_library(webpencode OBJECT ${WEBP_ENC_SRCS})
target_include_directories(webpencode
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR})
add_library(webpdsp
OBJECT
${WEBP_DSP_COMMON_SRCS}
${WEBP_DSP_DEC_SRCS}
${WEBP_DSP_ENC_SRCS})
target_include_directories(webpdsp
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR})
add_library(webputils
OBJECT
${WEBP_UTILS_COMMON_SRCS}
${WEBP_UTILS_DEC_SRCS}
${WEBP_UTILS_ENC_SRCS})
target_include_directories(webputils
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR})
add_library(webp
$<TARGET_OBJECTS:sharpyuv>
$<TARGET_OBJECTS:webpdecode>
$<TARGET_OBJECTS:webpdsp>
$<TARGET_OBJECTS:webpencode>
$<TARGET_OBJECTS:webputils>)
if(XCODE)
libwebp_add_stub_file(webp)
endif()
target_link_libraries(webp ${WEBP_DEP_LIBRARIES})
target_include_directories(
webp
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:include>)
set_target_properties(
webp
PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/encode.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
# Make sure the OBJECT libraries are built with position independent code (it is
# not ON by default).
set_target_properties(sharpyuv
webpdecode
webpdspdecode
webputilsdecode
webpencode
webpdsp
webputils
PROPERTIES POSITION_INDEPENDENT_CODE ON)
configure_pkg_config("src/libwebp.pc")
# Build the webp demux library.
add_library(webpdemux ${WEBP_DEMUX_SRCS})
target_link_libraries(webpdemux webp)
target_include_directories(webpdemux
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
PUBLIC $<INSTALL_INTERFACE:include>)
set_target_properties(
webpdemux
PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/demux.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux_types.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
configure_pkg_config("src/demux/libwebpdemux.pc")
# Set the version numbers.
macro(set_version FILE TARGET_NAME NAME_IN_MAKEFILE)
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/src/${FILE} SOURCE_FILE)
string(REGEX MATCH
"${NAME_IN_MAKEFILE}_la_LDFLAGS[^\n]* -version-info [0-9:]+"
TMP
${SOURCE_FILE})
string(REGEX MATCH
"[0-9:]+"
TMP
${TMP})
string(REGEX
REPLACE ":"
" "
LT_VERSION
${TMP})
# See the libtool docs for more information:
# https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
#
# c=<current>, a=<age>, r=<revision>
#
# libtool generates a .so file as .so.[c-a].a.r, while -version-info c:r:a is
# passed to libtool.
#
# We set FULL = [c-a].a.r and MAJOR = [c-a].
separate_arguments(LT_VERSION)
list(GET LT_VERSION 0 LT_CURRENT)
list(GET LT_VERSION 1 LT_REVISION)
list(GET LT_VERSION 2 LT_AGE)
math(EXPR LT_CURRENT_MINUS_AGE "${LT_CURRENT} - ${LT_AGE}")
set_target_properties(
${TARGET_NAME}
PROPERTIES VERSION
${LT_CURRENT_MINUS_AGE}.${LT_AGE}.${LT_REVISION}
SOVERSION
${LT_CURRENT_MINUS_AGE})
endmacro()
set_version(Makefile.am webp webp)
set_version(Makefile.am webpdecoder webpdecoder)
set_version(demux/Makefile.am webpdemux webpdemux)
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac CONFIGURE_FILE)
string(REGEX MATCH
"AC_INIT\\([^\n]*\\[[0-9\\.]+\\]"
TMP
${CONFIGURE_FILE})
string(REGEX MATCH
"[0-9\\.]+"
PROJECT_VERSION
${TMP})
# Define the libraries to install.
list(APPEND INSTALLED_LIBRARIES webpdecoder webp webpdemux)
# Deal with SIMD. Change the compile flags for SIMD files we use.
list(LENGTH WEBP_SIMD_FILES_TO_INCLUDE WEBP_SIMD_FILES_TO_INCLUDE_LENGTH)
math(EXPR WEBP_SIMD_FILES_TO_INCLUDE_RANGE
"${WEBP_SIMD_FILES_TO_INCLUDE_LENGTH}-1"
)
"${WEBP_SIMD_FILES_TO_INCLUDE_LENGTH}-1")
foreach(I_FILE RANGE ${WEBP_SIMD_FILES_TO_INCLUDE_RANGE})
list(GET WEBP_SIMD_FILES_TO_INCLUDE ${I_FILE} FILE)
list(GET WEBP_SIMD_FLAGS_TO_INCLUDE ${I_FILE} SIMD_COMPILE_FLAG)
set_source_files_properties(${FILE} PROPERTIES
COMPILE_FLAGS ${SIMD_COMPILE_FLAG}
)
set_source_files_properties(${FILE}
PROPERTIES
COMPILE_FLAGS
${SIMD_COMPILE_FLAG})
endforeach()
# Build the executables if asked for.
if(WEBP_BUILD_CWEBP OR WEBP_BUILD_DWEBP OR
WEBP_BUILD_GIF2WEBP OR WEBP_BUILD_IMG2WEBP)
# Example utility library.
set(exampleutil_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h
${CMAKE_CURRENT_SOURCE_DIR}/examples/example_util.c
${CMAKE_CURRENT_SOURCE_DIR}/examples/example_util.h)
add_library(exampleutil ${exampleutil_SRCS})
target_link_libraries(exampleutil webp ${WEBP_DEP_LIBRARIES})
if(NOT WEBP_BUILD_LIBWEBPMUX)
set(WEBP_BUILD_GIF2WEBP OFF)
set(WEBP_BUILD_IMG2WEBP OFF)
set(WEBP_BUILD_WEBPMUX OFF)
endif()
set(imageioutil_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/imageio/imageio_util.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/imageio_util.h)
add_library(imageioutil ${imageioutil_SRCS})
target_link_libraries(imageioutil ${WEBP_DEP_LIBRARIES})
if(WEBP_BUILD_GIF2WEBP AND NOT GIF_FOUND)
set(WEBP_BUILD_GIF2WEBP OFF)
endif()
if(WEBP_BUILD_ANIM_UTILS AND NOT GIF_FOUND)
set(WEBP_BUILD_ANIM_UTILS OFF)
endif()
# Build the executables if asked for.
if(WEBP_BUILD_ANIM_UTILS
OR WEBP_BUILD_CWEBP
OR WEBP_BUILD_DWEBP
OR WEBP_BUILD_GIF2WEBP
OR WEBP_BUILD_IMG2WEBP
OR WEBP_BUILD_VWEBP
OR WEBP_BUILD_WEBPMUX
OR WEBP_BUILD_WEBPINFO)
# Example utility library.
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "EXAMPLEUTIL_SRCS"
"example_util_[^ ]*")
list(APPEND EXAMPLEUTIL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
add_library(exampleutil STATIC ${EXAMPLEUTIL_SRCS})
target_include_directories(
exampleutil
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEIOUTILS_SRCS"
"imageio_util_[^ ]*")
add_library(imageioutil STATIC ${IMAGEIOUTILS_SRCS})
target_link_libraries(imageioutil webp)
target_link_libraries(exampleutil imageioutil)
# Image-decoding utility library.
set(imagedec_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/examples/gifdec.c
${CMAKE_CURRENT_SOURCE_DIR}/examples/gifdec.h
${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_dec.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_dec.h
${CMAKE_CURRENT_SOURCE_DIR}/imageio/jpegdec.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/jpegdec.h
${CMAKE_CURRENT_SOURCE_DIR}/imageio/metadata.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/metadata.h
${CMAKE_CURRENT_SOURCE_DIR}/imageio/pngdec.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/pngdec.h
${CMAKE_CURRENT_SOURCE_DIR}/imageio/tiffdec.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/tiffdec.h
${CMAKE_CURRENT_SOURCE_DIR}/imageio/webpdec.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/webpdec.h
${CMAKE_CURRENT_SOURCE_DIR}/imageio/wicdec.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/wicdec.h)
add_library(imagedec ${imagedec_SRCS})
target_link_libraries(imagedec webp ${WEBP_DEP_LIBRARIES}
${WEBP_DEP_IMG_LIBRARIES})
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEDEC_SRCS"
"imagedec_[^ ]*")
add_library(imagedec STATIC ${IMAGEDEC_SRCS})
target_link_libraries(imagedec
imageioutil
webpdemux
webp
${WEBP_DEP_IMG_LIBRARIES})
# Image-encoding utility library.
set(imageenc_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_enc.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_enc.h)
add_library(imageenc ${imageenc_SRCS})
target_link_libraries(imageenc webp imageioutil
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES})
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEENC_SRCS"
"imageenc_[^ ]*")
add_library(imageenc STATIC ${IMAGEENC_SRCS})
target_link_libraries(imageenc imageioutil webp)
set_property(TARGET exampleutil
imageioutil
imagedec
imageenc
PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_BINARY_DIR}/src)
endif()
if(WEBP_BUILD_DWEBP)
# dwebp
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
add_executable(dwebp
${CMAKE_CURRENT_SOURCE_DIR}/examples/dwebp.c
${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
target_link_libraries(dwebp imagedec imageenc webp
exampleutil imageioutil
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
)
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "DWEBP_SRCS" "dwebp")
add_executable(dwebp ${DWEBP_SRCS})
target_link_libraries(dwebp exampleutil imagedec imageenc)
target_include_directories(dwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
install(TARGETS dwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(WEBP_BUILD_CWEBP)
# cwebp
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
add_executable(cwebp
${CMAKE_CURRENT_SOURCE_DIR}/examples/cwebp.c
${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
target_link_libraries(cwebp imagedec webp exampleutil imageioutil
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
)
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "CWEBP_SRCS" "cwebp")
add_executable(cwebp ${CWEBP_SRCS})
target_link_libraries(cwebp exampleutil imagedec webp)
target_include_directories(cwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
install(TARGETS cwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(WEBP_BUILD_LIBWEBPMUX)
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "WEBP_MUX_SRCS" "")
add_library(libwebpmux ${WEBP_MUX_SRCS})
target_link_libraries(libwebpmux webp)
target_include_directories(libwebpmux
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR})
set_version(mux/Makefile.am libwebpmux webpmux)
set_target_properties(libwebpmux
PROPERTIES PUBLIC_HEADER
"${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux_types.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h;")
set_target_properties(libwebpmux PROPERTIES OUTPUT_NAME webpmux)
list(APPEND INSTALLED_LIBRARIES libwebpmux)
configure_pkg_config("src/mux/libwebpmux.pc")
endif()
if(WEBP_BUILD_GIF2WEBP)
# gif2webp
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
set(GIF2WEBP_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/gif2webp.c)
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "GIF2WEBP_SRCS")
include_directories(${WEBP_DEP_GIF_INCLUDE_DIRS})
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "GIF2WEBP_SRCS"
"gif2webp")
add_executable(gif2webp ${GIF2WEBP_SRCS})
target_link_libraries(gif2webp imagedec webp exampleutil imageioutil
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
)
target_link_libraries(gif2webp
exampleutil
imageioutil
webp
libwebpmux
${WEBP_DEP_GIF_LIBRARIES})
target_include_directories(gif2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
install(TARGETS gif2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(WEBP_BUILD_IMG2WEBP)
# img2webp
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
set(IMG2WEBP_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/img2webp.c)
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "IMG2WEBP_SRCS")
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "IMG2WEBP_SRCS"
"img2webp")
add_executable(img2webp ${IMG2WEBP_SRCS})
target_link_libraries(img2webp imagedec webp exampleutil imageioutil
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
)
target_link_libraries(img2webp
exampleutil
imagedec
imageioutil
webp
libwebpmux)
target_include_directories(img2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
install(TARGETS img2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(WEBP_BUILD_VWEBP)
# vwebp
find_package(GLUT)
if(GLUT_FOUND)
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "VWEBP_SRCS" "vwebp")
add_executable(vwebp ${VWEBP_SRCS})
target_link_libraries(vwebp
${OPENGL_LIBRARIES}
exampleutil
${GLUT_glut_LIBRARY}
imageioutil
webp
webpdemux)
target_include_directories(vwebp
PRIVATE ${GLUT_INCLUDE_DIR}
${CMAKE_CURRENT_BINARY_DIR}/src
${OPENGL_INCLUDE_DIR})
install(TARGETS vwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
check_c_compiler_flag("-Wno-deprecated-declarations" HAS_NO_DEPRECATED)
if(HAS_NO_DEPRECATED)
target_compile_options(vwebp PRIVATE "-Wno-deprecated-declarations")
endif()
endif()
endif()
endif()
if(WEBP_BUILD_WEBPINFO)
# webpinfo
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "WEBPINFO_SRCS"
"webpinfo")
add_executable(webpinfo ${WEBPINFO_SRCS})
target_link_libraries(webpinfo exampleutil imageioutil)
target_include_directories(webpinfo
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/src)
install(TARGETS webpinfo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(WEBP_BUILD_WEBPMUX)
# webpmux
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "WEBPMUX_SRCS"
"webpmux")
add_executable(webpmux ${WEBPMUX_SRCS})
target_link_libraries(webpmux exampleutil imageioutil libwebpmux webp)
target_include_directories(webpmux PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
install(TARGETS webpmux RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(WEBP_BUILD_EXTRAS)
set(EXTRAS_MAKEFILE "${CMAKE_CURRENT_SOURCE_DIR}/extras")
parse_makefile_am(${EXTRAS_MAKEFILE} "WEBP_EXTRAS_SRCS" "libwebpextras_la")
parse_makefile_am(${EXTRAS_MAKEFILE} "GET_DISTO_SRCS" "get_disto")
parse_makefile_am(${EXTRAS_MAKEFILE} "WEBP_QUALITY_SRCS" "webp_quality")
parse_makefile_am(${EXTRAS_MAKEFILE} "VWEBP_SDL_SRCS" "vwebp_sdl")
# libextras
add_library(extras STATIC ${WEBP_EXTRAS_SRCS})
target_include_directories(extras
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/src)
# get_disto
add_executable(get_disto ${GET_DISTO_SRCS})
target_link_libraries(get_disto imagedec)
target_include_directories(get_disto
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}/src)
# webp_quality
add_executable(webp_quality ${WEBP_QUALITY_SRCS})
target_link_libraries(webp_quality exampleutil imagedec extras)
target_include_directories(webp_quality
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR})
# vwebp_sdl
find_package(SDL)
if(WEBP_BUILD_VWEBP AND SDL_FOUND)
add_executable(vwebp_sdl ${VWEBP_SDL_SRCS})
target_link_libraries(vwebp_sdl ${SDL_LIBRARY} imageioutil webp)
target_include_directories(vwebp_sdl
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/src
${SDL_INCLUDE_DIR})
set(WEBP_HAVE_SDL 1)
target_compile_definitions(vwebp_sdl PUBLIC WEBP_HAVE_SDL)
endif()
endif()
if(WEBP_BUILD_WEBP_JS)
# wasm2js does not support SIMD.
if(NOT WEBP_ENABLE_SIMD)
# JavaScript version
add_executable(webp_js ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
target_link_libraries(webp_js webpdecoder SDL)
target_include_directories(webp_js PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
set(WEBP_HAVE_SDL 1)
set_target_properties(
webp_js
PROPERTIES LINK_FLAGS "-s WASM=0 \
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
-s EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
endif()
# WASM version
add_executable(webp_wasm ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
target_link_libraries(webp_wasm webpdecoder SDL)
target_include_directories(webp_wasm PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
set_target_properties(
webp_wasm
PROPERTIES LINK_FLAGS "-s WASM=1 \
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
-s EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
target_compile_definitions(webp_wasm PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
target_compile_definitions(webpdspdecode PUBLIC EMSCRIPTEN)
endif()
if(WEBP_BUILD_ANIM_UTILS)
# anim_diff
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS} ${WEBP_DEP_GIF_INCLUDE_DIRS})
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "ANIM_DIFF_SRCS"
"anim_diff")
add_executable(anim_diff ${ANIM_DIFF_SRCS})
target_link_libraries(anim_diff
exampleutil
imagedec
imageenc
imageioutil
webp
webpdemux
${WEBP_DEP_GIF_LIBRARIES})
target_include_directories(anim_diff PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
# anim_dump
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS} ${WEBP_DEP_GIF_INCLUDE_DIRS})
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "ANIM_DUMP_SRCS"
"anim_dump")
add_executable(anim_dump ${ANIM_DUMP_SRCS})
target_link_libraries(anim_dump
exampleutil
imagedec
imageenc
imageioutil
webp
webpdemux
${WEBP_DEP_GIF_LIBRARIES})
target_include_directories(anim_dump PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
endif()
# Install the different headers and libraries.
install(TARGETS ${INSTALLED_LIBRARIES}
EXPORT ${PROJECT_NAME}Targets
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webp
INCLUDES
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
set(ConfigPackageLocation ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/cmake/)
install(EXPORT ${PROJECT_NAME}Targets
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${ConfigPackageLocation})
# Create the CMake version file.
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
VERSION ${PACKAGE_VERSION}
COMPATIBILITY AnyNewerVersion)
# Create the Config file.
include(CMakePackageConfigHelpers)
# Fix libwebpmux reference. The target name libwebpmux is used for
# compatibility purposes, but the library mentioned in WebPConfig.cmake should
# be the unprefixed version.
list(TRANSFORM INSTALLED_LIBRARIES REPLACE "libwebpmux" "webpmux")
configure_package_config_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/WebPConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/WebPConfig.cmake
INSTALL_DESTINATION
${ConfigPackageLocation})
# Install the generated CMake files.
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/WebPConfig.cmake"
DESTINATION ${ConfigPackageLocation})
# Install the man pages.
set(MAN_PAGES
cwebp.1
dwebp.1
gif2webp.1
img2webp.1
vwebp.1
webpmux.1
webpinfo.1)
set(EXEC_BUILDS
"CWEBP"
"DWEBP"
"GIF2WEBP"
"IMG2WEBP"
"VWEBP"
"WEBPMUX"
"WEBPINFO")
list(LENGTH MAN_PAGES MAN_PAGES_LENGTH)
math(EXPR MAN_PAGES_RANGE "${MAN_PAGES_LENGTH} - 1")
foreach(I_MAN RANGE ${MAN_PAGES_RANGE})
list(GET EXEC_BUILDS ${I_MAN} EXEC_BUILD)
if(WEBP_BUILD_${EXEC_BUILD})
list(GET MAN_PAGES ${I_MAN} MAN_PAGE)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man/${MAN_PAGE}
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1
COMPONENT doc)
endif()
endforeach()

29
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,29 @@
# How to Contribute
We'd love to accept your patches and contributions to this project. There are
just a few small guidelines you need to follow.
## Contributor License Agreement
Contributions to this project must be accompanied by a Contributor License
Agreement. You (or your employer) retain the copyright to your contribution;
this simply gives us permission to use and redistribute your contributions as
part of the project. Head over to <https://cla.developers.google.com/> to see
your current agreements on file or to sign a new one.
You generally only need to submit a CLA once, so if you've already submitted one
(even if it was for a different project), you probably don't need to do it
again.
## Code reviews
All submissions, including submissions by project members, require review. We
use a [Gerrit](https://www.gerritcodereview.com) instance hosted at
https://chromium-review.googlesource.com for this purpose. See the
[WebM Project page](https://www.webmproject.org/code/contribute/submitting-patches/)
for additional details.
## Community Guidelines
This project follows
[Google's Open Source Community Guidelines](https://opensource.google.com/conduct/).

934
ChangeLog
View File

@ -1,9 +1,931 @@
980d2488 update NEWS
9fde8127 bump version to 1.2.4
e626925c lossless: fix crunch mode w/WEBP_REDUCE_SIZE
bfad7ab5 CMakeLists.txt: correct libwebpmux name in WebPConfig.cmake
c2e3fd30 Revert "cmake: fix webpmux lib name for cmake linking"
3c4a0fbf update ChangeLog (tag: v1.2.3)
56a480e8 dsp/cpu.h: add missing extern "C"
62b45bdd update ChangeLog (tag: v1.2.3-rc1)
8764ec7a Merge changes Idb037953,Id582e395 into 1.2.3
bcb872c3 vwebp: fix file name display in windows unicode build
67c44ac5 webpmux: fix -frame option in windows unicode build
8278825a makefile.unix: add sharpyuv objects to clean target
14a49e01 update NEWS
34b1dc33 bump version to 1.2.3
0b397fda update AUTHORS
c16488ac update .mailmap
5a2d929c Merge "unicode.h: set console mode before using wprintf" into main
169f867f unicode.h: set console mode before using wprintf
a94b855c Merge "libsharpyuv: add version defines" into main
f83bdb52 libsharpyuv: add version defines
bef0d797 unicode_gif.h: fix -Wdeclaration-after-statement
404c1622 Rename Huffman coding to prefix coding in the bitstream spec
8895f8a3 Merge "run_static_analysis.sh: fix scan-build archive path" into main
92a673d2 Merge "Add -fvisibility=hidden flag in CMakeLists." into main
67c1d722 Merge "add WEBP_MSAN" into main
1124ff66 Add -fvisibility=hidden flag in CMakeLists.
e15b3560 add WEBP_MSAN
ec9e782a sharpyuv: remove minimum image size from sharpyuv library
7bd07f3b run_static_analysis.sh: fix scan-build archive path
5ecee06f Merge "sharpyuv: increase precision of gamma<->linear conversion" into main
f81dd7d6 Merge changes I3d17d529,I53026880,I1bd61639,I6bd4b25d,Icfec8fba into main
2d607ee6 sharpyuv: increase precision of gamma<->linear conversion
266cbbc5 sharpyuv: add 32bit version of SharpYuvFilterRow.
9fc12274 CMake: add src to webpinfo includes
7d18f40a CMake: add WEBP_BUILD_WEBPINFO to list of checks for exampleutil
11309aa5 CMake: add WEBP_BUILD_WEBPMUX to list of checks for exampleutil
4bc762f7 CMake: link imageioutil to exampleutil after defined
0d1b9bc4 WEBP_DEP_LIBRARIES: use Threads::Threads
20ef48f0 Merge "sharpyuv: add support for 10/12/16 bit rgb and 10/12 bit yuv." into main
93c54371 sharpyuv: add support for 10/12/16 bit rgb and 10/12 bit yuv.
53cf2b49 normalize WebPValidatePicture declaration w/definition
d3006f4b sharpyuv: slightly improve precision
ea967098 Merge changes Ia01bd397,Ibf3771af into main
11bc8410 Merge changes I2d317c4b,I9e77f6db into main
30453ea4 Add an internal WebPValidatePicture.
6c43219a Some renamings for consistency.
4f59fa73 update .mailmap
e74f8a62 webp-lossless-bitstream-spec,cosmetics: normalize range syntax
5a709ec0 webp-lossless-bitstream-spec,cosmetics: fix code typo
a2093acc webp-lossless-bitstream-spec: add amendment note
86c66930 webp-lossless-bitstream-spec: fix BNF
232f22da webp-lossless-bitstream-spec: fix 'simple code' snippet
44dd765d webp-lossless-bitstream-spec: fix ColorTransform impl
7a7e33e9 webp-lossless-bitstream-spec: fix TR-pixel right border note
86f94ee0 Update lossless spec with Huffman codes.
a3927cc8 sharpyuv.c,cosmetics: fix indent
6c45cef7 Make sure the stride has a minimum value in the importer.
0c8b0e67 sharpyuv: cleanup/cosmetic changes
dc3841e0 {histogram,predictor}_enc: quiet int -> float warnings
a19a25bb Replace doubles by floats in lossless misc cost estimations.
42888f6c Add an option to enable static builds.
7efcf3cc Merge "Fix typo in color constants: Marix -> Matrix" into main
8f4b5c62 Fix typo in color constants: Marix -> Matrix
90084d84 Merge "demux,IsValidExtendedFormat: remove unused variable" into main
ed643f61 Merge changes I452d2485,Ic6d75475 into main
8fa053d1 Rename SharpYUV to SharpYuv for consistency.
99a87562 SharpYuvComputeConversionMatrix: quiet int->float warnings
deb426be Makefile.vc: add sharpyuv_csp.obj to SHARPYUV_OBJS
779597d4 demux,IsValidExtendedFormat: remove unused variable
40e8aa57 Merge "libsharpyuv: add colorspace utilities" into main
01a05de1 libsharpyuv: add colorspace utilities
2de4b05a Merge changes Id9890a60,I376d81e6,I1c958838 into main
b8bca81f Merge "configure.ac: use LT_INIT if available" into main
e8e77b9c Merge changes I479bc487,I39864691,I5d486c2c,I186d13be into main
7e7d5d50 Merge ".gitignore: add Android Studio & VS code dirs" into main
10c50848 normalize label indent
89f774e6 mux{edit,internal}: fix leaks on error
2d3293ad ExUtilInitCommandLineArguments: fix leak on error
ec34fd70 anim_util: fix leaks on error
e4717287 gif2webp: fix segfault on OOM
e3cfafaf GetBackwardReferences: fail on alloc error
a828a59b BackwardReferencesHashChainDistanceOnly: fix segfault on OOM
fe153fae VP8LEncodeStream: fix segfault on OOM
919acc0e .gitignore: add Android Studio & VS code dirs
efa0731b configure.ac: use LT_INIT if available
0957fd69 tiffdec: add grayscale support
e685feef Merge "Make libsharpyuv self-contained by removing dependency on cpu.c" into main
841960b6 Make libsharpyuv self-contained by removing dependency on cpu.c
617cf036 image_dec: add WebPGetEnabledInputFileFormats()
7a68afaa Let SharpArgbToYuv caller pass in an RGB>YUV conversion matrix.
34bb332c man/cwebp.1: add note about crop/resize order
f0e9351c webp-lossless-bitstream-spec,cosmetics: fix some typos
5ccbd6ed vp8l_dec.c,cosmetics: fix a few typos
c3d0c2d7 fix ios build scripts after sharpyuv dep added
d0d2292e Merge "Make libwebp depend on libsharpyuv." into main
03d12190 alpha_processing_neon.c: fix 0x01... typo
d55d447c Make libwebp depend on libsharpyuv.
e4cbcdd2 Fix lossless encoding for MIPS.
924e7ca6 alpha_processing_neon.c: fix Dispatch/ExtractAlpha_NEON
0fa0ea54 Makefile.vc: use /MANIFEST:EMBED
29cc95ce Basic version of libsharpyuv in libwebp, in C.
a30f2190 examples/webpmux.c: fix a couple of typos
66b3ce23 Fix bad overflow check in ReadTIFF()
54e61a38 Markdownify libwebp docs and reorganize them.
b4533deb CMakeLists.txt,cosmetics: break long line
b9d2f9cd quant_enc.c: use WEBP_RESTRICT qualifier
ec178f2c Add progress hook granularity in lossless
26139c73 Rename MAX_COST to MAX_BIT_COST in histogram_enc.c
13b82816 cmake: fix webpmux lib name for cmake linking
88b6a396 webp-container-spec.txt,cosmetics: normalize formatting
6f496540 Merge tag 'v1.2.2'
4074acf8 dsp.h: bump msvc arm64 version requirement to 16.6
b0a86089 update ChangeLog (tag: v1.2.2)
6db8248c libwebp: Fix VP8EncTokenLoop() progress
827a307f BMP enc: fix the transparency case
db25f1b4 libwebp: Fix VP8EncTokenLoop() progress
286e7fce libwebp: do not destroy jpeg codec twice on error
6e8a4126 libwebp: do not destroy jpeg codec twice on error
faf21968 Merge "BMP enc: fix the transparency case" into main
480cd51d BMP enc: fix the transparency case
9195ea05 update ChangeLog (tag: v1.2.2-rc2)
4acae017 update NEWS
883f0633 man/img2webp.1: update date
567e1f44 Reword img2webp synopsis command line
1b0c15db man/img2webp.1: update date
17bade38 Merge "Reword img2webp synopsis command line" into main
a80954a1 Reword img2webp synopsis command line
f084244d anim_decode: fix alpha blending with big-endian
b217b4ff webpinfo: fix fourcc comparison w/big-endian
ec497b75 Merge "anim_decode: fix alpha blending with big-endian" into main
e4886716 anim_decode: fix alpha blending with big-endian
e3cb052c webpinfo: fix fourcc comparison w/big-endian
a510fedb patch-check: detect duplicated files
f035d2e4 update ChangeLog (tag: v1.2.2-rc1)
7031946a update NEWS
973390b6 bump version to 1.2.2
abd6664f update AUTHORS
5b7e7930 Merge "add missing USE_{MSA,NEON} checks in headers" into main
02ca04c3 add missing USE_{MSA,NEON} checks in headers
e94716e2 xcframeworkbuild.sh: place headers in a subdir
c846efd8 patch-check: commit subject length check
b6f756e8 update http links
8f5cb4c1 update rfc links
8ea81561 change VP8LPredictorFunc signature to avoid reading 'left'
6b1d18c3 webpmux: fix the -bgcolor description
3368d876 Merge "webpmux: add "-set bgcolor A,R,G,B"" into main
f213abf6 webpinfo: print the number of warnings
50c97c30 webpmux: add "-set bgcolor A,R,G,B"
2c206aaf Remove CMakeLists.txt check in compile.sh
96e3dfef Merge "infra/common.sh: add shard_should_run()" into main
0e0f74b7 infra/common.sh: add shard_should_run()
35b7436a Jenkins scripts port: update shell function comments
21d24b4c webp-container-spec.txt: remove 'experimental' markers
cdcf8902 Merge "Port Jenkins script: compile" into main
dc683cde Jenkins scripts port: static analysis
0858494e Port Jenkins script: compile
c2cf6a93 Jenkins scripts port: android compilation
df0e808f presubmit: Add pylint-2.7 and .pylintrc
676c57db patch-check: shfmt
7bb7f747 patch-check: Add shellcheck
abcd1797 Reformat docstrings and imports
edaf0895 Port Jenkins scripts: compile js
b9622063 Set CheckPatchFormatted flags to fail on diffs
e23cd548 dsp.h: enable NEON w/VS2019+ ARM64 targets
3875c7de CMakeLists.txt: set minimum version to 3.7
1a8f0d45 Have a hard-coded value for memset in TrellisQuantizeBlock.
93480160 Speed up TrellisQuantizeBlock
45eaacc9 Convert deprecated uint32 to uint32_t.
42592af8 webp,cmake: Remove unnecessary include dirs
e298e05f Add patch-check steps in PRESUBMIT.py
29148919 Merge tag 'v1.2.1'
9ce5843d update ChangeLog (tag: v1.2.1)
d9191588 fuzzer/*: normalize src/ includes
c5bc3624 fuzzer/*: normalize src/ includes
53b6f762 fix indent
d2caaba4 fix indent
731246ba update ChangeLog (tag: v1.2.1-rc2)
d250f01d dsp/*: use WEBP_HAVE_* to determine Init availability
1fe31625 dsp/*: use WEBP_HAVE_* to determine Init availability
3a4d3ecd update NEWS
b2bc8093 bump version to 1.2.1
e542fc7a update AUTHORS
e0241154 Merge "libwebp/CMake: Add <BUILD_INTERFACE> to webp incl" into main
edea6444 libwebp/CMake: Add <BUILD_INTERFACE> to webp incl
ece18e55 dsp.h: respect --disable-sse2/sse4.1/neon
a89a3230 wicdec: support alpha from WebP WIC decoder
26f4aa01 Merge "alpha_processing: fix visual studio warnings" into main
8f594663 alpha_processing: fix visual studio warnings
46d844e6 Merge "cpu.cmake: fix compiler flag detection w/3.17.0+" into main
298d26ea Merge changes I593adf92,If20675e7,Ifac68eac into main
a1e5dae0 alpha_processing*: use WEBP_RESTRICT qualifier
327ef24f cpu.cmake: fix compiler flag detection w/3.17.0+
f70819de configure: enable libwebpmux by default
dc7e2b42 configure: add informational notices when disabling binaries
9df23ddd configure: move lib flag checks before binaries
a2e18f10 Merge "WebPConfig.config.in: correct WEBP_INCLUDE_DIRS" into main
e1a8d4f3 Merge "bit_reader_inl_utils: uniformly apply WEBP_RESTRICT" into main
4de35f43 rescaler.c: fix alignment
0f13eec7 bit_reader_inl_utils: uniformly apply WEBP_RESTRICT
277d3074 Fix size_t overflow in WebPRescalerInit
97adbba5 WebPConfig.config.in: correct WEBP_INCLUDE_DIRS
b60d4603 advanced_api_fuzzer: add extreme config value coverage
72fe52f6 anim_encode.c,cosmetics: normalize indent
116d235c anim_encode: Fix encoded_frames_[] overflow
6f445b3e CMake: set CMP0072 to NEW
b1cf887f define WEBP_RESTRICT for MSVC
3e265136 Add WEBP_RESTRICT & use it in VP8BitReader
f6d29247 vp8l_dec::ProcessRows: fix int overflow in multiply
de3b4ba8 CMake: add WEBP_BUILD_LIBWEBPMUX
7f09d3d1 CMakeLists.txt: rm libwebpmux dep from anim_{diff,dump}
4edea4a6 Init{RGB,YUV}Rescaler: fix a few more int overflows
c9e26bdb rescaler_utils: set max valid scaled w/h to INT_MAX/2
28d488e6 utils.h: add SizeOverflow()
695bdaa2 Export/EmitRescaledRowsRGBA: fix pointer offset int overflow
685d073e Init{RGB,YUV}Rescaler: fix int overflows in multiplication
d38bd0dd WebPFlipBuffer: fix integer overflow
109ff0f1 utils: allow MALLOC_LIMIT to indicate a max
a2fce867 WebPRescalerImportRowExpand_C: promote some vals before multiply
776983d4 AllocateBuffer: fix int multiplication overflow check
315abbd6 Merge "Revert "Do not use a palette for one color images.""
eae815d0 Merge changes Ica3bbf75,I82f82954
afbca5a1 Require Emscripten 2.0.18
3320416b CMakeLists,emscripten: use EXPORTED_RUNTIME_METHODS
29145ed6 Update README instructions for using Emscripten
1f579139 cosmetics: remove use of 'sanity' / 'master'
29b6129c WebPAnimEncoderNewInternal: remove some unnecessary inits
b60869a1 Revert "Do not use a palette for one color images."
6fb4cddc demux: move padded size calc post unpadded validation
05b72d42 vp8l_enc.c: normalize index types
b6513fba Do not use a palette for one color images.
98bbe35b Fix multi-threading with palettes.
b1674240 Add modified Zeng's method to palette sorting.
88c90c45 add CONTRIBUTING.md
6a9916d7 WebPRescalerInit: add missing int64_t promotion
b6cf52d5 WebPIoInitFromOptions: treat use_scaling as a bool
3b12b7f4 WebPIoInitFromOptions: treat use_cropping as a bool
595fa13f add WebPCheckCropDimensions()
8fdaecb0 Disable cross-color when palette is used.
8933bac2 WebPIoInitFromOptions: respect incoming bypass_filtering val
7d416ff0 webpdec,cosmetics: match error text to function call
ec6cfeb5 Fix typo on WebPPictureAlloc() in README
7e58a1a2 *.cmake: add license header
5651a6b2 cmake: fix .so versioning
25ae67b3 xcframeworkbuild.sh: add arm64 simulator target
5d4ee4c3 cosmetics: remove use of the term 'dummy'
01b38ee1 faster CollectColorXXXTransforms_SSE41
652aa344 Merge "Use BitCtz for FastSLog2Slow_C"
0320e1e3 add the missing default BitsCtz() code
8886f620 Use BitCtz for FastSLog2Slow_C
fae41617 faster CombinedShannonEntropy_SSE2
5bd2704e Introduce the BitCtz() function.
fee64287 Merge "wicdec,icc: treat unsupported op as non-fatal"
33ddb894 lossless_sse{2,41}: remove some unneeded includes
b27ea852 wicdec,icc: treat unsupported op as non-fatal
b78494a9 Merge "Fix undefined signed shift."
e79974cd Fix undefined signed shift.
a8853394 SSE4.1 versions of BGRA to RGB/BGR color-space conversions
a09a6472 SSE4.1 version of TransformColorInverse
401da22b Merge "pngdec: check version before using png_get_chunk_malloc_max"
26907822 pngdec: check version before using png_get_chunk_malloc_max
06c1e72e Code cleanup
8f0d41aa Merge changes Id135bbf4,I99e59797
373eb170 gif2webp: don't store loop-count if there's only 1 frame
759b9d5a cmake: add WEBP_USE_THREAD option
926ce921 cmake: don't install binaries from extras/
9c367bc6 WebPAnimDecoderNewInternal: validate bitstream before alloc
47f64f6e filters_sse2: import Chromium change
cc3577e9 fuzzer/*: use src/ based include paths
004d77ff Merge tag 'v1.2.0'
fedac6cc update ChangeLog (tag: v1.2.0-rc3, tag: v1.2.0)
170a8712 Fix check_c_source_compiles with pthread.
ceddb5fc Fix check_c_source_compiles with pthread.
85995719 disable CombinedShannonEntropy_SSE2 on x86
289757fe TiffDec: enforce stricter mem/dimension limit on tiles
8af7436f Merge "{ios,xcframework}build.sh: make min version(s) more visible" into 1.2.0
e56c3c5b pngdec: raise memory limit if needed
8696147d pngdec: raise memory limit if needed
13b8e9fe {ios,xcframework}build.sh: make min version(s) more visible
a9225410 animdecoder_fuzzer: fix memory leak
d6c2285d update gradle to 6.1.1
8df77fb1 animdecoder_fuzzer: fix memory leak
52ce6333 update NEWS
28c49820 bump version to 1.2.0
7363dff2 webp/encode.h: restore WEBP_ENCODER_ABI_VERSION to v1.1.0
826aafa5 update AUTHORS
63258823 animdecoder_fuzzer: validate canvas size
9eb26381 CMake: remove duplicate "include(GNUInstallDirs)"
2e7bed79 WebPPicture: clarify the ownership of user-owned data.
cccf5e33 webpmux: add an '-set loop <value>' option
c9a3f6a1 Merge changes Ie29f9867,I289c54c4
319f56f1 iosbuild.sh: sync some aspects of xcframeworkbuild.sh
e8e8db98 add xcframeworkbuild.sh
ae545534 dsp.h: allow config.h to override MSVC SIMD autodetection
fef789f3 Merge "cmake: fix per-file assembly flags"
fc14fc03 Have C encoding predictors use decoding predictors.
7656f0b3 README,cosmetics: fix a couple typos
d2e245ea cmake: disable webp.js if WEBP_ENABLE_SIMD=1
96099a79 cmake: fix per-file assembly flags
5abb5582 Merge "cmake: fix compilation w/Xcode generator"
8484a120 cmake: fix compilation w/Xcode generator
d7bf01c9 Merge changes Ifcae0f38,Iee2d7401
36c81ff6 WASM-SIMD: port 2 patches from rreverser@'s tree
988b02ab Merge "Couple of fixes to allow SIMD on Emscripten"
26faf770 wicdec: fail with animated images
ab2d08a8 [cd]webp: document lack of animated webp support
52273943 Couple of fixes to allow SIMD on Emscripten
8870ba7f Fix skia bug #10952
4b3c6953 Detect if StoreFrame read more than anmf_payload_size bytes
17fd4ba8 webp/decode.h,cosmetics: normalize 'flip' comment
411d3677 remove some unreachable break statements
3700ffd7 WebPPictureHasTransparency: remove unreachable return
83604bf3 {animencoder,enc_dec}_fuzzer: convert some abort()s to returns
eb44119c Merge changes I8ae09473,I678c8b1e
9f6055fc fuzz_utils.h: rename max() to Max()
695788e7 fuzz_utils.h: make functions WEBP_INLINE
906c1fcd make ImgIoUtilReadFile use WebPMalloc instead of malloc
8cb7e536 rename demux_api_fuzzer.c -> mux_demux_api_fuzzer.c
443db47d add animdecoder_fuzzer.cc
36a6eea3 Merge "import fuzzers from oss-fuzz/chromium"
ec5f12c1 Makefile.vc: remove deprecated /Gm option
64425a08 picture_tools_enc: fix windows build warning
bd94090a import fuzzers from oss-fuzz/chromium
cf847cba use WEBP_DSP_INIT_FUNC for Init{GammaTables*,GetCoeffs}
55a080e5 Add WebPReplaceTransparentPixels() in dsp
84739717 GetBackgroundColorGIF: promote to uint32_t before << 24
def64e92 cwebp: Fix -print_psnr for near_lossless
cf2f88b3 Add palette and spatial for q >= 75 and -m 5
f0110bae Add no-color cache configuration to the cruncher
749a8b99 Better estimate of the cache cost.
4f9f00cc Use spatial predictors on top of palette no matter what.
7658c686 Add spatial prediction on top of palette in cruncher.
133ff0e3 webp_js: force WASM=0 option explicitly
e3c259a2 Fix integer overflow in EmitFancyRGB.
b3ff0bde man/{gif2,img2}webp,webpmux: normalize some wording
f9b30586 fix ABI breakage introduced by 6a0ff358
1d58dcfc README.webp_js: update note about emscripten version
44070266 README.webp_js: s/fastcomp/upstream/
2565fa8f README.webp_js: update cmake command
47309ef5 webp: WEBP_OFFSET_PTR()
687ab00e DC{4,8,16}_NEON: replace vmovl w/vaddl
1b92fe75 DC16_NEON,aarch64: use vaddlv
53f3d8cf dec_neon,DC8_NEON: use vaddlv instead of movl+vaddv
27d08240 Fix integer overflow in WebPAnimDecoderGetNext()
69776e38 Merge "remove call to MBAnalyzeBestIntra4Mode for method >= 5"
a99078c1 remove call to MBAnalyzeBestIntra4Mode for method >= 5
22e404cc CMakeLists.txt: fix set(CACHE) argument order
71690b52 fix MSVC warning
6a0ff358 Enc: add a qmin / qmax range for quality factor
0fa56f30 Merge tag 'v1.1.0'
6cf504d0 PNM decoding: handle max_value != 255
d7844e97 update ChangeLog (tag: v1.1.0-rc2, tag: v1.1.0)
7f006436 Makefile.vc: fix webp_quality.exe link
cf047e83 Makefile.vc: fix webp_quality.exe link
c074c653 update NEWS
30f09551 bump version to 1.1.0
a76694a1 update AUTHORS
6e3ef7b3 extras: fix WEBP_SWAP_16BIT_CSP check
47178dbd extras: add WebPUnmultiplyARGB() convenience function
22cbae33 idec_dec: fix 0 offset of NULL pointer
290dd0b4 muxread: fix 0 offset of NULL pointer
0df474ac Merge "lossless_(enc_|)sse2: avoid offsetting a NULL pointer"
c6b75a19 lossless_(enc_|)sse2: avoid offsetting a NULL pointer
295e5e38 fix UBSAN warning
e2575e05 DC8_NEON,aarch64: use vaddv
b0e09e34 dec_neon: Fix build failure under some toolchains
cf0e903c dsp/lossless: Fix non gcc ARM builds
bb7bc40b Remove ubsan errors.
78881b76 CMake: fix GLUT library link
9f750f7a cmake: fix BUILD_SHARED_LIBS build on mac
17850e74 libwebp: Remove char-subscripts warning in pnmdec.c
2fa2552d Merge "Expose WebPMalloc() in addition to WebPFree()"
a4df4aae Expose WebPMalloc() in addition to WebPFree()
853ea3d8 imageio/tiff: Return error before allocating bad tile size
af650c0b Fix a Wxor-used-as-pow false positive
601ef17c libwebp.py: update to swig 3.0.12
0e48d889 bugfix: last alpha rows were incorrectly decoded
24d2ccb4 webp: Fix imageio ReadPNM() TUPLTYPE
fab8f9cf cosmetics: normalize '*' association
94138e0e update .gitignore
0fe1a89d update ChangeLog (tag: v1.0.3-rc1, tag: v1.0.3)
2ad0916d update NEWS
1287362b bump version to 1.0.3
7b968cc2 update AUTHORS
9d6988f4 Fix the oscillating prediction problem at low quality
312f74d0 makefile.unix: allow *_LIBS to be overridden w/EXTRA_LIBS
92dbf237 filters_sse2,cosmetics: shorten some long lines
a277d197 filters_sse2.c: quiet integer sanitizer warnings
804540f1 Fix cpufeatures in CMake.
bf00c15b Add CMake option for bittrace.
a788b498 filters_sse2.c: quiet integer sanitizer warnings
e6a92c5e filters.c: quiet integer sanitizer warnings
ec1cc40a lossless.c: remove U32 -> S8 conversion warnings
1106478f remove conversion U32 -> S8 warnings
812a6b49 lossless_enc: fix some conversion warning
4627c1c9 lossless_enc,TransformColorBlue: quiet uint32_t conv warning
c84673a6 lossless_enc_sse{2,41}: quiet signed conv warnings
776a7757 dec_sse2: quiet signed conv warnings
bd39c063 Merge "thread_utils: release mutex before signaling"
0550576f Merge "(alpha_processing,enc}_sse2: quiet signed conv warnings"
6682f2c4 thread_utils: release mutex before signaling
e78dea75 (alpha_processing,enc}_sse2: quiet signed conv warnings
9acf18ba iosbuild.sh: add WebP{Demux,Mux}.framework
b9be7e65 vwebp: remove the -fit option (and make it default)
1394a2bb Merge "README.webp_js: update Emscripten.cmake note"
dd3e7f8a README.webp_js: update Emscripten.cmake note
32cf8801 predictor_enc,GetBestGreenRedToBlue: quiet implicit conv warnings
e1c8acb5 Merge "vwebp: add a -fit option"
cbd23dd5 vwebp: add a -fit option
2e672351 bit_writer_utils,Flush: quiet implicit conversion warnings
1326988d swig: update libwebp_python_wrap.c
0e7f8548 update generated swig files
17ed1438 Merge "PutLE{16,24}: quiet implicit conversion warnings"
24686538 PutLE{16,24}: quiet implicit conversion warnings
153bb3a0 fix some clang-7 warnings:
ab2dc893 Rescaler: fix rounding error
aa65f89a HistogramCombineStochastic: fix free of uninit value
af0bac64 Merge "encode.h: mention 'exact' default in WebPEncodeLossless*"
6d2e11ec encode.h: mention 'exact' default in WebPEncodeLossless*
8c3f04fe AndroidCPUInfo: reorder terms in conditional
fcfd9c71 BitTrace: if BITTRACE is > 0, record and print syntax bits used
067031ea Speedups for unused Huffman groups.
01ac46ba libwebp: Display "libjpeg error:" in imageio/jpegdec
d9a662e1 WebPRescalerGetScaledDimensions: round scaled dimension up
62eb3f08 libwebp: Fix missing '{' in README
e05f785a Merge "unicode,INIT_WARGV: add missing cast"
63c9a69f tag the VP8LHashPix() function for potential uint roll-over
2b7214ab unicode,INIT_WARGV: add missing cast
bf424b46 tag the GetPixPairHash64() function for potential uint roll-over
7d05d6ca Have the color cache computation be u32-bit only.
6bcf8769 Remove BINARYEN_METHOD in wasm settings.
2b98df90 update ChangeLog (tag: v1.0.2-rc1, tag: v1.0.2)
61e372b7 update NEWS
7ae658a0 bump version to 1.0.2
51c4907d update AUTHORS
666bd6c6 man/cwebp.1: refine near-lossless text
561cdce5 Clarify the doc about GetFeatures.
aec2cf02 near_lossless: fix fuzzing-detected integer overflow
928a75de webp: Fix VP8LBitWriterClone() bug
5173d4ee neon IsFlat
5b081219 IsFlat: inline when possible
381b7b54 IsFlat: use int for thresh
6ed15ea1 fix unprobable leak in webp_sdl.c
22bbb24e Merge "IsFlat: return int"
8b3fb238 Merge tag 'v1.0.1'
f435de95 IsFlat: return int
41521aed utils.h: only define WEBP_NEED_LOG_TABLE_8BIT when needed
9f4d4a3f neon: GetResidualCost
0fd7514b neon: SetResidualCoeffs
f95a996c Simpler histogram clustering.
e85d3313 update ChangeLog (tag: v1.0.1-rc2, tag: v1.0.1)
fa8210e4 Fix pair update in stochastic entropy merging.
fd198f73 add codereview.settings
825389ac README.mux: add a reference to the AnimDecoder API
3be698c3 CMake: fix webp_js compilation
485ff86f Fix pair update in stochastic entropy merging.
4cd0582d CMake: fix webp_js compilation
4cbb4caf update NEWS
f5a5918d bump version to 1.0.1
d61385db Speed-up: Make sure we only initialize histograms when needed.
6752904b Speed-up: Make sure we only initialize histograms when needed.
0c570316 update AUTHORS
301a2dda img2webp: add help note about arguments from a file
f0abab92 Speedups for empty histograms.
f2dfd925 Split HistogramAdd to only have the high level logic in C.
06b7bc7d Fix compilation on windows and clang-cl+ninja.
b6284d82 img2webp: add help note about arguments from a file
decf6f6b Speedups for empty histograms.
dea3e899 Split HistogramAdd to only have the high level logic in C.
632798ae Merge "Fix compilation on windows and clang-cl+ninja."
dc1a9518 Merge "libwebp: Unicode command tools on Windows"
9cf9841b libwebp: Unicode command tools on Windows
98179495 remove some minor TODOs
a376e7b9 Fix compilation on windows and clang-cl+ninja.
cbf82cc0 Remove AVX2 files.
5030e902 Merge "TIFF decoder: remove unused KINV definition"
ac543311 Remove a few more useless #defines
123d3306 TIFF decoder: remove unused KINV definition
ef1094b0 Merge "- install pkg-config files during the CMake build"
b911fbc9 libwebp: Remove duplicate GIFDisplayError in anim_util
eee00b66 - install pkg-config files during the CMake build
ac3ec8c9 Merge "Clean-up the common sources in dsp."
3e13da7b Clean-up the common sources in dsp.
5c395f1d libwebp: cmake-format all
e7a69729 libwebp: Add extras targets in CMakeLists.txt
e52485d6 libwebp: Rename macros in webpmux.c
92dc0f09 clean-up MakeInputImageCopy()
39952de2 VP8IteratorImport: add missing 'const'
382af7a2 clean-up WebPBlendAlpha
14d020f6 libwebp: Use ExUtilGet*() in anim_diff
0d92ff25 libwebp: remove useless variable in gif2webp
556cb1b4 Merge "CMake: Set WEBP_BUILD_GIF2WEBP to off"
da26ee49 CMake: Set WEBP_BUILD_GIF2WEBP to off
b2a867c0 cwebp: Don't premultiply during -resize if -exact
637141bc pngdec: fix build w/libpng < 1.4.x
bc5092b1 pngdec: set memory functions
50d8345a Fix CMake math library.
6aa3e8aa Fix math library on Visual Studio.
d71df4e2 Fix math library finding in CMake.
de08d727 cosmetics: normalize include guard comment
009562b4 vwebp: Fix bug when Dispose then NoBlend frames
423f2579 Fix up CMake to create targets.
907208f9 Wait for all threads to be done in DecodeRemaining.
4649b3c4 vwebp: Add background color display option
78ad57a3 Fix bad glClearColor parameters
da96d8d9 Allow for a non-initialized alpha decompressor in DoRemap.
2563db47 fix rescaling rounding inaccuracy
211f37ee fix endian problems in pattern copy
5f0f5c07 Make sure partition #0 is read before VP8 data in IDecode.
de98732b fix GetColorf() bug
4338cd36 misc fixes in libwebpmux
e00af13e fix signatures after a9ceda7ff1
a9ceda7f Speed-up chunk list operations.
2281bbf6 Merge "Better handling of bogus Huffman codes."
39cb9aad Better handling of bogus Huffman codes.
89cc9d37 Merge "fix read-overflow while parsing VP8X chunk"
95fd6507 fix read-overflow while parsing VP8X chunk
9e729fe1 Fix VP8IoTeardownHook being called twice on worker sync failure
29fb8562 Merge "muxread,anmf: fail on multiple image chunks"
eb82ce76 muxread,anmf: fail on multiple image chunks
1344a2e9 fix alpha-filtering crash when image width is larger than radius
be738c6d muxread,ChunkVerifyAndAssign: validate chunk_size
2c70ad76 muxread,CreateInternal: fix riff size checks
569001f1 Fix for thread race heap-use-after-free
c56a02d9 Android.mk: use LOCAL_EXPORT_C_INCLUDES w/public libs
15795596 CMakeLists.txt,cosmetics: normalize if() formatting
1a44c233 Merge "cmake: add support for webpmux"
e9569ad7 Merge "configure,*am,cosmetics: s/WANT_/BUILD_/"
35c7de6f cmake: add support for webpmux
0f25e61c WebpToSDL(): fix the return value in case of error
5d8985de configure,*am,cosmetics: s/WANT_/BUILD_/
895fd28f Merge "man/Makefile.am: add img2webp.1"
5cf3e2af man/Makefile.am: add img2webp.1
2a9de5b9 Add build rules for anim_diff & anim_dump utils.
71ed73cf fix invalid check for buffer size
af0e4fbb gif2webp: fix transcode of loop count=65535
dce5d764 Limit memory allocation when reading invalid Huffman codes.
f9df0081 Merge "cmake: quiet glut deprecation warnings on OS X"
dc39b16f webpmux.1: correct grammar
c7aa1264 cwebp.c: fix a missing \n
53aa51e9 Merge tag 'v1.0.0'
698b8844 update ChangeLog (tag: v1.0.0)
8d510751 webp-container-spec: correct frame duration=0 note
e6b2164e vwebp: Copy Chrome's behavior w/frame duration == 0
094b3b28 cmake: quiet glut deprecation warnings on OS X
71c39a06 webp-container-spec: correct frame duration=0 note
fd3d5756 vwebp: Copy Chrome's behavior w/frame duration == 0
b0c966fb Build vwebp from CMake.
d20b7707 update ChangeLog (tag: v1.0.0-rc3)
0d5fad46 add WEBP_DSP_INIT / WEBP_DSP_INIT_FUNC
d77bf512 add WEBP_DSP_INIT / WEBP_DSP_INIT_FUNC
c1cb86af fix 16b overflow in SSE2
e577feb7 makefile.unix: add DEBUG flag for compiling w/ debug-symbol
99be34b3 cwebp,get_disto: fix bpp output
e122e511 cwebp,get_disto: fix bpp output
f5565ca8 cmake: Make sure we use near-lossless by default.
d898dc14 fix bug in WebPImport565: alpha value was not set
1c8f358d Fix CMake with WASM.
a0215fb7 webp_js: fix webp_js demo html
882784b0 update ChangeLog (tag: v1.0.0-rc2)
2f930e08 Revert "Use proper targets for CMake."
8165e8fb Use proper targets for CMake.
3f157dd5 Remove some very hard TODOs.
abb47760 Merge "Use proper targets for CMake."
cd758a17 {de,}mux/Makefile.am: add missing headers
e155dda0 Use proper targets for CMake.
b892b8ba makefile.unix,dist: use ascii for text output
64a57d05 add -version option to anim_dump,anim_diff and img2webp
994be82d Merge "Remove some very hard TODOs."
4033e1d7 Remove some very hard TODOs.
fc1b8e3a webp_js: fix webp_js demo html
15aa48d9 update ChangeLog (tag: v1.0.0-rc1)
e607dabc update AUTHORS
38410c08 [CFI] Remove function pointer casts
978eec25 [CFI] Remove function pointer casts
c57b2736 bump version to 1.0.0
cba28853 update NEWS
c909d531 Merge "remove some deprecation warning on MacOSX"
217443c7 remove some deprecation warning on MacOSX
b672bdfa configure: quiet glut deprecation warnings on OS X
daa9fcaf configure: use sdl-config if available
dd174cae Merge "imagedec: support metadata reading for WebP image decoding"
641cedcc imagedec: support metadata reading for WebP image decoding
065b2ce1 anim_diff: add a couple missing newlines in Help()
c4cc1147 Merge "gif2webp: force low duration frames to 100ms"
09333097 gif2webp: force low duration frames to 100ms
e03f0ec3 sharp_yuv: use 14b fixed-point precision for gamma
b2db361c image_enc,WebPWritePNG: move locals after setjmp
74e82ec6 Merge "WebPPictureDistortion: fix big-endian results order"
645d04ca Merge "cwebp,get_disto: report bpp"
120f58c3 Merge "lossless*sse2: improve non-const 16-bit vector creation"
a7fe9412 WebPPictureDistortion: fix big-endian results order
e26fe066 cwebp,get_disto: report bpp
9df64e28 Merge changes Id5b4a1a4,Ia20ce844
8043504f lossless*sse2: improve non-const 16-bit vector creation
1e3dfc48 Import: extract condition from loop
3b07d327 Import,RGBA: fix for BigEndian import
551948e4 Remove unused argument in VP8LBitsEntropy.
3005237a ReadWebP: fix for big-endian
499c395a Merge "anim_diff: expose the -max_diff option"
f69dcd69 Merge "remove WEBP_EXPERIMENTAL_FEATURES"
07d884d5 anim_diff: expose the -max_diff option
f4dd9256 remove WEBP_EXPERIMENTAL_FEATURES
94a8377b extract the command-line parsing helpers to example_util
fc09e6e2 PNM decoder: prevent unsupported depth=2 PAM case.
6de58603 MIPS64: Fix defined-but-not-used errors with WEBP_REDUCE_CSP
cbde5728 gif2webp: add support for reading from stdin
cf1c5054 Add an SSE4 version of some lossless color transforms.
45a8b5eb Fix lint error with man page.
cff38e8f Merge "PNG decoder: handle gAMA chunk"
59cb1a48 Merge "enable dc error-diffusion always"
78318b30 PNG decoder: handle gAMA chunk
664c21dd Merge "remove some TODOs"
815652de enable dc error-diffusion always
aec45cec remove some TODOs
5715dfce fix block-count[] increment in case of large image
c2d04f3e enable DC error-diffusion always for multi-pass
96bf07c5 use DC error diffusion for U/V at low-quality
1c59020b fix missing sse41 targets in makefile.unix
7a8e814b cosmetics: s/color_space/colorspace/
05f6fe24 upsampling: rm asserts w/REDUCE_CSP+OMIT_C_CODE
b4cf5597 Merge "Upsampling SSE2/SSE4 speedup."
ccbeb32c Makefile.vc: add missing sse41 files
55403a9a Upsampling SSE2/SSE4 speedup.
807b53c4 Implement the upsampling/yuv functions in SSE41
84101a81 Fix wasm WebP compilation
8bebd2a3 fix warning on MSVC
a7f93fe3 webpmux: allow reading argument from a file
b69f18a7 gif2webp.1: fix -loop_compatibility layout
72d530c0 Merge "fix lossless decoding w/WEBP_REDUCE_SIZE"
296c7dc4 fix lossless decoding w/WEBP_REDUCE_SIZE
0d5d029c Merge "ImgIoUtilReadFile: fix file leak upon error"
ae568ce7 ImgIoUtilReadFile: fix file leak upon error
796b5a8a Merge tag 'v0.6.1'
6b7a95fd update ChangeLog (tag: v0.6.1)
f66955de WEBP_REDUCE_CSP: restrict colorspace support
1af0df76 Merge "WEBP_REDUCE_CSP: restrict colorspace support"
6de20df0 WEBP_REDUCE_CSP: restrict colorspace support
a289d8e7 update ChangeLog (tag: v0.6.1-rc2)
c10a493c vwebp: disable double buffering on windows & mac
0d4466c2 webp_to_sdl.c: fix file mode
1b27bf8b WEBP_REDUCE_SIZE: disable all rescaler code
126be109 webpinfo: add -version option
0df22b9e WEBP_REDUCE_SIZE: disable all rescaler code
9add62b5 bump version to 0.6.1
d3e26144 update NEWS
2edda639 README: add webpinfo section
9ca568ef Merge "right-size some tables"
31f1995c Merge "SSE2 implementation of HasAlphaXXX"
a80c46bd SSE2 implementation of HasAlphaXXX
083507f2 right-size some tables
2e5785b2 anim_utils.c: remove warning when !defined(WEBP_HAVE_GIF)
b299c47e add WEBP_REDUCE_SIZE
f593d71a enc: disable pic->stats/extra_info w/WEBP_DISABLE_STATS
541179a9 Merge "predictor_enc: fix build w/--disable-near-lossless"
5755a7ec predictor_enc: fix build w/--disable-near-lossless
eab5bab7 add WEBP_DISABLE_STATS
8052c585 remove some petty TODOs from vwebp.
c245343d move LOAD8x4 and STORE8x2 closer to their use location
b9e734fd dec,cosmetics: normalize function naming style
c188d546 dec: harmonize function suffixes
28c5ac81 dec_sse41: harmonize function suffixes
e65b72a3 Merge "introduce WebPHasAlpha8b and WebPHasAlpha32b"
b94cee98 dec_sse2: remove HE8uv_SSE2
44a0ee3f introduce WebPHasAlpha8b and WebPHasAlpha32b
aebf59ac Merge "WebPPictureAllocARGB: align argb allocation"
c184665e WebPPictureAllocARGB: align argb allocation
3daf7509 WebPParseHeaders: remove obsolete animation TODO
80285d97 cmake: avoid security warnings under msvc
650eac55 cmake: don't set -Wall with MSVC
c462cd00 Remove useless code.
01a98217 Merge "remove WebPWorkerImpl declaration from the header"
3c49fc47 Merge "thread_utils: fix potentially bad call to Execute"
fde2782e thread_utils: fix potentially bad call to Execute
2a270c1d remove WebPWorkerImpl declaration from the header
f1f437cc remove mention of 'lossy-only parameters' from the doc
3879074d Merge "WebPMemToUint32: remove ptr cast to int"
04b029d2 WebPMemToUint32: remove ptr cast to int
b7971d0e dsp: avoid defining _C functions w/NEON builds
6ba98764 webpdec: correct alloc size check w/use_argb
5cfb3b0f normalize include guards
f433205e Merge changes Ia17c7dfc,I75423abb,Ia2f716b4,I161caa14,I4210081a, ...
8d033b14 {dec,enc}_neon: harmonize function suffixes x2
0295e981 upsampling_neon: harmonize function suffixes
d572c4e5 yuv_neon: harmonize function suffixes
ab9c2500 rescaler_neon: harmonize function suffixes
93e0ce27 lossless_neon: harmonize function suffixes
22fbc50e lossless_enc_neon: harmonize function suffixes
447875b4 filters_neon,cosmetics: fix indent
e51bdd43 remove unused VP8TokenToStats() function
785da7ea enc_neon: harmonize function suffixes
bc1a251f dec_neon: harmonize function suffixes
61e535f1 dsp/lossless: workaround gcc-4.8 bug on arm
68b2eab7 cwebp: fix alpha reporting w/lossless & metadata
30042faa WebPDemuxGetI: add doc details around WebPFormatFeature
0a17f471 Merge "WIP: list includes as descendants of the project dir"
a4399721 WIP: list includes as descendants of the project dir
08275708 Merge "Make sure we reach the full range for alpha blending."
d361a6a7 yuv_sse2: harmonize function suffixes
6921aa6f upsampling_sse2: harmonize function suffixes
08c67d3e ssim_sse2: harmonize function suffixes
582a1b57 rescaler_sse2: harmonize function suffixes
2c1b18ba lossless_sse2: harmonize function suffixes
0ac46e81 lossless_enc_sse2: harmonize function suffixes
bc634d57 enc_sse2: harmonize function suffixes
bcb7347c dec_sse2: harmonize function suffixes
e14ad93c Make sure we reach the full range for alpha blending.
7038ca8d demux,StoreFrame: restore hdr size check to min req
fb3daad6 cpu: fix ssse3 check
be590e06 Merge "Fix CMake redefinition for HAVE_CPU_FEATURES_H"
35f736e1 Fix CMake redefinition for HAVE_CPU_FEATURES_H
a5216efc Fix integer overflow warning.
a9c8916b decode.h,WebPIDecGetRGB: clarify output ptr validity
3c74c645 gif2webp: handle 1-frame case properly + fix anim_diff
c7f295d3 Merge "gif2webp: introduce -loop_compatibility option"
b4e04677 gif2webp: introduce -loop_compatibility option
f78da3de add LOCAL_CLANG_PREREQ and avoid WORK_AROUND_GCC w/3.8+
01c426f1 define WEBP_USE_INTRINSICS w/gcc-4.9+
8635973d use sdl-config (if available) to determine the link flags
e9459382 use CPPFLAGS before CFLAGS
4a9d788e Merge "Android.mk,mips: fix clang build with r15"
4fbdc9fb Android.mk,mips: fix clang build with r15
a80fcc4a ifdef code not used by Chrome/Android.
3993af12 Fix signed integer overflows.
f66f94ef anim_dump: small tool to dump frames from animated WebP
6eba857b Merge "rationalize the Makefile.am"
c5e34fba function definition cleanup
3822762a rationalize the Makefile.am
501ef6e4 configure style fix: animdiff -> anim_diff
f8bdc268 Merge "protect against NULL dump_folder[] value in ReadAnimatedImage()"
23bfc652 protect against NULL dump_folder[] value in ReadAnimatedImage()
8dc3d71b cosmetics,ReadAnimatedWebP: correct function comment
5bd40066 Merge changes I66a64a0a,I4d2e520f
7945575c cosmetics,webpinfo: remove an else after a return
8729fa11 cosmetics,cwebp: remove an else after a return
f324b7f9 cosmetics: normalize fn proto & decl param names
869eb369 CMake cleanups.
289e62a3 Remove declaration of unimplemented VP8ApplyNearLosslessPredict
20a94186 pnmdec,PAM: validate depth before calculating bytes_per_px
34130afe anim_encode: fix integer overflow
42c79aa6 Merge "Encoder: harmonize function suffixes"
b09307dc Encoder: harmonize function suffixes
bed0456d Merge "SSIM: harmonize the function suffix"
54f6a3cf lossless_sse2.c: fix some missed suffix changes
088f1dcc SSIM: harmonize the function suffix
86fc4dd9 webpdec: use ImgIoUtilCheckSizeArgumentsOverflow
08ea9ecd imageio: add ability restrict max image size
6f9daa4a jpegdec,ReadError: fix leaks on error
a0f72a4f VP8LTransformColorFunc: drop an non-respected 'const' from the signature.
8c934902 Merge "Lossess dec: harmonize the function suffixes"
622242aa Lossess dec: harmonize the function suffixes
1411f027 Lossless Enc: harmonize the function suffixes
24ad2e3c add const to two variables
46efe062 Merge "Allow the lossless cruncher to work for alpha."
8c3f9a47 Speed-up LZ77.
1aef4c71 Allow the lossless cruncher to work for alpha.
b8821dbd Improve the box LZ77 speed.
7beed280 add missing ()s to macro parameters
6473d20b Merge "fix Android standalone toolchain build"
dcefed95 Merge "build.gradle: fix arm64 build"
0c83a8bc Merge "yuv: harmonize suffix naming"
c6d1db4b fix Android standalone toolchain build
663a6d9d unify the ALTERNATE_CODE flag usage
73ea9f27 yuv: harmonize suffix naming
c71b68ac build.gradle: fix arm64 build
c4568b47 Rescaler: harmonize the suffix naming
6cb13b05 Merge "alpha_processing: harmonize the naming suffixes to be _C()"
83a3e69a Merge "simplify WEBP_EXTERN macro"
7295fde2 Merge "filters: harmonize the suffixes naming to _SSE2(), _C(), etc."
8e42ba4c simplify WEBP_EXTERN macro
331ab34b cost*.c: harmonize the suffix namings
b161f670 filters: harmonize the suffixes naming to _SSE2(), _C(), etc.
dec5e4d3 alpha_processing: harmonize the naming suffixes to be _C()
6878d427 fix memory leak in SDL_Init()
461ae555 Merge "configure: fix warnings in sdl check"
62486a22 configure: test for -Wundef
92982609 dsp.h: fix -Wundef w/__mips_dsp_rev
0265cede configure: fix warnings in sdl check
88c73d8a backward_references_enc.h: fix WINDOW_SIZE_BITS check
4ea49f6b rescaler_sse2.c: fix WEBP_RESCALER_FIX -> _RFIX typo
1b526638 Clean-up some CMake
87f57a4b Merge "cmake: fix gif lib detection when cross compiling"
b34a9db1 cosmetics,dec_sse2: remove some redundant comments
471c5755 cmake: fix gif lib detection when cross compiling
c793417a cmake: disable gif2webp if gif lib isn't found
dcbc1c88 cmake: split gif detection from IMG deps
66ad84f0 Merge "muxread: remove unreachable code"
50ec3ab7 muxread: remove unreachable code
7d67a164 Lossy encoding: smoothen transparent areas to improve compression
e50650c7 Merge "fix signature for DISABLE_TOKEN_BUFFER compilation"
671d2567 fix signature for DISABLE_TOKEN_BUFFER compilation
d6755580 cpu.cmake: use unique flag to test simd disable flags
28914528 Merge "Remove the argb* files."
8acb4942 Remove the argb* files.
3b62347b README: correct cmake invocation note
7ca0df13 Have the SSE2 version of PackARGB use common code.
7b250459 Merge "Re-use the transformed image when trying several LZ77 in lossless."
e132072f Re-use the transformed image when trying several LZ77 in lossless.
5d7a50ef Get code to compile in C++.
7b012987 configure: test for -Wparentheses-equality
f0569adb Fix man pages for multi-threading.
f1d5a397 multithread cruncher: only copy stats when picture->stats != NULL
f8c2ac15 Multi-thread the lossless cruncher.
a88c6522 Merge "Integrate a new LZ77 looking for matches in the neighborhood of a pixel only."
8f6df1d0 Unroll Predictors 10, 11 and 12.
355c3d1b Integrate a new LZ77 looking for matches in the neighborhood of a pixel only.
a1779a01 Refactor LZ77 handling in preparation for a new method.
67de68b5 Android.mk/build.gradle: fix mips build with clang from r14b
f209a548 Use the plane code and not the distance when computing statistics.
b903b80c Split cost-based backward references in its own file.
498cad34 Cosmetic changes in backward reference.
e4eb4587 lossless, VP8LTransformColor_C: make sure no overflow happens with colors.
af6deaff webpinfo: handle alpha flag mismatch
7caef29b Fix typo that creeped in.
39e19f92 Merge "near lossless: fix unsigned int overflow warnings."
9bbc0891 near lossless: fix unsigned int overflow warnings.
e1118d62 Merge "cosmetics,FindClosestDiscretized: use uint in mask creation"
186bc9b7 Merge "webpinfo: tolerate ALPH+VP8L"
b5887297 cosmetics,FindClosestDiscretized: use uint in mask creation
f1784aee near_lossless,FindClosestDiscretized: use unsigned ops
0d20abb3 webpinfo: tolerate ALPH+VP8L
972104b3 webpmux: tolerate false positive Alpha flag
dd7e83cc tiffdec,ReadTIFF: ensure data_size is < tsize_t max
d988eb7b tiffdec,MyRead: quiet -Wshorten-64-to-32 warning
dabda707 webpinfo: add support to parse Alpha bitstream
4c117643 webpinfo: correct background color output, BGRA->ARGB
defc98d7 Doc: clarify the role of quality in WebPConfig.
d78ff780 Merge "Fix code to compile with C++."
c8f14093 Fix code to compile with C++.
497dc6a7 pnmdec: sanitize invalid header output
d78e5867 Merge "configure: test for -Wconstant-conversion"
481e91eb Merge "pnmdec,PAM: set bytes_per_px based on depth when missing"
93b12753 configure: test for -Wconstant-conversion
645f0c53 pnmdec,PAM: set bytes_per_px based on depth when missing
e9154605 Merge "vwebp: activate GLUT double-buffering"
818d795b vwebp: activate GLUT double-buffering
d63e6f4b Add a man page for webpinfo
4d708435 Merge "NEON: implement ConvertRGB24ToY/BGR24/ARGB/RGBA32ToUV/ARGBToUV"
faf42213 NEON: implement ConvertRGB24ToY/BGR24/ARGB/RGBA32ToUV/ARGBToUV
b4d576fa Install man pages with CMake.
cbc1b921 webpinfo: add features to parse bitstream header
e644c556 Fix bad bit writer initialization.
b62cdad2 Merge "Implement a cruncher for lossless at method 6."
da3e4dfb use the exact constant for the gamma transfer function
a9c701e0 Merge "tiffdec: fix EXTRASAMPLES check"
adab8ce0 Implement a cruncher for lossless at method 6.
1b92b237 Merge "Fix VP8ApplyNearLossless to respect const and stride."
1923ff02 tiffdec: fix EXTRASAMPLES check
97cce5ba tiffdec: only request EXTRASAMPLES w/> 3 samples/px
0dcd85b6 Fix VP8ApplyNearLossless to respect const and stride.
f7682189 yuv: rationalize the C/SSE2 function naming
52245424 NEON implementation of some Sharp-YUV420 functions
690efd82 Avoid several backward reference copies.
4bb1f607 src/dec/vp8_dec.h, cosmetics: fix comments
285748be cmake: build/install webpinfo
78fd199c backward_references_enc.c: clear -Wshadow warnings
ae836410 WebPLog2FloorC: clear -Wshadow warning
d0b7404e Merge "WASM support"
134e314f WASM support
c08adb6f Merge "VP8LEnc: remove use of BitsLog2Ceiling()"
28c37ebd VP8LEnc: remove use of BitsLog2Ceiling()
2cb58ab2 webpinfo: output format as a human readable string
bb175a93 Merge "rename some symbols clashing with MSVC headers"
39eda658 Remove a duplicated pixel hash implementation.
36b8274d rename some symbols clashing with MSVC headers
274daf54 Add webpinfo tool.
ec5036e4 add explicit reference to /usr/local/{lib,inc}
18f0dfac Merge "fix TIFF encoder regarding rgbA/RGBA"
4e2b0b50 Merge "webpdec.h: fix a doc typo"
e2eeabff Merge "Install binaries, libraries and headers in CMake."
836607e6 webpdec.h: fix a doc typo
9273e441 fix TIFF encoder regarding rgbA/RGBA
17e3c11f Add limited PAM decoding support
5f624871 Install binaries, libraries and headers in CMake.
976adac1 Merge "lossless incremental decoding: fix missing eos_ test"
f8fad4fa lossless incremental decoding: fix missing eos_ test
27415d41 Merge "vwebp_sdl: fix the makefile.unix"
49566182 Merge "ImgIoUtilWriteFile(): use ImgIoUtilSetBinaryMode"
6f75a51b Analyze the transform entropy on the whole image.
a5e4e3af Use palette only if we can in entropy analysis.
75a9c3c4 Improve compression by better entropy analysis.
39cf6f4f vwebp_sdl: fix the makefile.unix
699b0416 ImgIoUtilWriteFile(): use ImgIoUtilSetBinaryMode
7d985bd1 Fix small entropy analysis bug.
6e7caf06 Optimize the color cache size.
833c9219 More efficient stochastic histogram merge.
5183326b Refactor the greedy histogram merge.
99f6f462 Merge "histogram_enc.c,MyRand: s/ul/u/ for unsigned constants"
80a22186 ssim.c: remove dead include
a128dfff histogram_enc.c,MyRand: s/ul/u/ for unsigned constants
693bf74e move the SSIM calculation code in ssim.c / ssim_sse2.c
10d791ca Merge "Fix the random generator in HistogramCombineStochastic."
fa63a966 Fix the random generator in HistogramCombineStochastic.
16be192f VP8LSetBitPos: remove the eos_ setting
027151ca don't erase the surface before blitting.
4105d565 disable WEBP_USE_XXX optimisations when EMSCRIPTEN is defined
9ee32a75 Merge "WebP-JS: emscripten-based Javascript decoder"
ca9f7b7d WebP-JS: emscripten-based Javascript decoder
868aa690 Perform greedy histogram merge in a unified way.
5b393f2d Merge "fix path typo for vwebp_sdl in Makefile.vc"
e0012bea CMake: only use libwebpdecoder for building dwebp
84c2a7b0 fix path typo for vwebp_sdl in Makefile.vc
1b0e4abf Merge "Add a flag to disable SIMD optimizations."
32263250 Add a flag to disable SIMD optimizations.
b494fdec optimize the ARGB->ARGB Import to use memcpy
f1536039 Merge "ReadWebP: decode directly into a pre-allocated buffer"
e69ed291 ReadWebP: decode directly into a pre-allocated buffer
57d8de8a Merge "vwebp_sdl: simple viewer based on SDL"
5cfd4ebc LZ77 interval speedups. Faster, smaller, simpler.
1e7ad88b PNM header decoder: add some basic numerical validation
17c7890c Merge "Add a decoder only library for WebP in CMake."
be733786 Merge "Add clang build fix for MSA"
03cda0e4 Add a decoder only library for WebP in CMake.
aa893914 Add clang build fix for MSA
31a92e97 Merge "imageio: add limited PNM support for reading"
dcf9d82a imageio: add limited PNM support for reading
6524fcd6 vwebp_sdl: simple viewer based on SDL
6cf24a24 get_disto: fix reference file read
43d472aa Merge tag 'v0.6.0'
50d1a848 update ChangeLog (tag: v0.6.0, origin/0.6.0)
20a7fea0 extras/Makefile.am: fix libwebpextras.la reference
415f3ffe update ChangeLog (tag: v0.6.0-rc3)
3c6d1224 update NEWS
ee4a4141 update AUTHORS
32ed856f Fix "all|no frames are keyframes" settings.
1c3190b6 Merge "Fix "all|no frames are keyframes" settings."
f4dc56fd disable GradientUnfilter_NEON
4f3e3bbd disable GradientUnfilter_NEON
2dc0bdca Fix "all|no frames are keyframes" settings.
0d8e0588 img2webp: treat -loop as a no-op w/single images
b0450139 ReadImage(): restore size reporting
0ad3b4ef update ChangeLog (tag: v0.6.0-rc2)
@ -71,7 +993,7 @@ b016cb91 NEON: faster fancy upsampling
f04eb376 Merge tag 'v0.5.2'
341d711c NEON: 5% faster conversion to RGB565 and RGBA4444
abb54827 remove Clang warnings with unused arch arguments.
ece9684f update ChangeLog (tag: v0.5.2-rc2, tag: v0.5.2, origin/0.5.2, 0.5.2)
ece9684f update ChangeLog (tag: v0.5.2-rc2, tag: v0.5.2, origin/0.5.2)
aa7744ca anim_util: quiet implicit conv warnings in 32-bit
d9120271 jpegdec: correct ContextFill signature
24eb3940 Remove some errors when compiling the code as C++.
@ -358,7 +1280,7 @@ bbb6ecd9 Merge "Add MSA optimized distortion functions"
c0991a14 io,EmitRescaledAlphaYUV: factor out a common expr
48bf5ed1 build.gradle: remove tab
bfef6c9f Merge tag 'v0.5.1'
3d97bb75 update ChangeLog (tag: v0.5.1, origin/0.5.1, 0.5.1)
3d97bb75 update ChangeLog (tag: v0.5.1, origin/0.5.1)
deb54d91 Clarify the expected 'config' lifespan in WebPIDecode()
435308e0 Add MSA optimized encoder transform functions
dce64bfa Add MSA optimized alpha filter functions
@ -552,7 +1474,7 @@ b74657fb configure: fix builtin detection w/-Werror
6c1d7631 avoid Yoda style for comparison
8ce975ac SSE optimization for vector mismatch.
7db53831 Merge tag 'v0.5.0'
37f04949 update ChangeLog (tag: v0.5.0-rc1, tag: v0.5.0, origin/0.5.0, 0.5.0)
37f04949 update ChangeLog (tag: v0.5.0-rc1, tag: v0.5.0, origin/0.5.0)
7e7b6ccc faster rgb565/rgb4444/argb output
4c7f565f update NEWS
1f62b6b2 update AUTHORS
@ -1336,7 +2258,7 @@ b5a36cc9 add -near_lossless [0..100] experimental option
0524d9e5 dsp: detect mips64 & disable mips32 code
d3485d96 cwebp.1: fix quality description placement
29a9fe22 Merge tag 'v0.4.1'
8af27718 update ChangeLog (tag: v0.4.1, origin/0.4.1, 0.4.1)
8af27718 update ChangeLog (tag: v0.4.1, origin/0.4.1)
e09e9ff6 Record & log the image pre-processing time.
f59c0b4b iosbuild.sh: specify optimization flags
8d34ea3e update ChangeLog (tag: v0.4.1-rc1)
@ -1721,7 +2643,7 @@ ea59a8e9 Merge "Merge tag 'v0.4.0'"
effcb0fd Merge tag 'v0.4.0'
7c76255d autoconf: update ax_pthread.m4
fff2a11b make -short work with -print_ssim, -print_psnr, etc.
68e7901d update ChangeLog (tag: v0.4.0-rc1, tag: v0.4.0, origin/0.4.0, 0.4.0)
68e7901d update ChangeLog (tag: v0.4.0-rc1, tag: v0.4.0, origin/0.4.0)
256e4333 update NEWS description with new general features
29625340 Merge "gif2webp: don't use C99 %zu" into 0.4.0
3b9f9dd0 gif2webp: don't use C99 %zu
@ -2497,7 +3419,7 @@ a61a824b Merge "Add NULL check in chunk APIs"
a0770727 mux struct naming
6c66dde8 Merge "Tune Lossless encoder"
ab5ea217 Tune Lossless encoder
74fefc8c Update ChangeLog (tag: v0.2.1, origin/0.2.0, 0.2.0)
74fefc8c Update ChangeLog (tag: v0.2.1, origin/0.2.0)
92f8059c Rename some chunks:
3bb4bbeb Merge "Mux API change:"
d0c79f05 Mux API change:

View File

@ -1,8 +1,8 @@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src imageio man
SUBDIRS = sharpyuv src imageio man
EXTRA_DIST = COPYING autogen.sh
if WANT_EXTRAS
if BUILD_EXTRAS
SUBDIRS += extras
endif

View File

@ -28,15 +28,14 @@ PLATFORM_LDFLAGS = /SAFESEH
NOLOGO = /nologo
CCNODBG = cl.exe $(NOLOGO) /O2 /DNDEBUG
CCDEBUG = cl.exe $(NOLOGO) /Od /Gm /Zi /D_DEBUG /RTC1
CFLAGS = /Isrc $(NOLOGO) /W3 /EHsc /c
CCDEBUG = cl.exe $(NOLOGO) /Od /Zi /D_DEBUG /RTC1
CFLAGS = /I. /Isrc $(NOLOGO) /W3 /EHsc /c
CFLAGS = $(CFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN
LDFLAGS = /LARGEADDRESSAWARE /MANIFEST /NXCOMPAT /DYNAMICBASE
LDFLAGS = /LARGEADDRESSAWARE /MANIFEST:EMBED /NXCOMPAT /DYNAMICBASE
LDFLAGS = $(LDFLAGS) $(PLATFORM_LDFLAGS)
LNKDLL = link.exe /DLL $(NOLOGO)
LNKEXE = link.exe $(NOLOGO)
LNKLIB = lib.exe $(NOLOGO)
MT = mt.exe $(NOLOGO)
RCNODBG = rc.exe $(NOLOGO) /l"0x0409" # 0x409 = U.S. English
RCDEBUG = $(RCNODBG) /D_DEBUG
@ -53,11 +52,6 @@ OUTDIR = ..\obj\
OUTDIR = $(OBJDIR)
!ENDIF
!IF "$(HAVE_AVX2)" == "1"
CFLAGS = $(CFLAGS) /DWEBP_HAVE_AVX2
AVX2_FLAGS = /arch:AVX2
!ENDIF
##############################################################
# Runtime library configuration
!IF "$(RTLIBCFG)" == "static"
@ -87,6 +81,7 @@ OUTPUT_DIRS = $(DIRBIN) $(DIRINC) $(DIRLIB) \
$(DIROBJ)\extras \
$(DIROBJ)\imageio \
$(DIROBJ)\mux \
$(DIROBJ)\sharpyuv \
$(DIROBJ)\utils \
# Target configuration
@ -134,12 +129,16 @@ LIBWEBP_PDBNAME = $(DIROBJ)\$(LIBWEBP_BASENAME)_dll.pdb
CFGSET = TRUE
!ENDIF
!IF "$(UNICODE)" == "1"
CFLAGS = $(CFLAGS) /D_UNICODE /DUNICODE
!ENDIF
#######################
# Usage
#
!IF "$(CFGSET)" == "FALSE"
!MESSAGE Usage: nmake /f Makefile.vc [CFG=<config>]
!MESSAGE . [OBJDIR=<path>] [RTLIBCFG=<rtlib>] [<target>]
!MESSAGE . [OBJDIR=<path>] [RTLIBCFG=<rtlib>] [UNICODE=1] [<target>]
!MESSAGE
!MESSAGE where <config> is one of:
!MESSAGE - release-static - release static library
@ -155,6 +154,7 @@ CFGSET = TRUE
!MESSAGE - all - build (de)mux-based targets for CFG
!MESSAGE - gif2webp - requires libgif & >= VS2013
!MESSAGE - anim_diff - requires libgif & >= VS2013
!MESSAGE - anim_dump
!MESSAGE
!MESSAGE RTLIBCFG controls the runtime library linkage - 'static' or 'dynamic'.
!MESSAGE 'legacy' will produce a Windows 2000 compatible library.
@ -174,6 +174,14 @@ CFGSET = TRUE
# A config was provided, so the library can be built.
#
SHARPYUV_OBJS = \
$(DIROBJ)\sharpyuv\sharpyuv.obj \
$(DIROBJ)\sharpyuv\sharpyuv_csp.obj \
$(DIROBJ)\sharpyuv\sharpyuv_dsp.obj \
$(DIROBJ)\sharpyuv\sharpyuv_gamma.obj \
$(DIROBJ)\sharpyuv\sharpyuv_neon.obj \
$(DIROBJ)\sharpyuv\sharpyuv_sse2.obj \
DEC_OBJS = \
$(DIROBJ)\dec\alpha_dec.obj \
$(DIROBJ)\dec\buffer_dec.obj \
@ -215,6 +223,7 @@ DSP_DEC_OBJS = \
$(DIROBJ)\dsp\lossless_msa.obj \
$(DIROBJ)\dsp\lossless_neon.obj \
$(DIROBJ)\dsp\lossless_sse2.obj \
$(DIROBJ)\dsp\lossless_sse41.obj \
$(DIROBJ)\dsp\rescaler.obj \
$(DIROBJ)\dsp\rescaler_mips32.obj \
$(DIROBJ)\dsp\rescaler_mips_dsp_r2.obj \
@ -226,21 +235,21 @@ DSP_DEC_OBJS = \
$(DIROBJ)\dsp\upsampling_msa.obj \
$(DIROBJ)\dsp\upsampling_neon.obj \
$(DIROBJ)\dsp\upsampling_sse2.obj \
$(DIROBJ)\dsp\upsampling_sse41.obj \
$(DIROBJ)\dsp\yuv.obj \
$(DIROBJ)\dsp\yuv_mips32.obj \
$(DIROBJ)\dsp\yuv_mips_dsp_r2.obj \
$(DIROBJ)\dsp\yuv_neon.obj \
$(DIROBJ)\dsp\yuv_sse2.obj \
$(DIROBJ)\dsp\yuv_sse41.obj \
DSP_ENC_OBJS = \
$(DIROBJ)\dsp\argb.obj \
$(DIROBJ)\dsp\argb_mips_dsp_r2.obj \
$(DIROBJ)\dsp\argb_sse2.obj \
$(DIROBJ)\dsp\cost.obj \
$(DIROBJ)\dsp\cost_mips32.obj \
$(DIROBJ)\dsp\cost_mips_dsp_r2.obj \
$(DIROBJ)\dsp\cost_neon.obj \
$(DIROBJ)\dsp\cost_sse2.obj \
$(DIROBJ)\dsp\enc.obj \
$(DIROBJ)\dsp\enc_avx2.obj \
$(DIROBJ)\dsp\enc_mips32.obj \
$(DIROBJ)\dsp\enc_mips_dsp_r2.obj \
$(DIROBJ)\dsp\enc_msa.obj \
@ -254,6 +263,8 @@ DSP_ENC_OBJS = \
$(DIROBJ)\dsp\lossless_enc_neon.obj \
$(DIROBJ)\dsp\lossless_enc_sse2.obj \
$(DIROBJ)\dsp\lossless_enc_sse41.obj \
$(DIROBJ)\dsp\ssim.obj \
$(DIROBJ)\dsp\ssim_sse2.obj \
EX_ANIM_UTIL_OBJS = \
$(DIROBJ)\examples\anim_util.obj \
@ -263,6 +274,7 @@ IMAGEIO_DEC_OBJS = \
$(DIROBJ)\imageio\jpegdec.obj \
$(DIROBJ)\imageio\metadata.obj \
$(DIROBJ)\imageio\pngdec.obj \
$(DIROBJ)\imageio\pnmdec.obj \
$(DIROBJ)\imageio\tiffdec.obj \
$(DIROBJ)\imageio\webpdec.obj \
$(DIROBJ)\imageio\wicdec.obj \
@ -279,10 +291,10 @@ EX_UTIL_OBJS = \
ENC_OBJS = \
$(DIROBJ)\enc\alpha_enc.obj \
$(DIROBJ)\enc\analysis_enc.obj \
$(DIROBJ)\enc\backward_references_cost_enc.obj \
$(DIROBJ)\enc\backward_references_enc.obj \
$(DIROBJ)\enc\config_enc.obj \
$(DIROBJ)\enc\cost_enc.obj \
$(DIROBJ)\enc\delta_palettization_enc.obj \
$(DIROBJ)\enc\filter_enc.obj \
$(DIROBJ)\enc\frame_enc.obj \
$(DIROBJ)\enc\histogram_enc.obj \
@ -331,8 +343,8 @@ UTILS_ENC_OBJS = \
$(DIROBJ)\utils\quant_levels_utils.obj \
LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS)
LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) $(DSP_ENC_OBJS) \
$(UTILS_ENC_OBJS) $(DLL_OBJS)
LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(SHARPYUV_OBJS) $(ENC_OBJS) \
$(DSP_ENC_OBJS) $(UTILS_ENC_OBJS) $(DLL_OBJS)
LIBWEBPMUX_OBJS = $(MUX_OBJS) $(LIBWEBPMUX_OBJS)
LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS) $(LIBWEBPDEMUX_OBJS)
@ -344,7 +356,8 @@ all: ex
OUT_EXAMPLES = $(DIRBIN)\cwebp.exe $(DIRBIN)\dwebp.exe
EXTRA_EXAMPLES = $(DIRBIN)\vwebp.exe $(DIRBIN)\webpmux.exe \
$(DIRBIN)\img2webp.exe $(DIRBIN)\get_disto.exe \
$(DIRBIN)\webp_quality.exe
$(DIRBIN)\webp_quality.exe $(DIRBIN)\vwebp_sdl.exe \
$(DIRBIN)\webpinfo.exe
ex: $(OUT_LIBS) $(OUT_EXAMPLES)
all: ex $(EXTRA_EXAMPLES)
@ -352,42 +365,58 @@ all: ex $(EXTRA_EXAMPLES)
# C99 support which is only available from VS2013 onward.
gif2webp: $(DIRBIN)\gif2webp.exe
anim_diff: $(DIRBIN)\anim_diff.exe
anim_dump: $(DIRBIN)\anim_dump.exe
$(DIRBIN)\anim_diff.exe: $(DIROBJ)\examples\anim_diff.obj $(EX_ANIM_UTIL_OBJS)
$(DIRBIN)\anim_diff.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
$(DIRBIN)\anim_diff.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
$(DIRBIN)\anim_dump.exe: $(DIROBJ)\examples\anim_dump.obj $(EX_ANIM_UTIL_OBJS)
$(DIRBIN)\anim_dump.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
$(DIRBIN)\anim_dump.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
$(DIRBIN)\anim_dump.exe: $(IMAGEIO_ENC_OBJS)
$(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj $(IMAGEIO_DEC_OBJS)
$(DIRBIN)\cwebp.exe: $(IMAGEIO_UTIL_OBJS)
$(DIRBIN)\cwebp.exe: $(LIBWEBPDEMUX)
$(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj $(IMAGEIO_DEC_OBJS)
$(DIRBIN)\dwebp.exe: $(IMAGEIO_ENC_OBJS)
$(DIRBIN)\dwebp.exe: $(IMAGEIO_UTIL_OBJS)
$(DIRBIN)\dwebp.exe: $(LIBWEBPDEMUX)
$(DIRBIN)\gif2webp.exe: $(DIROBJ)\examples\gif2webp.obj $(EX_GIF_DEC_OBJS)
$(DIRBIN)\gif2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBPMUX)
$(DIRBIN)\gif2webp.exe: $(LIBWEBP)
$(DIRBIN)\vwebp.exe: $(DIROBJ)\examples\vwebp.obj $(EX_UTIL_OBJS)
$(DIRBIN)\vwebp.exe: $(IMAGEIO_UTIL_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
$(DIRBIN)\vwebp_sdl.exe: $(DIROBJ)\extras\vwebp_sdl.obj
$(DIRBIN)\vwebp_sdl.exe: $(DIROBJ)\extras\webp_to_sdl.obj
$(DIRBIN)\vwebp_sdl.exe: $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
$(DIRBIN)\webpmux.exe: $(DIROBJ)\examples\webpmux.obj $(LIBWEBPMUX)
$(DIRBIN)\webpmux.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
$(DIRBIN)\img2webp.exe: $(DIROBJ)\examples\img2webp.obj $(LIBWEBPMUX)
$(DIRBIN)\img2webp.exe: $(IMAGEIO_DEC_OBJS)
$(DIRBIN)\img2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
$(DIRBIN)\img2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
$(DIRBIN)\img2webp.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
$(DIRBIN)\get_disto.exe: $(DIROBJ)\extras\get_disto.obj
$(DIRBIN)\get_disto.exe: $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
$(DIRBIN)\get_disto.exe: $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS)
$(DIRBIN)\get_disto.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
$(DIRBIN)\webp_quality.exe: $(DIROBJ)\extras\webp_quality.obj
$(DIRBIN)\webp_quality.exe: $(IMAGEIO_UTIL_OBJS)
$(DIRBIN)\webp_quality.exe: $(EXTRAS_OBJS) $(LIBWEBP)
$(DIRBIN)\webp_quality.exe: $(EXTRAS_OBJS)
# EXTRA_OBJS requires private symbols from dsp. Explicitly add those when
# building libwebp as a dll.
!IF "$(DLLBUILD)" == "TRUE"
$(DIRBIN)\webp_quality.exe: $(DSP_DEC_OBJS)
!ENDIF
$(DIRBIN)\webp_quality.exe: $(LIBWEBP)
$(DIRBIN)\webpinfo.exe: $(DIROBJ)\examples\webpinfo.obj
$(DIRBIN)\webpinfo.exe: $(IMAGEIO_DEC_OBJS)
$(DIRBIN)\webpinfo.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
$(DIRBIN)\webpinfo.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
$(OUT_EXAMPLES): $(EX_UTIL_OBJS) $(LIBWEBP)
$(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS): $(OUTPUT_DIRS)
$(IMAGEIO_DEC_OBJS) $(IMAGEIO_ENC_OBJS) $(EXTRAS_OBJS): $(OUTPUT_DIRS)
!ENDIF # ARCH == ARM
experimental:
$(MAKE) /f Makefile.vc \
CFG=$(CFG) \
CFLAGS="$(CFLAGS) /DWEBP_EXPERIMENTAL_FEATURES" /$(MAKEFLAGS)
$(LIBWEBPDECODER): $(LIBWEBPDECODER_OBJS)
$(LIBWEBP): $(LIBWEBP_OBJS)
$(LIBWEBPMUX): $(LIBWEBPMUX_OBJS)
@ -433,18 +462,18 @@ $(OUTPUT_DIRS):
$(DIROBJ)\$(DLLINC):
@echo #ifndef WEBP_DLL_H_ > $@
@echo #define WEBP_DLL_H_ >> $@
@echo #define WEBP_EXTERN(type) __declspec(dllexport) type >> $@
@echo #define WEBP_EXTERN __declspec(dllexport) >> $@
@echo #endif /* WEBP_DLL_H_ */ >> $@
.SUFFIXES: .c .obj .res .exe
# File-specific flag builds. Note batch rules take precedence over wildcards,
# so for now name each file individually.
$(DIROBJ)\dsp\enc_avx2.obj: src\dsp\enc_avx2.c
$(CC) $(CFLAGS) $(AVX2_FLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dsp\ \
src\dsp\$(@B).c
$(DIROBJ)\examples\anim_diff.obj: examples\anim_diff.c
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
/Fo$(DIROBJ)\examples\ examples\$(@B).c
$(DIROBJ)\examples\anim_dump.obj: examples\anim_dump.c
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
/Fo$(DIROBJ)\examples\ examples\$(@B).c
$(DIROBJ)\examples\anim_util.obj: examples\anim_util.c
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
/Fo$(DIROBJ)\examples\ examples\$(@B).c
@ -461,6 +490,8 @@ $(DIROBJ)\examples\gifdec.obj: examples\gifdec.c
$(CC) $(CFLAGS) /Fd$(DIROBJ)\extras\ /Fo$(DIROBJ)\extras\ $<
{imageio}.c{$(DIROBJ)\imageio}.obj::
$(CC) $(CFLAGS) /Fd$(DIROBJ)\imageio\ /Fo$(DIROBJ)\imageio\ $<
{sharpyuv}.c{$(DIROBJ)\sharpyuv}.obj::
$(CC) $(CFLAGS) /Fd$(DIROBJ)\sharpyuv\ /Fo$(DIROBJ)\sharpyuv\ $<
{src\dec}.c{$(DIROBJ)\dec}.obj::
$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dec\ $<
{src\demux}.c{$(DIROBJ)\demux}.obj::
@ -474,17 +505,16 @@ $(DIROBJ)\examples\gifdec.obj: examples\gifdec.c
{src\utils}.c{$(DIROBJ)\utils}.obj::
$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\utils\ $<
LNKLIBS = ole32.lib windowscodecs.lib shlwapi.lib
!IF "$(UNICODE)" == "1"
LNKLIBS = $(LNKLIBS) Shell32.lib
!ENDIF
{$(DIROBJ)\examples}.obj{$(DIRBIN)}.exe:
$(LNKEXE) $(LDFLAGS) /OUT:$@ $** \
ole32.lib windowscodecs.lib shlwapi.lib
$(MT) -manifest $@.manifest -outputresource:$@;1
del $@.manifest
$(LNKEXE) $(LDFLAGS) /OUT:$@ $** $(LNKLIBS)
{$(DIROBJ)\extras}.obj{$(DIRBIN)}.exe:
$(LNKEXE) $(LDFLAGS) /OUT:$@ $** \
ole32.lib windowscodecs.lib shlwapi.lib
$(MT) -manifest $@.manifest -outputresource:$@;1
del $@.manifest
$(LNKEXE) $(LDFLAGS) /OUT:$@ $** $(LNKLIBS)
clean::
@-erase /s $(DIROBJ)\*.dll 2> NUL

112
NEWS
View File

@ -1,3 +1,115 @@
- 8/4/2022: version 1.2.4
This is a binary compatible release.
* restore CMake libwebpmux target name for compatibility with 1.2.2 (#575)
* fix lossless crunch mode encoding with WEBP_REDUCE_SIZE
(chromium: #1345547, #1345595, #1345772, #1345804)
- 6/30/2022: version 1.2.3
This is a binary compatible release.
* security fix for lossless encoder (#565, chromium:1313709)
* improved progress granularity in WebPReportProgress() when using lossless
* improved precision in Sharp YUV (-sharp_yuv) conversion
* many corrections to webp-lossless-bitstream-spec.txt (#551)
* crash/leak fixes on error/OOM and other bug fixes (#558, #563, #569, #573)
- 1/11/2022: version 1.2.2
This is a binary compatible release.
* webpmux: add "-set bgcolor A,R,G,B"
* add ARM64 NEON support for MSVC builds (#539)
* fix duplicate include error in Xcode when using multiple XCFrameworks in a
project (#542)
* doc updates and bug fixes (#538, #544, #548, #550)
- 7/20/2021: version 1.2.1
This is a binary compatible release.
* minor lossless encoder improvements and x86 color conversion speed up
* add ARM64 simulator support to xcframeworkbuild.sh (#510)
* further security related hardening in libwebp & examples
(issues: #497, #508, #518)
(chromium: #1196480, #1196773, #1196775, #1196777, #1196778, #1196850)
(oss-fuzz: #28658, #28978)
* toolchain updates and bug fixes (#498, #501, #502, #504, #505, #506, #509,
#533)
* use more inclusive language within the source (#507)
- 12/23/2020: version 1.2.0
* API changes:
- libwebp:
encode.h: add a qmin / qmax range for quality factor (cwebp adds -qrange)
* lossless encoder improvements
* SIMD support for Wasm builds
* add xcframeworkbuild.sh, supports Mac Catalyst builds
* import fuzzers from oss-fuzz & chromium (#409)
* webpmux: add an '-set loop <value>' option (#494)
* toolchain updates and bug fixes (#449, #463, #470, #475, #477, #478, #479,
#488, #491)
- 12/18/2019: version 1.1.0
* API changes:
- libwebp:
WebPMalloc (issue #442)
- extras:
WebPUnmultiplyARGB
* alpha decode fix (issue #439)
* toolchain updates and bug fixes
(chromium: #1026858, #1027136, #1027409, #1028620, #1028716, #995200)
(oss-fuzz: #19430, #19447)
- 7/4/2019: version 1.0.3
This is a binary compatible release.
* resize fixes for Nx1 sizes and the addition of non-opaque alpha values for
odd sizes (issues #418, #434)
* lossless encode/decode performance improvements
* lossy compression performance improvement at low quality levels with flat
content (issue #432)
* python swig files updated to support python 3
Tool updates:
vwebp will now preserve the aspect ratio of images that exceed monitor
resolution by scaling the image to fit (issue #433)
- 1/14/2019: version 1.0.2
This is a binary compatible release.
* (Windows) unicode file support in the tools (linux and mac already had
support, issue #398)
* lossless encoder speedups
* lossy encoder speedup on ARM
* lossless multi-threaded security fix (chromium:917029)
- 11/2/2018: version 1.0.1
This is a binary compatible release.
* lossless encoder speedups
* big-endian fix for alpha decoding (issue #393)
* gif2webp fix for loop count=65535 transcode (issue #382)
* further security related hardening in libwebp & libwebpmux
(issues #383, #385, #386, #387, #388, #391)
(oss-fuzz #9099, #9100, #9105, #9106, #9111, #9112, #9119, #9123, #9170,
#9178, #9179, #9183, #9186, #9191, #9364, #9417, #9496, #10349,
#10423, #10634, #10700, #10838, #10922, #11021, #11088, #11152)
* miscellaneous bug & build fixes (issues #381, #394, #396, #397, #400)
- 4/2/2018: version 1.0.0
This is a binary compatible release.
* lossy encoder improvements to avoid chroma shifts in various circumstances
(issues #308, #340)
* big-endian fixes for decode, RGBA import and WebPPictureDistortion
Tool updates:
gifwebp, anim_diff - default duration behavior (<= 10ms) changed to match
web browsers, transcoding tools (issue #379)
img2webp, webpmux - allow options to be passed in via a file (issue #355)
- 11/24/2017: version 0.6.1
This is a binary compatible release.
* lossless performance and compression improvements + a new 'cruncher' mode
(-m 6 -q 100)
* ARM performance improvements with clang (15-20% w/ndk r15c, issue #339)
* webp-js: emscripten/webassembly based javascript decoder
* miscellaneous bug & build fixes (issue #329, #332, #343, #353, #360, #361,
#363)
Tool updates / additions:
added webpinfo - prints file format information (issue #330)
gif2webp - loop behavior modified to match Chrome M63+ (crbug.com/649264);
'-loop_compatibility' can be used for the old behavior
- 1/26/2017: version 0.6.0
* lossless performance and compression improvements
* miscellaneous performance improvements (SSE2, NEON, MSA)

245
PRESUBMIT.py Normal file
View File

@ -0,0 +1,245 @@
# Copyright (c) 2021, Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# * Neither the name of Google nor the names of its contributors may
# be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Top-level presubmit script for libwebp.
See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for
details on the presubmit API built into depot_tools.
"""
import re
import subprocess2
USE_PYTHON3 = True
_BASH_INDENTATION = "2"
_GIT_COMMIT_SUBJECT_LENGTH = 65
_INCLUDE_BASH_FILES_ONLY = [r".*\.sh$"]
_INCLUDE_MAN_FILES_ONLY = [r"man/.+\.1$"]
_INCLUDE_SOURCE_FILES_ONLY = [r".*\.[ch]$"]
_LIBWEBP_MAX_LINE_LENGTH = 80
def _CheckCommitSubjectLength(input_api, output_api):
"""Ensures commit's subject length is no longer than 65 chars."""
name = "git-commit subject"
cmd = ["git", "log", "-1", "--pretty=%s"]
start = input_api.time.time()
proc = subprocess2.Popen(
cmd,
stderr=subprocess2.PIPE,
stdout=subprocess2.PIPE,
universal_newlines=True)
stdout, _ = proc.communicate()
duration = input_api.time.time() - start
if not re.match(r"^Revert",
stdout) and (len(stdout) - 1) > _GIT_COMMIT_SUBJECT_LENGTH:
failure_msg = (
"The commit subject: %s is too long (%d chars)\n"
"Try to keep this to 50 or less (up to 65 is permitted for "
"non-reverts).\n"
"https://www.git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-"
"Project#_commit_guidelines") % (stdout, len(stdout) - 1)
return output_api.PresubmitError("%s\n (%4.2fs) failed\n%s" %
(name, duration, failure_msg))
return output_api.PresubmitResult("%s\n (%4.2fs) success" % (name, duration))
def _CheckDuplicateFiles(input_api, output_api):
"""Ensures there are not repeated filenames."""
all_files = []
for f in input_api.change.AllFiles():
for include_file in _INCLUDE_SOURCE_FILES_ONLY:
if re.match(include_file, f):
all_files.append(f)
break
basename_to_path = {}
for f in all_files:
basename_file = input_api.basename(f)
if basename_file in basename_to_path:
basename_to_path[basename_file].append(f)
else:
basename_to_path[basename_file] = [f]
dupes = []
for files in basename_to_path.values():
if len(files) > 1:
dupes.extend(files)
if dupes:
return output_api.PresubmitError(
"Duplicate source files, rebase or rename some to make them unique:\n%s"
% dupes)
return output_api.PresubmitResult("No duplicates, success\n")
def _GetFilesToSkip(input_api):
return list(input_api.DEFAULT_FILES_TO_SKIP) + [
r"swig/.*\.py$",
r"\.pylintrc$",
]
def _RunManCmd(input_api, output_api, man_file):
"""man command wrapper."""
cmd = ["man", "--warnings", "-EUTF-8", "-l", "-Tutf8", "-Z", man_file]
name = "Check %s file." % man_file
start = input_api.time.time()
output, _ = subprocess2.communicate(
cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
duration = input_api.time.time() - start
if output[1]:
return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
(name, " ".join(cmd), duration, output[1]))
return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
(name, " ".join(cmd), duration))
def _RunShellCheckCmd(input_api, output_api, bash_file):
"""shellcheck command wrapper."""
cmd = ["shellcheck", "-x", "-oall", "-sbash", bash_file]
name = "Check %s file." % bash_file
start = input_api.time.time()
output, rc = subprocess2.communicate(
cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
duration = input_api.time.time() - start
if rc == 0:
return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
(name, " ".join(cmd), duration))
return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
(name, " ".join(cmd), duration, output[1]))
def _RunShfmtCheckCmd(input_api, output_api, bash_file):
"""shfmt command wrapper."""
cmd = [
"shfmt", "-i", _BASH_INDENTATION, "-bn", "-ci", "-sr", "-kp", "-d",
bash_file
]
name = "Check %s file." % bash_file
start = input_api.time.time()
output, rc = subprocess2.communicate(
cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
duration = input_api.time.time() - start
if rc == 0:
return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
(name, " ".join(cmd), duration))
return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
(name, " ".join(cmd), duration, output[1]))
def _RunCmdOnCheckedFiles(input_api, output_api, run_cmd, files_to_check):
"""Ensure that libwebp/ files are clean."""
file_filter = lambda x: input_api.FilterSourceFile(
x, files_to_check=files_to_check, files_to_skip=None)
affected_files = input_api.change.AffectedFiles(file_filter=file_filter)
results = [
run_cmd(input_api, output_api, f.AbsoluteLocalPath())
for f in affected_files
]
return results
def _CommonChecks(input_api, output_api):
"""Ensures this patch does not have trailing spaces, extra EOLs,
or long lines.
"""
results = []
results.extend(
input_api.canned_checks.CheckChangeHasNoCrAndHasOnlyOneEol(
input_api, output_api))
results.extend(
input_api.canned_checks.CheckChangeHasNoTabs(input_api, output_api))
results.extend(
input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
input_api, output_api))
results.append(_CheckCommitSubjectLength(input_api, output_api))
results.append(_CheckDuplicateFiles(input_api, output_api))
source_file_filter = lambda x: input_api.FilterSourceFile(
x, files_to_skip=_GetFilesToSkip(input_api))
results.extend(
input_api.canned_checks.CheckLongLines(
input_api,
output_api,
maxlen=_LIBWEBP_MAX_LINE_LENGTH,
source_file_filter=source_file_filter))
results.extend(
input_api.canned_checks.CheckPatchFormatted(
input_api,
output_api,
check_clang_format=False,
check_python=True,
result_factory=output_api.PresubmitError))
results.extend(
_RunCmdOnCheckedFiles(input_api, output_api, _RunManCmd,
_INCLUDE_MAN_FILES_ONLY))
# Run pylint.
results.extend(
input_api.canned_checks.RunPylint(
input_api,
output_api,
files_to_skip=_GetFilesToSkip(input_api),
pylintrc=".pylintrc",
version="2.7"))
# Binaries shellcheck and shfmt are not installed in depot_tools.
# Installation is needed
try:
subprocess2.communicate(["shellcheck", "--version"])
results.extend(
_RunCmdOnCheckedFiles(input_api, output_api, _RunShellCheckCmd,
_INCLUDE_BASH_FILES_ONLY))
print("shfmt")
subprocess2.communicate(["shfmt", "-version"])
results.extend(
_RunCmdOnCheckedFiles(input_api, output_api, _RunShfmtCheckCmd,
_INCLUDE_BASH_FILES_ONLY))
except OSError as os_error:
results.append(
output_api.PresubmitPromptWarning(
"%s\nPlease install missing binaries locally." % os_error.args[0]))
return results
def CheckChangeOnUpload(input_api, output_api):
results = []
results.extend(_CommonChecks(input_api, output_api))
return results
def CheckChangeOnCommit(input_api, output_api):
results = []
results.extend(_CommonChecks(input_api, output_api))
return results

750
README
View File

@ -1,750 +0,0 @@
__ __ ____ ____ ____
/ \\/ \/ _ \/ _ )/ _ \
\ / __/ _ \ __/
\__\__/\____/\_____/__/ ____ ___
/ _/ / \ \ / _ \/ _/
/ \_/ / / \ \ __/ \__
\____/____/\_____/_____/____/v0.6.0
Description:
============
WebP codec: library to encode and decode images in WebP format. This package
contains the library that can be used in other programs to add WebP support,
as well as the command line tools 'cwebp' and 'dwebp'.
See http://developers.google.com/speed/webp
The latest source tree is available at
https://chromium.googlesource.com/webm/libwebp
It is released under the same license as the WebM project.
See http://www.webmproject.org/license/software/ or the
"COPYING" file for details. An additional intellectual
property rights grant can be found in the file PATENTS.
Building:
=========
Windows build:
--------------
By running:
nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output
the directory output\release-static\(x64|x86)\bin will contain the tools
cwebp.exe and dwebp.exe. The directory output\release-static\(x64|x86)\lib will
contain the libwebp static library.
The target architecture (x86/x64) is detected by Makefile.vc from the Visual
Studio compiler (cl.exe) available in the system path.
Unix build using makefile.unix:
-------------------------------
On platforms with GNU tools installed (gcc and make), running
make -f makefile.unix
will build the binaries examples/cwebp and examples/dwebp, along
with the static library src/libwebp.a. No system-wide installation
is supplied, as this is a simple alternative to the full installation
system based on the autoconf tools (see below).
Please refer to makefile.unix for additional details and customizations.
Using autoconf tools:
---------------------
Prerequisites:
A compiler (e.g., gcc), make, autoconf, automake, libtool.
On a Debian-like system the following should install everything you need for a
minimal build:
$ sudo apt-get install gcc make autoconf automake libtool
When building from git sources, you will need to run autogen.sh to generate the
configure script.
./configure
make
make install
should be all you need to have the following files
/usr/local/include/webp/decode.h
/usr/local/include/webp/encode.h
/usr/local/include/webp/types.h
/usr/local/lib/libwebp.*
/usr/local/bin/cwebp
/usr/local/bin/dwebp
installed.
Note: A decode-only library, libwebpdecoder, is available using the
'--enable-libwebpdecoder' flag. The encode library is built separately and can
be installed independently using a minor modification in the corresponding
Makefile.am configure files (see comments there). See './configure --help' for
more options.
Building for MIPS Linux:
------------------------
MIPS Linux toolchain stable available releases can be found at:
https://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/available-releases/
# Add toolchain to PATH
export PATH=$PATH:/path/to/toolchain/bin
# 32-bit build for mips32r5 (p5600)
HOST=mips-mti-linux-gnu
MIPS_CFLAGS="-O3 -mips32r5 -mabi=32 -mtune=p5600 -mmsa -mfp64 \
-msched-weight -mload-store-pairs -fPIE"
MIPS_LDFLAGS="-mips32r5 -mabi=32 -mmsa -mfp64 -pie"
# 64-bit build for mips64r6 (i6400)
HOST=mips-img-linux-gnu
MIPS_CFLAGS="-O3 -mips64r6 -mabi=64 -mtune=i6400 -mmsa -mfp64 \
-msched-weight -mload-store-pairs -fPIE"
MIPS_LDFLAGS="-mips64r6 -mabi=64 -mmsa -mfp64 -pie"
./configure --host=${HOST} --build=`config.guess` \
CC="${HOST}-gcc -EL" \
CFLAGS="$MIPS_CFLAGS" \
LDFLAGS="$MIPS_LDFLAGS"
make
make install
CMake:
------
The support for CMake is minimal: it only helps you compile libwebp, cwebp and
dwebp.
Prerequisites:
A compiler (e.g., gcc with autotools) and CMake.
On a Debian-like system the following should install everything you need for a
minimal build:
$ sudo apt-get install build-essential cmake
When building from git sources, you will need to run cmake to generate the
configure script.
mkdir build && cd build && cmake ../
make
make install
If you also want cwebp or dwebp, you will need to enable them through CMake:
cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../
or through your favorite interface (like ccmake or cmake-qt-gui).
Gradle:
-------
The support for Gradle is minimal: it only helps you compile libwebp, cwebp and
dwebp and webpmux_example.
Prerequisites:
A compiler (e.g., gcc with autotools) and gradle.
On a Debian-like system the following should install everything you need for a
minimal build:
$ sudo apt-get install build-essential gradle
When building from git sources, you will need to run the Gradle wrapper with the
appropriate target, e.g. :
./gradlew buildAllExecutables
SWIG bindings:
--------------
To generate language bindings from swig/libwebp.swig at least swig-1.3
(http://www.swig.org) is required.
Currently the following functions are mapped:
Decode:
WebPGetDecoderVersion
WebPGetInfo
WebPDecodeRGBA
WebPDecodeARGB
WebPDecodeBGRA
WebPDecodeBGR
WebPDecodeRGB
Encode:
WebPGetEncoderVersion
WebPEncodeRGBA
WebPEncodeBGRA
WebPEncodeRGB
WebPEncodeBGR
WebPEncodeLosslessRGBA
WebPEncodeLosslessBGRA
WebPEncodeLosslessRGB
WebPEncodeLosslessBGR
See swig/README for more detailed build instructions.
Java bindings:
To build the swig-generated JNI wrapper code at least JDK-1.5 (or equivalent)
is necessary for enum support. The output is intended to be a shared object /
DLL that can be loaded via System.loadLibrary("webp_jni").
Python bindings:
To build the swig-generated Python extension code at least Python 2.6 is
required. Python < 2.6 may build with some minor changes to libwebp.swig or the
generated code, but is untested.
Encoding tool:
==============
The examples/ directory contains tools for encoding (cwebp) and
decoding (dwebp) images.
The easiest use should look like:
cwebp input.png -q 80 -o output.webp
which will convert the input file to a WebP file using a quality factor of 80
on a 0->100 scale (0 being the lowest quality, 100 being the best. Default
value is 75).
You might want to try the -lossless flag too, which will compress the source
(in RGBA format) without any loss. The -q quality parameter will in this case
control the amount of processing time spent trying to make the output file as
small as possible.
A longer list of options is available using the -longhelp command line flag:
> cwebp -longhelp
Usage:
cwebp [-preset <...>] [options] in_file [-o out_file]
If input size (-s) for an image is not specified, it is
assumed to be a PNG, JPEG, TIFF or WebP file.
Options:
-h / -help ............. short help
-H / -longhelp ......... long help
-q <float> ............. quality factor (0:small..100:big), default=75
-alpha_q <int> ......... transparency-compression quality (0..100),
default=100
-preset <string> ....... preset setting, one of:
default, photo, picture,
drawing, icon, text
-preset must come first, as it overwrites other parameters
-z <int> ............... activates lossless preset with given
level in [0:fast, ..., 9:slowest]
-m <int> ............... compression method (0=fast, 6=slowest), default=4
-segments <int> ........ number of segments to use (1..4), default=4
-size <int> ............ target size (in bytes)
-psnr <float> .......... target PSNR (in dB. typically: 42)
-s <int> <int> ......... input size (width x height) for YUV
-sns <int> ............. spatial noise shaping (0:off, 100:max), default=50
-f <int> ............... filter strength (0=off..100), default=60
-sharpness <int> ....... filter sharpness (0:most .. 7:least sharp), default=0
-strong ................ use strong filter instead of simple (default)
-nostrong .............. use simple filter instead of strong
-sharp_yuv ............. use sharper (and slower) RGB->YUV conversion
-partition_limit <int> . limit quality to fit the 512k limit on
the first partition (0=no degradation ... 100=full)
-pass <int> ............ analysis pass number (1..10)
-crop <x> <y> <w> <h> .. crop picture with the given rectangle
-resize <w> <h> ........ resize picture (after any cropping)
-mt .................... use multi-threading if available
-low_memory ............ reduce memory usage (slower encoding)
-map <int> ............. print map of extra info
-print_psnr ............ prints averaged PSNR distortion
-print_ssim ............ prints averaged SSIM distortion
-print_lsim ............ prints local-similarity distortion
-d <file.pgm> .......... dump the compressed output (PGM file)
-alpha_method <int> .... transparency-compression method (0..1), default=1
-alpha_filter <string> . predictive filtering for alpha plane,
one of: none, fast (default) or best
-exact ................. preserve RGB values in transparent area, default=off
-blend_alpha <hex> ..... blend colors against background color
expressed as RGB values written in
hexadecimal, e.g. 0xc0e0d0 for red=0xc0
green=0xe0 and blue=0xd0
-noalpha ............... discard any transparency information
-lossless .............. encode image losslessly, default=off
-near_lossless <int> ... use near-lossless image
preprocessing (0..100=off), default=100
-hint <string> ......... specify image characteristics hint,
one of: photo, picture or graph
-metadata <string> ..... comma separated list of metadata to
copy from the input to the output if present.
Valid values: all, none (default), exif, icc, xmp
-short ................. condense printed message
-quiet ................. don't print anything
-version ............... print version number and exit
-noasm ................. disable all assembly optimizations
-v ..................... verbose, e.g. print encoding/decoding times
-progress .............. report encoding progress
Experimental Options:
-jpeg_like ............. roughly match expected JPEG size
-af .................... auto-adjust filter strength
-pre <int> ............. pre-processing filter
The main options you might want to try in order to further tune the
visual quality are:
-preset
-sns
-f
-m
Namely:
* 'preset' will set up a default encoding configuration targeting a
particular type of input. It should appear first in the list of options,
so that subsequent options can take effect on top of this preset.
Default value is 'default'.
* 'sns' will progressively turn on (when going from 0 to 100) some additional
visual optimizations (like: segmentation map re-enforcement). This option
will balance the bit allocation differently. It tries to take bits from the
"easy" parts of the picture and use them in the "difficult" ones instead.
Usually, raising the sns value (at fixed -q value) leads to larger files,
but with better quality.
Typical value is around '75'.
* 'f' option directly links to the filtering strength used by the codec's
in-loop processing. The higher the value, the smoother the
highly-compressed area will look. This is particularly useful when aiming
at very small files. Typical values are around 20-30. Note that using the
option -strong/-nostrong will change the type of filtering. Use "-f 0" to
turn filtering off.
* 'm' controls the trade-off between encoding speed and quality. Default is 4.
You can try -m 5 or -m 6 to explore more (time-consuming) encoding
possibilities. A lower value will result in faster encoding at the expense
of quality.
Decoding tool:
==============
There is a decoding sample in examples/dwebp.c which will take
a .webp file and decode it to a PNG image file (amongst other formats).
This is simply to demonstrate the use of the API. You can verify the
file test.webp decodes to exactly the same as test_ref.ppm by using:
cd examples
./dwebp test.webp -ppm -o test.ppm
diff test.ppm test_ref.ppm
The full list of options is available using -h:
> dwebp -h
Usage: dwebp in_file [options] [-o out_file]
Decodes the WebP image file to PNG format [Default]
Use following options to convert into alternate image formats:
-pam ......... save the raw RGBA samples as a color PAM
-ppm ......... save the raw RGB samples as a color PPM
-bmp ......... save as uncompressed BMP format
-tiff ........ save as uncompressed TIFF format
-pgm ......... save the raw YUV samples as a grayscale PGM
file with IMC4 layout
-yuv ......... save the raw YUV samples in flat layout
Other options are:
-version ..... print version number and exit
-nofancy ..... don't use the fancy YUV420 upscaler
-nofilter .... disable in-loop filtering
-nodither .... disable dithering
-dither <d> .. dithering strength (in 0..100)
-alpha_dither use alpha-plane dithering if needed
-mt .......... use multi-threading
-crop <x> <y> <w> <h> ... crop output with the given rectangle
-resize <w> <h> ......... scale the output (*after* any cropping)
-flip ........ flip the output vertically
-alpha ....... only save the alpha plane
-incremental . use incremental decoding (useful for tests)
-h ........... this help message
-v ........... verbose (e.g. print encoding/decoding times)
-quiet ....... quiet mode, don't print anything
-noasm ....... disable all assembly optimizations
Visualization tool:
===================
There's a little self-serve visualization tool called 'vwebp' under the
examples/ directory. It uses OpenGL to open a simple drawing window and show
a decoded WebP file. It's not yet integrated in the automake build system, but
you can try to manually compile it using the recommendations below.
Usage: vwebp in_file [options]
Decodes the WebP image file and visualize it using OpenGL
Options are:
-version ..... print version number and exit
-noicc ....... don't use the icc profile if present
-nofancy ..... don't use the fancy YUV420 upscaler
-nofilter .... disable in-loop filtering
-dither <int> dithering strength (0..100), default=50
-noalphadither disable alpha plane dithering
-mt .......... use multi-threading
-info ........ print info
-h ........... this help message
Keyboard shortcuts:
'c' ................ toggle use of color profile
'i' ................ overlay file information
'd' ................ disable blending & disposal (debug)
'q' / 'Q' / ESC .... quit
Building:
---------
Prerequisites:
1) OpenGL & OpenGL Utility Toolkit (GLUT)
Linux:
$ sudo apt-get install freeglut3-dev mesa-common-dev
Mac + XCode:
- These libraries should be available in the OpenGL / GLUT frameworks.
Windows:
http://freeglut.sourceforge.net/index.php#download
2) (Optional) qcms (Quick Color Management System)
i. Download qcms from Mozilla / Chromium:
http://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
http://src.chromium.org/viewvc/chrome/trunk/src/third_party/qcms
ii. Build and archive the source files as libqcms.a / qcms.lib
iii. Update makefile.unix / Makefile.vc
a) Define WEBP_HAVE_QCMS
b) Update include / library paths to reference the qcms directory.
Build using makefile.unix / Makefile.vc:
$ make -f makefile.unix examples/vwebp
> nmake /f Makefile.vc CFG=release-static \
../obj/x64/release-static/bin/vwebp.exe
Animation creation tool:
========================
The utility 'img2webp' can turn a sequence of input images (PNG, JPEG, ...)
into an animated WebP file. It offers fine control over duration, encoding
modes, etc.
Usage:
img2webp [file-level options] [image files...] [per-frame options...]
File-level options (only used at the start of compression):
-min_size ............ minimize size
-loop <int> .......... loop count (default: 0, = infinite loop)
-kmax <int> .......... maximum number of frame between key-frames
(0=only keyframes)
-kmin <int> .......... minimum number of frame between key-frames
(0=disable key-frames altogether)
-mixed ............... use mixed lossy/lossless automatic mode
-v ................... verbose mode
-h ................... this help
Per-frame options (only used for subsequent images input):
-d <int> ............. frame duration in ms (default: 100)
-lossless ........... use lossless mode (default)
-lossy ... ........... use lossy mode
-q <float> ........... quality
-m <int> ............. method to use
example: img2webp -loop 2 in0.png -lossy in1.jpg
-d 80 in2.tiff -o out.webp
Animated GIF conversion:
========================
Animated GIF files can be converted to WebP files with animation using the
gif2webp utility available under examples/. The files can then be viewed using
vwebp.
Usage:
gif2webp [options] gif_file -o webp_file
Options:
-h / -help ............. this help
-lossy ................. encode image using lossy compression
-mixed ................. for each frame in the image, pick lossy
or lossless compression heuristically
-q <float> ............. quality factor (0:small..100:big)
-m <int> ............... compression method (0=fast, 6=slowest)
-min_size .............. minimize output size (default:off)
lossless compression by default; can be
combined with -q, -m, -lossy or -mixed
options
-kmin <int> ............ min distance between key frames
-kmax <int> ............ max distance between key frames
-f <int> ............... filter strength (0=off..100)
-metadata <string> ..... comma separated list of metadata to
copy from the input to the output if present
Valid values: all, none, icc, xmp (default)
-mt .................... use multi-threading if available
-version ............... print version number and exit
-v ..................... verbose
-quiet ................. don't print anything
Building:
---------
With the libgif development files installed, gif2webp can be built using
makefile.unix:
$ make -f makefile.unix examples/gif2webp
or using autoconf:
$ ./configure --enable-everything
$ make
Comparison of animated images:
==============================
Test utility anim_diff under examples/ can be used to compare two animated
images (each can be GIF or WebP).
Usage: anim_diff <image1> <image2> [options]
Options:
-dump_frames <folder> dump decoded frames in PAM format
-min_psnr <float> ... minimum per-frame PSNR
-raw_comparison ..... if this flag is not used, RGB is
premultiplied before comparison
Building:
---------
With the libgif development files and a C++ compiler installed, anim_diff can
be built using makefile.unix:
$ make -f makefile.unix examples/anim_diff
or using autoconf:
$ ./configure --enable-everything
$ make
Encoding API:
=============
The main encoding functions are available in the header src/webp/encode.h
The ready-to-use ones are:
size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride,
float quality_factor, uint8_t** output);
size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride,
float quality_factor, uint8_t** output);
size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride,
float quality_factor, uint8_t** output);
size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride,
float quality_factor, uint8_t** output);
They will convert raw RGB samples to a WebP data. The only control supplied
is the quality factor.
There are some variants for using the lossless format:
size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height,
int stride, uint8_t** output);
size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height,
int stride, uint8_t** output);
size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height,
int stride, uint8_t** output);
size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height,
int stride, uint8_t** output);
Of course in this case, no quality factor is needed since the compression
occurs without loss of the input values, at the expense of larger output sizes.
Advanced encoding API:
----------------------
A more advanced API is based on the WebPConfig and WebPPicture structures.
WebPConfig contains the encoding settings and is not tied to a particular
picture.
WebPPicture contains input data, on which some WebPConfig will be used for
compression.
The encoding flow looks like:
-------------------------------------- BEGIN PSEUDO EXAMPLE
#include <webp/encode.h>
// Setup a config, starting form a preset and tuning some additional
// parameters
WebPConfig config;
if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor))
return 0; // version error
}
// ... additional tuning
config.sns_strength = 90;
config.filter_sharpness = 6;
config_error = WebPValidateConfig(&config); // not mandatory, but useful
// Setup the input data
WebPPicture pic;
if (!WebPPictureInit(&pic)) {
return 0; // version error
}
pic.width = width;
pic.height = height;
// allocated picture of dimension width x height
if (!WebPPictureAllocate(&pic)) {
return 0; // memory error
}
// at this point, 'pic' has been initialized as a container,
// and can receive the Y/U/V samples.
// Alternatively, one could use ready-made import functions like
// WebPPictureImportRGB(), which will take care of memory allocation.
// In any case, past this point, one will have to call
// WebPPictureFree(&pic) to reclaim memory.
// Set up a byte-output write method. WebPMemoryWriter, for instance.
WebPMemoryWriter wrt;
WebPMemoryWriterInit(&wrt); // initialize 'wrt'
pic.writer = MyFileWriter;
pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
// Compress!
int ok = WebPEncode(&config, &pic); // ok = 0 => error occurred!
WebPPictureFree(&pic); // must be called independently of the 'ok' result.
// output data should have been handled by the writer at that point.
// -> compressed data is the memory buffer described by wrt.mem / wrt.size
// deallocate the memory used by compressed data
WebPMemoryWriterClear(&wrt);
-------------------------------------- END PSEUDO EXAMPLE
Decoding API:
=============
This is mainly just one function to call:
#include "webp/decode.h"
uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
int* width, int* height);
Please have a look at the file src/webp/decode.h for the details.
There are variants for decoding in BGR/RGBA/ARGB/BGRA order, along with
decoding to raw Y'CbCr samples. One can also decode the image directly into a
pre-allocated buffer.
To detect a WebP file and gather the picture's dimensions, the function:
int WebPGetInfo(const uint8_t* data, size_t data_size,
int* width, int* height);
is supplied. No decoding is involved when using it.
Incremental decoding API:
=========================
In the case when data is being progressively transmitted, pictures can still
be incrementally decoded using a slightly more complicated API. Decoder state
is stored into an instance of the WebPIDecoder object. This object can be
created with the purpose of decoding either RGB or Y'CbCr samples.
For instance:
WebPDecBuffer buffer;
WebPInitDecBuffer(&buffer);
buffer.colorspace = MODE_BGR;
...
WebPIDecoder* idec = WebPINewDecoder(&buffer);
As data is made progressively available, this incremental-decoder object
can be used to decode the picture further. There are two (mutually exclusive)
ways to pass freshly arrived data:
either by appending the fresh bytes:
WebPIAppend(idec, fresh_data, size_of_fresh_data);
or by just mentioning the new size of the transmitted data:
WebPIUpdate(idec, buffer, size_of_transmitted_buffer);
Note that 'buffer' can be modified between each call to WebPIUpdate, in
particular when the buffer is resized to accommodate larger data.
These functions will return the decoding status: either VP8_STATUS_SUSPENDED if
decoding is not finished yet or VP8_STATUS_OK when decoding is done. Any other
status is an error condition.
The 'idec' object must always be released (even upon an error condition) by
calling: WebPDelete(idec).
To retrieve partially decoded picture samples, one must use the corresponding
method: WebPIDecGetRGB or WebPIDecGetYUVA.
It will return the last displayable pixel row.
Lastly, note that decoding can also be performed into a pre-allocated pixel
buffer. This buffer must be passed when creating a WebPIDecoder, calling
WebPINewRGB() or WebPINewYUVA().
Please have a look at the src/webp/decode.h header for further details.
Advanced Decoding API:
======================
WebP decoding supports an advanced API which provides on-the-fly cropping and
rescaling, something of great usefulness on memory-constrained environments like
mobile phones. Basically, the memory usage will scale with the output's size,
not the input's, when one only needs a quick preview or a zoomed in portion of
an otherwise too-large picture. Some CPU can be saved too, incidentally.
-------------------------------------- BEGIN PSEUDO EXAMPLE
// A) Init a configuration object
WebPDecoderConfig config;
CHECK(WebPInitDecoderConfig(&config));
// B) optional: retrieve the bitstream's features.
CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
// C) Adjust 'config' options, if needed
config.options.no_fancy_upsampling = 1;
config.options.use_scaling = 1;
config.options.scaled_width = scaledWidth();
config.options.scaled_height = scaledHeight();
// etc.
// D) Specify 'config' output options for specifying output colorspace.
// Optionally the external image decode buffer can also be specified.
config.output.colorspace = MODE_BGRA;
// Optionally, the config.output can be pointed to an external buffer as
// well for decoding the image. This externally supplied memory buffer
// should be big enough to store the decoded picture.
config.output.u.RGBA.rgba = (uint8_t*) memory_buffer;
config.output.u.RGBA.stride = scanline_stride;
config.output.u.RGBA.size = total_size_of_the_memory_buffer;
config.output.is_external_memory = 1;
// E) Decode the WebP image. There are two variants w.r.t decoding image.
// The first one (E.1) decodes the full image and the second one (E.2) is
// used to incrementally decode the image using small input buffers.
// Any one of these steps can be used to decode the WebP image.
// E.1) Decode full image.
CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
// E.2) Decode image incrementally.
WebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config);
CHECK(idec != NULL);
while (bytes_remaining > 0) {
VP8StatusCode status = WebPIAppend(idec, input, bytes_read);
if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
bytes_remaining -= bytes_read;
} else {
break;
}
}
WebPIDelete(idec);
// F) Decoded image is now in config.output (and config.output.u.RGBA).
// It can be saved, displayed or otherwise processed.
// G) Reclaim memory allocated in config's object. It's safe to call
// this function even if the memory is external and wasn't allocated
// by WebPDecode().
WebPFreeDecBuffer(&config.output);
-------------------------------------- END PSEUDO EXAMPLE
Bugs:
=====
Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
Patches welcome! See this page to get started:
http://www.webmproject.org/code/contribute/submitting-patches/
Discuss:
========
Email: webp-discuss@webmproject.org
Web: http://groups.google.com/a/webmproject.org/group/webp-discuss

53
README.md Normal file
View File

@ -0,0 +1,53 @@
# WebP Codec
```
__ __ ____ ____ ____
/ \\/ \/ _ \/ _ )/ _ \
\ / __/ _ \ __/
\__\__/\____/\_____/__/ ____ ___
/ _/ / \ \ / _ \/ _/
/ \_/ / / \ \ __/ \__
\____/____/\_____/_____/____/v1.2.4
```
WebP codec is a library to encode and decode images in WebP format. This package
contains the library that can be used in other programs to add WebP support, as
well as the command line tools 'cwebp' and 'dwebp' to compress and decompress
images respectively.
See https://developers.google.com/speed/webp for details on the image format.
The latest source tree is available at
https://chromium.googlesource.com/webm/libwebp
It is released under the same license as the WebM project. See
https://www.webmproject.org/license/software/ or the "COPYING" file for details.
An additional intellectual property rights grant can be found in the file
PATENTS.
## Building
See the [building documentation](doc/building.md).
## Encoding and Decoding Tools
The examples/ directory contains tools to encode and decode images and
animations, view information about WebP images, and more. See the
[tools documentation](doc/tools.md).
## APIs
See the [APIs documentation](doc/api.md), and API usage examples in the
`examples/` directory.
## Bugs
Please report all bugs to the issue tracker: https://bugs.chromium.org/p/webp
Patches welcome! See [how to contribute](CONTRIBUTING.md).
## Discuss
Email: webp-discuss@webmproject.org
Web: https://groups.google.com/a/webmproject.org/group/webp-discuss

View File

@ -1,223 +0,0 @@
 __ __ ____ ____ ____ __ __ _ __ __
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
\ / __/ _ \ __/ / / (_/ /__
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v0.4.0
Description:
============
WebPMux: set of two libraries 'Mux' and 'Demux' for creation, extraction and
manipulation of an extended format WebP file, which can have features like
color profile, metadata and animation. Reference command-line tools 'webpmux'
and 'vwebp' as well as the WebP container specification
'doc/webp-container-spec.txt' are also provided in this package.
WebP Mux tool:
==============
The examples/ directory contains a tool (webpmux) for manipulating WebP
files. The webpmux tool can be used to create an extended format WebP file and
also to extract or strip relevant data from such a file.
A list of options is available using the -help command line flag:
> webpmux -help
Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT
webpmux -set SET_OPTIONS INPUT -o OUTPUT
webpmux -duration DURATION_OPTIONS [-duration ...]
INPUT -o OUTPUT
webpmux -strip STRIP_OPTIONS INPUT -o OUTPUT
webpmux -frame FRAME_OPTIONS [-frame...] [-loop LOOP_COUNT]
[-bgcolor BACKGROUND_COLOR] -o OUTPUT
webpmux -info INPUT
webpmux [-h|-help]
webpmux -version
GET_OPTIONS:
Extract relevant data:
icc get ICC profile
exif get EXIF metadata
xmp get XMP metadata
frame n get nth frame
SET_OPTIONS:
Set color profile/metadata:
icc file.icc set ICC profile
exif file.exif set EXIF metadata
xmp file.xmp set XMP metadata
where: 'file.icc' contains the ICC profile to be set,
'file.exif' contains the EXIF metadata to be set
'file.xmp' contains the XMP metadata to be set
DURATION_OPTIONS:
Set duration of selected frames:
duration set duration for each frames
duration,frame set duration of a particular frame
duration,start,end set duration of frames in the
interval [start,end])
where: 'duration' is the duration in milliseconds
'start' is the start frame index
'end' is the inclusive end frame index
The special 'end' value '0' means: last frame.
STRIP_OPTIONS:
Strip color profile/metadata:
icc strip ICC profile
exif strip EXIF metadata
xmp strip XMP metadata
FRAME_OPTIONS(i):
Create animation:
file_i +di+[xi+yi[+mi[bi]]]
where: 'file_i' is the i'th animation frame (WebP format),
'di' is the pause duration before next frame,
'xi','yi' specify the image offset for this frame,
'mi' is the dispose method for this frame (0 or 1),
'bi' is the blending method for this frame (+b or -b)
LOOP_COUNT:
Number of times to repeat the animation.
Valid range is 0 to 65535 [Default: 0 (infinite)].
BACKGROUND_COLOR:
Background color of the canvas.
A,R,G,B
where: 'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying
the Alpha, Red, Green and Blue component values respectively
[Default: 255,255,255,255]
INPUT & OUTPUT are in WebP format.
Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be
valid.
Visualization tool:
===================
The examples/ directory also contains a tool (vwebp) for viewing WebP files.
It decodes the image and visualizes it using OpenGL. See the libwebp README
for details on building and running this program.
Mux API:
========
The Mux API contains methods for adding data to and reading data from WebP
files. This API currently supports XMP/EXIF metadata, ICC profile and animation.
Other features may be added in subsequent releases.
Example#1 (pseudo code): Creating a WebPMux object with image data, color
profile and XMP metadata.
int copy_data = 0;
WebPMux* mux = WebPMuxNew();
// ... (Prepare image data).
WebPMuxSetImage(mux, &image, copy_data);
// ... (Prepare ICC profile data).
WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
// ... (Prepare XMP metadata).
WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
// Get data from mux in WebP RIFF format.
WebPMuxAssemble(mux, &output_data);
WebPMuxDelete(mux);
// ... (Consume output_data; e.g. write output_data.bytes to file).
WebPDataClear(&output_data);
Example#2 (pseudo code): Get image and color profile data from a WebP file.
int copy_data = 0;
// ... (Read data from file).
WebPMux* mux = WebPMuxCreate(&data, copy_data);
WebPMuxGetFrame(mux, 1, &image);
// ... (Consume image; e.g. call WebPDecode() to decode the data).
WebPMuxGetChunk(mux, "ICCP", &icc_profile);
// ... (Consume icc_profile).
WebPMuxDelete(mux);
free(data);
For a detailed Mux API reference, please refer to the header file
(src/webp/mux.h).
Demux API:
==========
The Demux API enables extraction of images and extended format data from
WebP files. This API currently supports reading of XMP/EXIF metadata, ICC
profile and animated images. Other features may be added in subsequent
releases.
Code example: Demuxing WebP data to extract all the frames, ICC profile
and EXIF/XMP metadata.
WebPDemuxer* demux = WebPDemux(&webp_data);
uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
// ... (Get information about the features present in the WebP file).
uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
// ... (Iterate over all frames).
WebPIterator iter;
if (WebPDemuxGetFrame(demux, 1, &iter)) {
do {
// ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
// ... and get other frame properties like width, height, offsets etc.
// ... see 'struct WebPIterator' below for more info).
} while (WebPDemuxNextFrame(&iter));
WebPDemuxReleaseIterator(&iter);
}
// ... (Extract metadata).
WebPChunkIterator chunk_iter;
if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
// ... (Consume the ICC profile in 'chunk_iter.chunk').
WebPDemuxReleaseChunkIterator(&chunk_iter);
if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
// ... (Consume the EXIF metadata in 'chunk_iter.chunk').
WebPDemuxReleaseChunkIterator(&chunk_iter);
if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
// ... (Consume the XMP metadata in 'chunk_iter.chunk').
WebPDemuxReleaseChunkIterator(&chunk_iter);
WebPDemuxDelete(demux);
For a detailed Demux API reference, please refer to the header file
(src/webp/demux.h).
AnimEncoder API:
================
The AnimEncoder API can be used to create animated WebP images.
Code example:
WebPAnimEncoderOptions enc_options;
WebPAnimEncoderOptionsInit(&enc_options);
// ... (Tune 'enc_options' as needed).
WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
while(<there are more frames>) {
WebPConfig config;
WebPConfigInit(&config);
// ... (Tune 'config' as needed).
WebPAnimEncoderAdd(enc, frame, duration, &config);
}
WebPAnimEncoderAssemble(enc, webp_data);
WebPAnimEncoderDelete(enc);
// ... (Write the 'webp_data' to a file, or re-mux it further).
For a detailed AnimEncoder API reference, please refer to the header file
(src/webp/mux.h).
Bugs:
=====
Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
Patches welcome! See this page to get started:
http://www.webmproject.org/code/contribute/submitting-patches/
Discuss:
========
Email: webp-discuss@webmproject.org
Web: http://groups.google.com/a/webmproject.org/group/webp-discuss

View File

@ -74,12 +74,22 @@ model {
cCompiler.args "-frename-registers -s"
}
}
// mips32 fails to build with clang from r14b
// https://bugs.chromium.org/p/webp/issues/detail?id=343
if (toolChain in Clang) {
if (getTargetPlatform() == "mips") {
cCompiler.args "-no-integrated-as"
}
}
// Check for NEON usage.
if (getTargetPlatform() == "arm" || getTargetPlatform() == "arm64") {
if (getTargetPlatform() == "arm") {
NEON = "c.neon"
cCompiler.define "HAVE_CPU_FEATURES_H"
} else {
NEON = "c"
}
cCompiler.args "-I" + file(".").absolutePath
}
// Link to pthread for shared libraries.
withType(SharedLibraryBinarySpec) {
@ -95,6 +105,13 @@ model {
sources {
c {
source {
srcDir "sharpyuv"
include "sharpyuv.c"
include "sharpyuv_csp.c"
include "sharpyuv_dsp.c"
include "sharpyuv_gamma.c"
include "sharpyuv_neon.c"
include "sharpyuv_sse2.c"
srcDir "src/dec"
include "alpha_dec.c"
include "buffer_dec.c"
@ -112,9 +129,6 @@ model {
include "alpha_processing_neon.$NEON"
include "alpha_processing_sse2.c"
include "alpha_processing_sse41.c"
include "argb.c"
include "argb_mips_dsp_r2.c"
include "argb_sse2.c"
include "cpu.c"
include "dec.c"
include "dec_clip_tables.c"
@ -134,6 +148,7 @@ model {
include "lossless_msa.c"
include "lossless_neon.$NEON"
include "lossless_sse2.c"
include "lossless_sse41.c"
include "rescaler.c"
include "rescaler_mips32.c"
include "rescaler_mips_dsp_r2.c"
@ -145,10 +160,13 @@ model {
include "upsampling_msa.c"
include "upsampling_neon.$NEON"
include "upsampling_sse2.c"
include "upsampling_sse41.c"
include "yuv.c"
include "yuv_mips32.c"
include "yuv_mips_dsp_r2.c"
include "yuv_neon.$NEON"
include "yuv_sse2.c"
include "yuv_sse41.c"
srcDir "src/utils"
include "bit_reader_utils.c"
include "color_cache_utils.c"
@ -163,9 +181,9 @@ model {
include "cost.c"
include "cost_mips32.c"
include "cost_mips_dsp_r2.c"
include "cost_neon.$NEON"
include "cost_sse2.c"
include "enc.c"
include "enc_avx2.c"
include "enc_mips32.c"
include "enc_mips_dsp_r2.c"
include "enc_msa.c"
@ -179,13 +197,15 @@ model {
include "lossless_enc_neon.$NEON"
include "lossless_enc_sse2.c"
include "lossless_enc_sse41.c"
include "ssim.c"
include "ssim_sse2.c"
srcDir "src/enc"
include "alpha_enc.c"
include "analysis_enc.c"
include "backward_references_cost_enc.c"
include "backward_references_enc.c"
include "config_enc.c"
include "cost_enc.c"
include "delta_palettization_enc.c"
include "filter_enc.c"
include "frame_enc.c"
include "histogram_enc.c"
@ -277,6 +297,7 @@ model {
imagedec(NativeLibrarySpec) {
binaries {
all {
lib library: "webpdemux", linkage: "static"
lib library: "webp", linkage: "static"
}
}
@ -288,6 +309,7 @@ model {
include "jpegdec.c"
include "metadata.c"
include "pngdec.c"
include "pnmdec.c"
include "tiffdec.c"
include "webpdec.c"
}
@ -318,6 +340,7 @@ model {
lib library: "example_util", linkage: "static"
lib library: "imagedec", linkage: "static"
lib library: "imageio_util", linkage: "static"
lib library: "webpdemux", linkage: "static"
lib library: "webp", linkage: "static"
}
}
@ -338,6 +361,7 @@ model {
lib library: "imagedec", linkage: "static"
lib library: "imageenc", linkage: "static"
lib library: "imageio_util", linkage: "static"
lib library: "webpdemux", linkage: "static"
lib library: "webp"
}
}
@ -377,6 +401,7 @@ model {
lib library: "imagedec", linkage: "static"
lib library: "imageio_util", linkage: "static"
lib library: "webpmux", linkage: "static"
lib library: "webpdemux", linkage: "static"
lib library: "webp"
}
}
@ -389,6 +414,24 @@ model {
}
}
}
webpinfo_example(NativeExecutableSpec) {
binaries {
all {
lib library: "example_util", linkage: "static"
lib library: "imageio_util", linkage: "static"
lib library: "webp"
}
}
sources {
c {
source {
srcDir "./examples"
include "webpinfo.c"
}
}
}
}
}
tasks {
// Task to test all possible configurations.
@ -397,8 +440,3 @@ model {
}
}
}
// Task to generate the wrapper.
task wrapper(type: Wrapper) {
gradleVersion = '2.13'
}

16
cmake/WebPConfig.cmake.in Normal file
View File

@ -0,0 +1,16 @@
set(WebP_VERSION @PROJECT_VERSION@)
set(WEBP_VERSION ${WebP_VERSION})
@PACKAGE_INIT@
if(@WEBP_USE_THREAD@)
include(CMakeFindDependencyMacro)
find_dependency(Threads REQUIRED)
endif()
include ("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
set(WebP_INCLUDE_DIRS "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
set(WEBP_INCLUDE_DIRS ${WebP_INCLUDE_DIRS})
set(WebP_LIBRARIES "@INSTALLED_LIBRARIES@")
set(WEBP_LIBRARIES "${WebP_LIBRARIES}")

View File

@ -1,141 +0,0 @@
# Generate the config.h to compile with specific intrinsics / libs.
## Check for compiler options.
include(CheckCSourceCompiles)
check_c_source_compiles("
int main(void) {
(void)__builtin_bswap16(0);
return 0;
}
"
HAVE_BUILTIN_BSWAP16
)
check_c_source_compiles("
int main(void) {
(void)__builtin_bswap32(0);
return 0;
}
"
HAVE_BUILTIN_BSWAP32
)
check_c_source_compiles("
int main(void) {
(void)__builtin_bswap64(0);
return 0;
}
"
HAVE_BUILTIN_BSWAP64
)
## Check for libraries.
find_package(Threads)
if(Threads_FOUND)
if(CMAKE_USE_PTHREADS_INIT)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
endif()
foreach(PTHREAD_TEST HAVE_PTHREAD_PRIO_INHERIT PTHREAD_CREATE_UNDETACHED)
check_c_source_compiles("
#include <pthread.h>
int main (void) {
int attr = ${PTHREAD_TEST};
return attr;
}
" ${PTHREAD_TEST}
)
endforeach()
list(APPEND WEBP_DEP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
endif()
set(WEBP_USE_THREAD ${Threads_FOUND})
# TODO: this seems unused, check with autotools.
set(LT_OBJDIR ".libs/")
# Only useful for vwebp, so useless for now.
# find_package(OpenGL)
# set(WEBP_HAVE_GL ${OPENGL_FOUND})
# set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIRS})
# set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} ${OPENGL_LIBRARIES})
# Find the standard C math library.
find_library(MATH_LIBRARY NAMES m)
if(MATH_LIBRARY)
list(APPEND WEBP_DEP_LIBRARIES ${MATH_LIBRARY})
endif()
# Find the standard image libraries.
set(WEBP_DEP_IMG_LIBRARIES)
set(WEBP_DEP_IMG_INCLUDE_DIRS)
foreach(I_LIB PNG JPEG TIFF GIF)
find_package(${I_LIB})
set(WEBP_HAVE_${I_LIB} ${${I_LIB}_FOUND})
if(${I_LIB}_FOUND)
list(APPEND WEBP_DEP_IMG_LIBRARIES ${${I_LIB}_LIBRARIES})
list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS ${${I_LIB}_INCLUDE_DIRS})
endif()
endforeach()
## Check for specific headers.
include(CheckIncludeFiles)
check_include_files("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS)
check_include_files(dlfcn.h HAVE_DLFCN_H)
check_include_files(GLUT/glut.h HAVE_GLUT_GLUT_H)
check_include_files(GL/glut.h HAVE_GL_GLUT_H)
check_include_files(inttypes.h HAVE_INTTYPES_H)
check_include_files(memory.h HAVE_MEMORY_H)
check_include_files(OpenGL/glut.h HAVE_OPENGL_GLUT_H)
check_include_files(shlwapi.h HAVE_SHLWAPI_H)
check_include_files(stdint.h HAVE_STDINT_H)
check_include_files(stdlib.h HAVE_STDLIB_H)
check_include_files(strings.h HAVE_STRINGS_H)
check_include_files(string.h HAVE_STRING_H)
check_include_files(sys/stat.h HAVE_SYS_STAT_H)
check_include_files(sys/types.h HAVE_SYS_TYPES_H)
check_include_files(unistd.h HAVE_UNISTD_H)
check_include_files(wincodec.h HAVE_WINCODEC_H)
check_include_files(windows.h HAVE_WINDOWS_H)
# Windows specifics
if(HAVE_WINCODEC_H)
list(APPEND WEBP_DEP_LIBRARIES shlwapi ole32 windowscodecs)
endif()
## Check for SIMD extensions.
include(${CMAKE_CURRENT_LIST_DIR}/cpu.cmake)
## Define extra info.
set(PACKAGE ${PROJECT_NAME})
set(PACKAGE_NAME ${PROJECT_NAME})
# Read from configure.ac.
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac CONFIGURE_AC)
string(REGEX MATCHALL "\\[([0-9a-z\\.:/]*)\\]"
CONFIGURE_AC_PACKAGE_INFO ${CONFIGURE_AC}
)
function(strip_bracket VAR)
string(LENGTH ${${VAR}} TMP_LEN)
math(EXPR TMP_LEN ${TMP_LEN}-2)
string(SUBSTRING ${${VAR}} 1 ${TMP_LEN} TMP_SUB)
set(${VAR} ${TMP_SUB} PARENT_SCOPE)
endfunction()
list(GET CONFIGURE_AC_PACKAGE_INFO 1 PACKAGE_VERSION)
strip_bracket(PACKAGE_VERSION)
list(GET CONFIGURE_AC_PACKAGE_INFO 2 PACKAGE_BUGREPORT)
strip_bracket(PACKAGE_BUGREPORT)
list(GET CONFIGURE_AC_PACKAGE_INFO 3 PACKAGE_URL)
strip_bracket(PACKAGE_URL)
# Build more info.
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME ${PACKAGE_NAME})
set(VERSION ${PACKAGE_VERSION})
## Generate the config.h header.
configure_file(${CMAKE_CURRENT_LIST_DIR}/config.h.in
${CMAKE_CURRENT_BINARY_DIR}/include/webp/config.h)
add_definitions(-DHAVE_CONFIG_H)
# The webp folder is included as we reference config.h as
# ../webp/config.h or webp/config.h
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include
${CMAKE_CURRENT_BINARY_DIR}/include/webp
)

View File

@ -13,6 +13,9 @@
/* Set to 1 if __builtin_bswap64 is available */
#cmakedefine HAVE_BUILTIN_BSWAP64 1
/* Define to 1 if you have the <cpu-features.h> header file. */
#cmakedefine HAVE_CPU_FEATURES_H 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#cmakedefine HAVE_DLFCN_H 1
@ -90,22 +93,12 @@
/* Define to the version of this package. */
#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#cmakedefine PTHREAD_CREATE_JOINABLE 1
/* Define to 1 if you have the ANSI C header files. */
#cmakedefine STDC_HEADERS 1
/* Version number of package */
#cmakedefine VERSION "@VERSION@"
/* Enable experimental code */
#cmakedefine WEBP_EXPERIMENTAL_FEATURES 1
/* Set to 1 if AVX2 is supported */
#cmakedefine WEBP_HAVE_AVX2 1
/* Set to 1 if GIF library is installed */
#cmakedefine WEBP_HAVE_GIF 1
@ -115,9 +108,19 @@
/* Set to 1 if JPEG library is installed */
#cmakedefine WEBP_HAVE_JPEG 1
/* Set to 1 if NEON is supported */
#cmakedefine WEBP_HAVE_NEON
/* Set to 1 if runtime detection of NEON is enabled */
/* TODO: handle properly in CMake */
#cmakedefine WEBP_HAVE_NEON_RTCD
/* Set to 1 if PNG library is installed */
#cmakedefine WEBP_HAVE_PNG 1
/* Set to 1 if SDL library is installed */
#cmakedefine WEBP_HAVE_SDL 1
/* Set to 1 if SSE2 is supported */
#cmakedefine WEBP_HAVE_SSE2 1
@ -127,6 +130,9 @@
/* Set to 1 if TIFF library is installed */
#cmakedefine WEBP_HAVE_TIFF 1
/* Enable near lossless encoding */
#cmakedefine WEBP_NEAR_LOSSLESS 1
/* Undefine this to disable thread support. */
#cmakedefine WEBP_USE_THREAD 1

View File

@ -1,7 +1,23 @@
## Check for SIMD extensions.
# Copyright (c) 2021 Google LLC.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
function(webp_check_compiler_flag WEBP_SIMD_FLAG)
# Check for SIMD extensions.
include(CMakePushCheckState)
function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
if(NOT ENABLE_SIMD)
message(STATUS "Disabling ${WEBP_SIMD_FLAG} optimization.")
set(WEBP_HAVE_${WEBP_SIMD_FLAG} 0 PARENT_SCOPE)
return()
endif()
unset(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG} CACHE)
cmake_push_check_state()
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR})
check_c_source_compiles("
#include \"${CMAKE_CURRENT_LIST_DIR}/../src/dsp/dsp.h\"
int main(void) {
@ -10,8 +26,8 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG)
#endif
return 0;
}
" WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG}
)
" WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
cmake_pop_check_state()
if(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
set(WEBP_HAVE_${WEBP_SIMD_FLAG} 1 PARENT_SCOPE)
else()
@ -20,16 +36,26 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG)
endfunction()
# those are included in the names of WEBP_USE_* in c++ code.
set(WEBP_SIMD_FLAGS "SSE2;SSE41;AVX2;MIPS32;MIPS_DSP_R2;NEON;MSA")
set(WEBP_SIMD_FILE_EXTENSIONS "_sse2.c;_sse41.c;_avx2.c;_mips32.c;_mips_dsp_r2.c;_neon.c;_msa.c")
if(MSVC)
# MSVC does not have a SSE4 flag but AVX2 support implies
# SSE4 support.
set(SIMD_ENABLE_FLAGS "/arch:SSE2;/arch:AVX2;/arch:AVX2;;;;")
set(WEBP_SIMD_FLAGS "SSE41;SSE2;MIPS32;MIPS_DSP_R2;NEON;MSA")
set(WEBP_SIMD_FILE_EXTENSIONS
"_sse41.c;_sse2.c;_mips32.c;_mips_dsp_r2.c;_neon.c;_msa.c")
if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "MSVC")
# With at least Visual Studio 12 (2013)+ /arch is not necessary to build SSE2
# or SSE4 code unless a lesser /arch is forced. MSVC does not have a SSE4
# flag, but an AVX one. Using that with SSE4 code risks generating illegal
# instructions when used on machines with SSE4 only. The flags are left for
# older (untested) versions to avoid any potential compatibility issues.
if(MSVC_VERSION GREATER_EQUAL 1800 AND NOT CMAKE_C_FLAGS MATCHES "/arch:")
set(SIMD_ENABLE_FLAGS)
else()
set(SIMD_ENABLE_FLAGS "/arch:AVX;/arch:SSE2;;;;")
endif()
set(SIMD_DISABLE_FLAGS)
else()
set(SIMD_ENABLE_FLAGS "-msse2;-msse4.1;-mavx2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
set(SIMD_DISABLE_FLAGS "-mno-sse2;-mno-sse4.1;-mno-avx2;;-mno-dspr2;;-mno-msa")
set(SIMD_ENABLE_FLAGS
"-msse4.1;-msse2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
set(SIMD_DISABLE_FLAGS
"-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa")
endif()
set(WEBP_SIMD_FILES_TO_NOT_INCLUDE)
@ -38,10 +64,9 @@ set(WEBP_SIMD_FLAGS_TO_INCLUDE)
if(${ANDROID})
if(${ANDROID_ABI} STREQUAL "armeabi-v7a")
# This is because Android studio uses the configuration
# "-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
# that does not trigger neon optimizations but should
# (as this configuration does not exist anymore).
# This is because Android studio uses the configuration "-march=armv7-a
# -mfloat-abi=softfp -mfpu=vfpv3-d16" that does not trigger neon
# optimizations but should (as this configuration does not exist anymore).
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon ")
endif()
endif()
@ -50,25 +75,40 @@ list(LENGTH WEBP_SIMD_FLAGS WEBP_SIMD_FLAGS_LENGTH)
math(EXPR WEBP_SIMD_FLAGS_RANGE "${WEBP_SIMD_FLAGS_LENGTH} - 1")
foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
# With Emscripten 2.0.9 -msimd128 -mfpu=neon will enable NEON, but the
# source will fail to compile.
if(EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 2)
break()
endif()
list(GET WEBP_SIMD_FLAGS ${I_SIMD} WEBP_SIMD_FLAG)
# First try with no extra flag added as the compiler might have default flags
# (especially on Android).
unset(WEBP_HAVE_${WEBP_SIMD_FLAG} CACHE)
cmake_push_check_state()
set(CMAKE_REQUIRED_FLAGS)
webp_check_compiler_flag(${WEBP_SIMD_FLAG})
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
if(EMSCRIPTEN)
set(SIMD_COMPILE_FLAG "-msimd128 ${SIMD_COMPILE_FLAG}")
endif()
set(CMAKE_REQUIRED_FLAGS ${SIMD_COMPILE_FLAG})
webp_check_compiler_flag(${WEBP_SIMD_FLAG})
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
else()
set(SIMD_COMPILE_FLAG " ")
if(MSVC AND SIMD_ENABLE_FLAGS)
# The detection for SSE2/SSE4 support under MSVC is based on the compiler
# version so e.g., clang-cl will require flags to enable the assembly.
list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
else()
set(SIMD_COMPILE_FLAG " ")
endif()
endif()
# Check which files we should include or not.
list(GET WEBP_SIMD_FILE_EXTENSIONS ${I_SIMD} WEBP_SIMD_FILE_EXTENSION)
file(GLOB SIMD_FILES "${CMAKE_CURRENT_LIST_DIR}/../"
"src/dsp/*${WEBP_SIMD_FILE_EXTENSION}"
)
"src/dsp/*${WEBP_SIMD_FILE_EXTENSION}")
if(WEBP_HAVE_${WEBP_SIMD_FLAG})
# Memorize the file and flags.
foreach(FILE ${SIMD_FILES})
@ -85,6 +125,12 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
list(GET SIMD_DISABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
include(CheckCCompilerFlag)
if(SIMD_COMPILE_FLAG)
# Between 3.17.0 and 3.18.2 check_cxx_compiler_flag() sets a normal
# variable at parent scope while check_cxx_source_compiles() continues
# to set an internal cache variable, so we unset both to avoid the
# failure / success state persisting between checks. See
# https://gitlab.kitware.com/cmake/cmake/-/issues/21207.
unset(HAS_COMPILE_FLAG)
unset(HAS_COMPILE_FLAG CACHE)
check_c_compiler_flag(${SIMD_COMPILE_FLAG} HAS_COMPILE_FLAG)
if(HAS_COMPILE_FLAG)
@ -96,11 +142,13 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
set(COMMON_PATTERNS)
endif()
set(CMAKE_REQUIRED_DEFINITIONS ${SIMD_COMPILE_FLAG})
check_c_source_compiles("int main(void) {return 0;}" FLAG2
FAIL_REGEX "warning: argument unused during compilation:"
${COMMON_PATTERNS}
)
if(NOT FLAG2)
check_c_source_compiles("int main(void) {return 0;}"
FLAG_${SIMD_COMPILE_FLAG}
FAIL_REGEX
"warning: argument unused during compilation:"
${COMMON_PATTERNS})
if(NOT FLAG_${SIMD_COMPILE_FLAG})
unset(HAS_COMPILE_FLAG)
unset(HAS_COMPILE_FLAG CACHE)
endif()
endif()
@ -110,4 +158,5 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
endif()
endif()
endif()
cmake_pop_check_state()
endforeach()

185
cmake/deps.cmake Normal file
View File

@ -0,0 +1,185 @@
# Copyright (c) 2021 Google LLC.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
# Generate the config.h to compile with specific intrinsics / libs.
# Check for compiler options.
include(CheckCSourceCompiles)
check_c_source_compiles("
int main(void) {
(void)__builtin_bswap16(0);
return 0;
}
" HAVE_BUILTIN_BSWAP16)
check_c_source_compiles("
int main(void) {
(void)__builtin_bswap32(0);
return 0;
}
" HAVE_BUILTIN_BSWAP32)
check_c_source_compiles("
int main(void) {
(void)__builtin_bswap64(0);
return 0;
}
" HAVE_BUILTIN_BSWAP64)
# Check for libraries.
if(WEBP_USE_THREAD)
find_package(Threads)
if(Threads_FOUND)
# work around cmake bug on QNX (https://cmake.org/Bug/view.php?id=11333)
if(CMAKE_USE_PTHREADS_INIT AND NOT CMAKE_SYSTEM_NAME STREQUAL "QNX")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
endif()
check_c_source_compiles("
#include <pthread.h>
int main (void) {
int attr = PTHREAD_PRIO_INHERIT;
return attr;
}
" FLAG_HAVE_PTHREAD_PRIO_INHERIT)
set(HAVE_PTHREAD_PRIO_INHERIT ${FLAG_HAVE_PTHREAD_PRIO_INHERIT})
list(APPEND WEBP_DEP_LIBRARIES Threads::Threads)
endif()
set(WEBP_USE_THREAD ${Threads_FOUND})
endif()
# TODO: this seems unused, check with autotools.
set(LT_OBJDIR ".libs/")
# Only useful for vwebp, so useless for now.
find_package(OpenGL)
set(WEBP_HAVE_GL ${OPENGL_FOUND})
# Check if we need to link to the C math library. We do not look for it as it is
# not found when cross-compiling, while it is here.
check_c_source_compiles("
#include <math.h>
int main(int argc, char** argv) {
return (int)pow(argc, 2.5);
}
" HAVE_MATH_LIBRARY)
if(NOT HAVE_MATH_LIBRARY)
message(STATUS "Adding -lm flag.")
list(APPEND WEBP_DEP_LIBRARIES m)
endif()
# Find the standard image libraries.
set(WEBP_DEP_IMG_LIBRARIES)
set(WEBP_DEP_IMG_INCLUDE_DIRS)
foreach(I_LIB PNG JPEG TIFF)
# Disable tiff when compiling in static mode as it is failing on Ubuntu.
if(WEBP_LINK_STATIC AND ${I_LIB} STREQUAL "TIFF")
message("TIFF is disabled when statically linking.")
continue()
endif()
find_package(${I_LIB})
set(WEBP_HAVE_${I_LIB} ${${I_LIB}_FOUND})
if(${I_LIB}_FOUND)
list(APPEND WEBP_DEP_IMG_LIBRARIES ${${I_LIB}_LIBRARIES})
list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS ${${I_LIB}_INCLUDE_DIR}
${${I_LIB}_INCLUDE_DIRS})
endif()
endforeach()
if(WEBP_DEP_IMG_INCLUDE_DIRS)
list(REMOVE_DUPLICATES WEBP_DEP_IMG_INCLUDE_DIRS)
endif()
# GIF detection, gifdec isn't part of the imageio lib.
include(CMakePushCheckState)
set(WEBP_DEP_GIF_LIBRARIES)
set(WEBP_DEP_GIF_INCLUDE_DIRS)
find_package(GIF)
set(WEBP_HAVE_GIF ${GIF_FOUND})
if(GIF_FOUND)
# GIF find_package only locates the header and library, it doesn't fail
# compile tests when detecting the version, but falls back to 3 (as of at
# least cmake 3.7.2). Make sure the library links to avoid incorrect detection
# when cross compiling.
cmake_push_check_state()
set(CMAKE_REQUIRED_LIBRARIES ${GIF_LIBRARIES})
set(CMAKE_REQUIRED_INCLUDES ${GIF_INCLUDE_DIR})
check_c_source_compiles("
#include <gif_lib.h>
int main(void) {
(void)DGifOpenFileHandle;
return 0;
}
" GIF_COMPILES)
cmake_pop_check_state()
if(GIF_COMPILES)
list(APPEND WEBP_DEP_GIF_LIBRARIES ${GIF_LIBRARIES})
list(APPEND WEBP_DEP_GIF_INCLUDE_DIRS ${GIF_INCLUDE_DIR})
else()
unset(GIF_FOUND)
endif()
endif()
# Check for specific headers.
include(CheckIncludeFiles)
check_include_files("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS)
check_include_files(dlfcn.h HAVE_DLFCN_H)
check_include_files(GLUT/glut.h HAVE_GLUT_GLUT_H)
check_include_files(GL/glut.h HAVE_GL_GLUT_H)
check_include_files(inttypes.h HAVE_INTTYPES_H)
check_include_files(memory.h HAVE_MEMORY_H)
check_include_files(OpenGL/glut.h HAVE_OPENGL_GLUT_H)
check_include_files(shlwapi.h HAVE_SHLWAPI_H)
check_include_files(stdint.h HAVE_STDINT_H)
check_include_files(stdlib.h HAVE_STDLIB_H)
check_include_files(strings.h HAVE_STRINGS_H)
check_include_files(string.h HAVE_STRING_H)
check_include_files(sys/stat.h HAVE_SYS_STAT_H)
check_include_files(sys/types.h HAVE_SYS_TYPES_H)
check_include_files(unistd.h HAVE_UNISTD_H)
check_include_files(wincodec.h HAVE_WINCODEC_H)
check_include_files(windows.h HAVE_WINDOWS_H)
# Windows specifics
if(HAVE_WINCODEC_H)
list(APPEND WEBP_DEP_LIBRARIES
shlwapi
ole32
windowscodecs)
endif()
# Check for SIMD extensions.
include(${CMAKE_CURRENT_LIST_DIR}/cpu.cmake)
# Define extra info.
set(PACKAGE ${PROJECT_NAME})
set(PACKAGE_NAME ${PROJECT_NAME})
# Read from configure.ac.
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac CONFIGURE_AC)
string(REGEX MATCHALL
"\\[([0-9a-z\\.:/]*)\\]"
CONFIGURE_AC_PACKAGE_INFO
${CONFIGURE_AC})
function(strip_bracket VAR)
string(LENGTH ${${VAR}} TMP_LEN)
math(EXPR TMP_LEN ${TMP_LEN}-2)
string(SUBSTRING ${${VAR}}
1
${TMP_LEN}
TMP_SUB)
set(${VAR} ${TMP_SUB} PARENT_SCOPE)
endfunction()
list(GET CONFIGURE_AC_PACKAGE_INFO 1 PACKAGE_VERSION)
strip_bracket(PACKAGE_VERSION)
list(GET CONFIGURE_AC_PACKAGE_INFO 2 PACKAGE_BUGREPORT)
strip_bracket(PACKAGE_BUGREPORT)
list(GET CONFIGURE_AC_PACKAGE_INFO 3 PACKAGE_URL)
strip_bracket(PACKAGE_URL)
# Build more info.
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME ${PACKAGE_NAME})
set(VERSION ${PACKAGE_VERSION})

4
codereview.settings Normal file
View File

@ -0,0 +1,4 @@
# This file is used by git cl to get repository specific information.
GERRIT_HOST: True
CODE_REVIEW_SERVER: chromium-review.googlesource.com
GERRIT_SQUASH_UPLOADS: False

View File

@ -1,6 +1,6 @@
AC_INIT([libwebp], [0.6.0],
AC_INIT([libwebp], [1.2.4],
[https://bugs.chromium.org/p/webp],,
[http://developers.google.com/speed/webp])
[https://developers.google.com/speed/webp])
AC_CANONICAL_HOST
AC_PREREQ([2.60])
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
@ -9,7 +9,8 @@ dnl === automake >= 1.12 requires this for 'unusual archivers' support.
dnl === it must occur before LT_INIT (AC_PROG_LIBTOOL).
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_PROG_LIBTOOL
dnl === AC_PROG_LIBTOOL is deprecated.
m4_ifdef([LT_INIT], [LT_INIT], [AC_PROG_LIBTOOL])
AC_PROG_SED
AM_PROG_CC_C_O
@ -27,11 +28,46 @@ AC_ARG_ENABLE([everything],
AS_HELP_STRING([--enable-everything],
[Enable all optional targets. These can still be
disabled with --disable-target]),
[SET_IF_UNSET([enable_libwebpdecoder], [$enableval])
[SET_IF_UNSET([enable_libsharpyuv], [$enableval])
SET_IF_UNSET([enable_libwebpdecoder], [$enableval])
SET_IF_UNSET([enable_libwebpdemux], [$enableval])
SET_IF_UNSET([enable_libwebpextras], [$enableval])
SET_IF_UNSET([enable_libwebpmux], [$enableval])])
dnl === Check whether libwebpmux should be built
AC_MSG_CHECKING(whether libwebpmux is to be built)
AC_ARG_ENABLE([libwebpmux],
AS_HELP_STRING([--disable-libwebpmux],
[Disable libwebpmux @<:@default=no@:>@]),
[], [enable_libwebpmux=yes])
AC_MSG_RESULT(${enable_libwebpmux-no})
AM_CONDITIONAL([BUILD_MUX], [test "$enable_libwebpmux" = "yes"])
dnl === Check whether libwebpdemux should be built
AC_MSG_CHECKING(whether libwebpdemux is to be built)
AC_ARG_ENABLE([libwebpdemux],
AS_HELP_STRING([--disable-libwebpdemux],
[Disable libwebpdemux @<:@default=no@:>@]),
[], [enable_libwebpdemux=yes])
AC_MSG_RESULT(${enable_libwebpdemux-no})
AM_CONDITIONAL([BUILD_DEMUX], [test "$enable_libwebpdemux" = "yes"])
dnl === Check whether decoder library should be built.
AC_MSG_CHECKING(whether decoder library is to be built)
AC_ARG_ENABLE([libwebpdecoder],
AS_HELP_STRING([--enable-libwebpdecoder],
[Build libwebpdecoder @<:@default=no@:>@]))
AC_MSG_RESULT(${enable_libwebpdecoder-no})
AM_CONDITIONAL([BUILD_LIBWEBPDECODER], [test "$enable_libwebpdecoder" = "yes"])
dnl === Check whether libwebpextras should be built
AC_MSG_CHECKING(whether libwebpextras is to be built)
AC_ARG_ENABLE([libwebpextras],
AS_HELP_STRING([--enable-libwebpextras],
[Build libwebpextras @<:@default=no@:>@]))
AC_MSG_RESULT(${enable_libwebpextras-no})
AM_CONDITIONAL([BUILD_EXTRAS], [test "$enable_libwebpextras" = "yes"])
dnl === If --enable-asserts is not defined, define NDEBUG
AC_MSG_CHECKING(whether asserts are enabled)
@ -67,6 +103,7 @@ AC_DEFUN([TEST_AND_ADD_CFLAGS],
CFLAGS="$SAVED_CFLAGS"])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-fvisibility=hidden])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wall])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wconstant-conversion])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wdeclaration-after-statement])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wextra])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wfloat-conversion])
@ -75,8 +112,11 @@ TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wformat -Wformat-security])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wmissing-declarations])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wmissing-prototypes])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wold-style-definition])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wparentheses-equality])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshadow])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshorten-64-to-32])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wundef])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunreachable-code-aggressive])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunreachable-code])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused-but-set-variable])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused])
@ -119,31 +159,6 @@ AS_IF([test "$GCC" = "yes" ], [
AC_SUBST([AM_CFLAGS])
dnl === Check for machine specific flags
AC_ARG_ENABLE([avx2],
AS_HELP_STRING([--disable-avx2],
[Disable detection of AVX2 support
@<:@default=auto@:>@]))
AS_IF([test "x$enable_avx2" != "xno" -a "x$enable_sse4_1" != "xno" \
-a "x$enable_sse2" != "xno"], [
AVX2_CFLAGS="$INTRINSICS_CFLAGS $AVX2_FLAGS"
TEST_AND_ADD_CFLAGS([AVX2_FLAGS], [-mavx2])
AS_IF([test -n "$AVX2_FLAGS"], [
SAVED_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS $AVX2_FLAGS"
AC_CHECK_HEADER([immintrin.h],
[AC_DEFINE(WEBP_HAVE_AVX2, [1],
[Set to 1 if AVX2 is supported])],
[AVX2_FLAGS=""],
dnl it's illegal to directly include avx2intrin.h, but it's
dnl included conditionally in immintrin.h, tricky!
[#ifndef __AVX2__
#error avx2 is not enabled
#endif
])
CFLAGS=$SAVED_CFLAGS])
AC_SUBST([AVX2_FLAGS])])
AC_ARG_ENABLE([sse4.1],
AS_HELP_STRING([--disable-sse4.1],
[Disable detection of SSE4.1 support
@ -241,9 +256,16 @@ AS_IF([test "x$enable_neon" != "xno"], [
NEON_FLAGS=""],
[AC_DEFINE(WEBP_HAVE_NEON_RTCD, [1],
[Set to 1 if runtime detection of NEON is enabled])])])
;;
esac
AC_SUBST([NEON_FLAGS])])
case "$host_os" in
*android*) AC_CHECK_HEADERS([cpu-features.h]) ;;
esac
;;
aarch64*|arm64*)
AC_DEFINE(WEBP_HAVE_NEON, [1], [Set to 1 if NEON is supported])
;;
esac
AC_SUBST([NEON_FLAGS])])
dnl === CLEAR_LIBVARS([var_pfx])
dnl === Clears <var_pfx>_{INCLUDES,LIBS}.
@ -340,6 +362,8 @@ AS_IF([test "x$enable_gl" != "xno"], [
# override with --with-gl*
glut_cflags="$glut_cflags|-framework GLUT -framework OpenGL"
glut_ldflags="$glut_ldflags|-framework GLUT -framework OpenGL"
# quiet deprecation warnings for glut
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wno-deprecated-declarations])
;;
esac
@ -424,10 +448,75 @@ AS_IF([test "x$enable_gl" != "xno"], [
if test "$glut_support" = "yes" -a "$enable_libwebpdemux" = "yes"; then
build_vwebp=yes
else
AC_MSG_NOTICE(
m4_normalize([Not building vwebp.
OpenGL libraries and --enable-libwebpdemux are required.]))
fi
])
AM_CONDITIONAL([BUILD_VWEBP], [test "$build_vwebp" = "yes"])
dnl === check for SDL support ===
AC_ARG_ENABLE([sdl],
AS_HELP_STRING([--disable-sdl],
[Disable detection of SDL support
@<:@default=auto@:>@]))
AS_IF([test "x$enable_sdl" != "xno"], [
CLEAR_LIBVARS([SDL])
AC_PATH_PROGS([LIBSDL_CONFIG], [sdl-config])
if test -n "$LIBSDL_CONFIG"; then
SDL_INCLUDES=`$LIBSDL_CONFIG --cflags`
SDL_LIBS="`$LIBSDL_CONFIG --libs`"
fi
WITHLIB_OPTION([sdl], [SDL])
sdl_header="no"
LIBCHECK_PROLOGUE([SDL])
AC_CHECK_HEADER([SDL/SDL.h], [sdl_header="SDL/SDL.h"],
[AC_CHECK_HEADER([SDL.h], [sdl_header="SDL.h"],
[AC_MSG_WARN(SDL library not available - no sdl.h)])])
if test x"$sdl_header" != "xno"; then
AC_LANG_PUSH(C)
SDL_SAVED_LIBS="$LIBS"
for lib in "" "-lSDL" "-lSDLmain -lSDL"; do
LIBS="$SDL_SAVED_LIBS $lib"
# Perform a full link to ensure SDL_main is resolved if needed.
AC_LINK_IFELSE(
[AC_LANG_SOURCE([
#include <$sdl_header>
int main(int argc, char** argv) {
SDL_Init(0);
return 0;
}])],
[SDL_LIBS="$LDFLAGS $LIBS"
SDL_INCLUDES="$SDL_INCLUDES -DWEBP_HAVE_SDL"
AC_DEFINE(WEBP_HAVE_SDL, [1],
[Set to 1 if SDL library is installed])
sdl_support=yes]
)
if test x"$sdl_support" = "xyes"; then
break
fi
done
# LIBS is restored by LIBCHECK_EPILOGUE
AC_LANG_POP
if test x"$sdl_header" = "xSDL.h"; then
SDL_INCLUDES="$SDL_INCLUDES -DWEBP_HAVE_JUST_SDL_H"
fi
fi
LIBCHECK_EPILOGUE([SDL])
if test x"$sdl_support" = "xyes"; then
build_vwebp_sdl=yes
else
AC_MSG_NOTICE([Not building vwebp-sdl. SDL library is required.])
fi
])
AM_CONDITIONAL([BUILD_VWEBP_SDL], [test "$build_vwebp_sdl" = "yes"])
dnl === check for PNG support ===
AC_ARG_ENABLE([png], AS_HELP_STRING([--disable-png],
@ -545,22 +634,39 @@ AS_IF([test "x$enable_gif" != "xno"], [
if test "$gif_support" = "yes" -a \
"$enable_libwebpdemux" = "yes"; then
build_animdiff=yes
build_anim_diff=yes
else
AC_MSG_NOTICE(
[Not building anim_diff. libgif and --enable-libwebpdemux are required.])
fi
if test "$gif_support" = "yes" -a \
"$enable_libwebpmux" = "yes"; then
build_gif2webp=yes
else
AC_MSG_NOTICE(
[Not building gif2webp. libgif and --enable-libwebpmux are required.])
fi
])
AM_CONDITIONAL([BUILD_ANIMDIFF], [test "${build_animdiff}" = "yes"])
AM_CONDITIONAL([BUILD_ANIMDIFF], [test "${build_anim_diff}" = "yes"])
AM_CONDITIONAL([BUILD_GIF2WEBP], [test "${build_gif2webp}" = "yes"])
if test "$enable_libwebpmux" = "yes"; then
if test "$enable_libwebpdemux" = "yes" -a "$enable_libwebpmux" = "yes"; then
build_img2webp=yes
else
AC_MSG_NOTICE(
m4_normalize([Not building img2webp.
--enable-libwebpdemux & --enable-libwebpmux are required.]))
fi
AM_CONDITIONAL([BUILD_IMG2WEBP], [test "${build_img2webp}" = "yes"])
if test "$enable_libwebpmux" = "yes"; then
build_webpinfo=yes
else
AC_MSG_NOTICE([Not building webpinfo. --enable-libwebpdemux is required.])
fi
AM_CONDITIONAL([BUILD_WEBPINFO], [test "${build_webpinfo}" = "yes"])
dnl === check for WIC support ===
AC_ARG_ENABLE([wic],
@ -613,7 +719,7 @@ if test "$enable_wic" = "yes"; then
fi
esac
dnl === If --enable-swap-16bit-csp is defined, add -DWEBP_SWAP_16BIT_CSP
dnl === If --enable-swap-16bit-csp is defined, add -DWEBP_SWAP_16BIT_CSP=1
USE_SWAP_16BIT_CSP=""
AC_MSG_CHECKING(if --enable-swap-16bit-csp option is specified)
@ -621,55 +727,25 @@ AC_ARG_ENABLE([swap-16bit-csp],
AS_HELP_STRING([--enable-swap-16bit-csp],
[Enable byte swap for 16 bit colorspaces]))
if test "$enable_swap_16bit_csp" = "yes"; then
USE_SWAP_16BIT_CSP="-DWEBP_SWAP_16BIT_CSP"
USE_SWAP_16BIT_CSP="-DWEBP_SWAP_16BIT_CSP=1"
fi
AC_MSG_RESULT(${enable_swap_16bit_csp-no})
AC_SUBST(USE_SWAP_16BIT_CSP)
dnl === If --enable-experimental is defined, add -DWEBP_EXPERIMENTAL_FEATURES
dnl === If --disable-near-lossless is defined, add -DWEBP_NEAR_LOSSLESS=0
USE_EXPERIMENTAL_CODE=""
AC_MSG_CHECKING(if --enable-experimental option is specified)
AC_ARG_ENABLE([experimental], AS_HELP_STRING([--enable-experimental],
[Activate experimental features]))
if test "$enable_experimental" = "yes"; then
AC_DEFINE(WEBP_EXPERIMENTAL_FEATURES, [1], [Enable experimental code])
USE_EXPERIMENTAL_CODE="-DWEBP_EXPERIMENTAL_FEATURES"
AC_DEFINE(WEBP_NEAR_LOSSLESS, [1], [Enable near lossless encoding])
AC_MSG_CHECKING(if --disable-near-lossless option is specified)
AC_ARG_ENABLE([near_lossless],
AS_HELP_STRING([--disable-near-lossless],
[Disable near lossless encoding]),
[], [enable_near_lossless=yes])
if test "$enable_near_lossless" = "no"; then
AC_DEFINE(WEBP_NEAR_LOSSLESS, [0], [Enable near lossless encoding])
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
AC_MSG_RESULT(${enable_experimental-no})
AC_SUBST(USE_EXPERIMENTAL_CODE)
dnl === Check whether libwebpmux should be built
AC_MSG_CHECKING(whether libwebpmux is to be built)
AC_ARG_ENABLE([libwebpmux],
AS_HELP_STRING([--enable-libwebpmux],
[Build libwebpmux @<:@default=no@:>@]))
AC_MSG_RESULT(${enable_libwebpmux-no})
AM_CONDITIONAL([WANT_MUX], [test "$enable_libwebpmux" = "yes"])
dnl === Check whether libwebpdemux should be built
AC_MSG_CHECKING(whether libwebpdemux is to be built)
AC_ARG_ENABLE([libwebpdemux],
AS_HELP_STRING([--enable-libwebpdemux],
[Build libwebpdemux @<:@default=no@:>@]))
AC_MSG_RESULT(${enable_libwebpdemux-no})
AM_CONDITIONAL([WANT_DEMUX], [test "$enable_libwebpdemux" = "yes"])
dnl === Check whether decoder library should be built.
AC_MSG_CHECKING(whether decoder library is to be built)
AC_ARG_ENABLE([libwebpdecoder],
AS_HELP_STRING([--enable-libwebpdecoder],
[Build libwebpdecoder @<:@default=no@:>@]))
AC_MSG_RESULT(${enable_libwebpdecoder-no})
AM_CONDITIONAL([BUILD_LIBWEBPDECODER], [test "$enable_libwebpdecoder" = "yes"])
dnl === Check whether libwebpextras should be built
AC_MSG_CHECKING(whether libwebpextras is to be built)
AC_ARG_ENABLE([libwebpextras],
AS_HELP_STRING([--enable-libwebpextras],
[Build libwebpextras @<:@default=no@:>@]))
AC_MSG_RESULT(${enable_libwebpextras-no})
AM_CONDITIONAL([WANT_EXTRAS], [test "$enable_libwebpextras" = "yes"])
dnl =========================
@ -677,6 +753,7 @@ AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([src/webp/config.h])
AC_CONFIG_FILES([Makefile src/Makefile man/Makefile \
examples/Makefile extras/Makefile imageio/Makefile \
sharpyuv/Makefile \
src/dec/Makefile src/enc/Makefile src/dsp/Makefile \
src/demux/Makefile src/mux/Makefile \
src/utils/Makefile \
@ -700,22 +777,25 @@ libwebpmux: ${enable_libwebpmux-no}
libwebpextras: ${enable_libwebpextras-no}
Tools:
cwebp : yes
cwebp : ${enable_libwebpdemux-no}
Input format support
====================
JPEG : ${jpeg_support-no}
PNG : ${png_support-no}
TIFF : ${tiff_support-no}
WIC : ${wic_support-no}
dwebp : yes
dwebp : ${enable_libwebpdemux-no}
Output format support
=====================
PNG : ${png_support-no}
WIC : ${wic_support-no}
GIF support : ${gif_support-no}
anim_diff : ${build_animdiff-no}
anim_diff : ${build_anim_diff-no}
gif2webp : ${build_gif2webp-no}
img2webp : ${build_img2webp-no}
webpmux : ${enable_libwebpmux-no}
vwebp : ${build_vwebp-no}
webpinfo : ${build_webpinfo-no}
SDL support : ${sdl_support-no}
vwebp_sdl : ${build_vwebp_sdl-no}
])

View File

@ -1,29 +0,0 @@
Generate libwebp Container Spec Docs from Text Source
=====================================================
HTML generation requires kramdown [1], easily installed as a
rubygem [2]. Rubygems installation should satisfy dependencies
automatically.
[1]: http://kramdown.rubyforge.org/
[2]: http://rubygems.org/
HTML generation can then be done from the project root:
$ kramdown doc/webp-container-spec.txt --template doc/template.html > \
doc/output/webp-container-spec.html
kramdown can optionally syntax highlight code blocks, using CodeRay [3],
a dependency of kramdown that rubygems will install automatically. The
following will apply inline CSS styling; an external stylesheet is not
needed.
$ kramdown doc/webp-lossless-bitstream-spec.txt --template \
doc/template.html --coderay-css style --coderay-line-numbers ' ' \
--coderay-default-lang c > \
doc/output/webp-lossless-bitstream-spec.html
Optimally, use kramdown 0.13.7 or newer if syntax highlighting desired.
[3]: http://coderay.rubychan.de/

385
doc/api.md Normal file
View File

@ -0,0 +1,385 @@
# WebP APIs
## Encoding API
The main encoding functions are available in the header src/webp/encode.h
The ready-to-use ones are:
```c
size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride,
float quality_factor, uint8_t** output);
size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride,
float quality_factor, uint8_t** output);
size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride,
float quality_factor, uint8_t** output);
size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride,
float quality_factor, uint8_t** output);
```
They will convert raw RGB samples to a WebP data. The only control supplied is
the quality factor.
There are some variants for using the lossless format:
```c
size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height,
int stride, uint8_t** output);
size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height,
int stride, uint8_t** output);
size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height,
int stride, uint8_t** output);
size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height,
int stride, uint8_t** output);
```
Of course in this case, no quality factor is needed since the compression occurs
without loss of the input values, at the expense of larger output sizes.
### Advanced encoding API
A more advanced API is based on the WebPConfig and WebPPicture structures.
WebPConfig contains the encoding settings and is not tied to a particular
picture. WebPPicture contains input data, on which some WebPConfig will be used
for compression. The encoding flow looks like:
```c
#include <webp/encode.h>
// Setup a config, starting form a preset and tuning some additional
// parameters
WebPConfig config;
if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor)) {
return 0; // version error
}
// ... additional tuning
config.sns_strength = 90;
config.filter_sharpness = 6;
config_error = WebPValidateConfig(&config); // not mandatory, but useful
// Setup the input data
WebPPicture pic;
if (!WebPPictureInit(&pic)) {
return 0; // version error
}
pic.width = width;
pic.height = height;
// allocated picture of dimension width x height
if (!WebPPictureAlloc(&pic)) {
return 0; // memory error
}
// at this point, 'pic' has been initialized as a container,
// and can receive the Y/U/V samples.
// Alternatively, one could use ready-made import functions like
// WebPPictureImportRGB(), which will take care of memory allocation.
// In any case, past this point, one will have to call
// WebPPictureFree(&pic) to reclaim memory.
// Set up a byte-output write method. WebPMemoryWriter, for instance.
WebPMemoryWriter wrt;
WebPMemoryWriterInit(&wrt); // initialize 'wrt'
pic.writer = MyFileWriter;
pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
// Compress!
int ok = WebPEncode(&config, &pic); // ok = 0 => error occurred!
WebPPictureFree(&pic); // must be called independently of the 'ok' result.
// output data should have been handled by the writer at that point.
// -> compressed data is the memory buffer described by wrt.mem / wrt.size
// deallocate the memory used by compressed data
WebPMemoryWriterClear(&wrt);
```
## Decoding API
This is mainly just one function to call:
```c
#include "webp/decode.h"
uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
int* width, int* height);
```
Please have a look at the file src/webp/decode.h for the details. There are
variants for decoding in BGR/RGBA/ARGB/BGRA order, along with decoding to raw
Y'CbCr samples. One can also decode the image directly into a pre-allocated
buffer.
To detect a WebP file and gather the picture's dimensions, the function:
```c
int WebPGetInfo(const uint8_t* data, size_t data_size,
int* width, int* height);
```
is supplied. No decoding is involved when using it.
### Incremental decoding API
In the case when data is being progressively transmitted, pictures can still be
incrementally decoded using a slightly more complicated API. Decoder state is
stored into an instance of the WebPIDecoder object. This object can be created
with the purpose of decoding either RGB or Y'CbCr samples. For instance:
```c
WebPDecBuffer buffer;
WebPInitDecBuffer(&buffer);
buffer.colorspace = MODE_BGR;
...
WebPIDecoder* idec = WebPINewDecoder(&buffer);
```
As data is made progressively available, this incremental-decoder object can be
used to decode the picture further. There are two (mutually exclusive) ways to
pass freshly arrived data:
either by appending the fresh bytes:
```c
WebPIAppend(idec, fresh_data, size_of_fresh_data);
```
or by just mentioning the new size of the transmitted data:
```c
WebPIUpdate(idec, buffer, size_of_transmitted_buffer);
```
Note that 'buffer' can be modified between each call to WebPIUpdate, in
particular when the buffer is resized to accommodate larger data.
These functions will return the decoding status: either VP8_STATUS_SUSPENDED if
decoding is not finished yet or VP8_STATUS_OK when decoding is done. Any other
status is an error condition.
The 'idec' object must always be released (even upon an error condition) by
calling: WebPDelete(idec).
To retrieve partially decoded picture samples, one must use the corresponding
method: WebPIDecGetRGB or WebPIDecGetYUVA. It will return the last displayable
pixel row.
Lastly, note that decoding can also be performed into a pre-allocated pixel
buffer. This buffer must be passed when creating a WebPIDecoder, calling
WebPINewRGB() or WebPINewYUVA().
Please have a look at the src/webp/decode.h header for further details.
### Advanced Decoding API
WebP decoding supports an advanced API which provides on-the-fly cropping and
rescaling, something of great usefulness on memory-constrained environments like
mobile phones. Basically, the memory usage will scale with the output's size,
not the input's, when one only needs a quick preview or a zoomed in portion of
an otherwise too-large picture. Some CPU can be saved too, incidentally.
```c
// A) Init a configuration object
WebPDecoderConfig config;
CHECK(WebPInitDecoderConfig(&config));
// B) optional: retrieve the bitstream's features.
CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
// C) Adjust 'config' options, if needed
config.options.no_fancy_upsampling = 1;
config.options.use_scaling = 1;
config.options.scaled_width = scaledWidth();
config.options.scaled_height = scaledHeight();
// etc.
// D) Specify 'config' output options for specifying output colorspace.
// Optionally the external image decode buffer can also be specified.
config.output.colorspace = MODE_BGRA;
// Optionally, the config.output can be pointed to an external buffer as
// well for decoding the image. This externally supplied memory buffer
// should be big enough to store the decoded picture.
config.output.u.RGBA.rgba = (uint8_t*) memory_buffer;
config.output.u.RGBA.stride = scanline_stride;
config.output.u.RGBA.size = total_size_of_the_memory_buffer;
config.output.is_external_memory = 1;
// E) Decode the WebP image. There are two variants w.r.t decoding image.
// The first one (E.1) decodes the full image and the second one (E.2) is
// used to incrementally decode the image using small input buffers.
// Any one of these steps can be used to decode the WebP image.
// E.1) Decode full image.
CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
// E.2) Decode image incrementally.
WebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config);
CHECK(idec != NULL);
while (bytes_remaining > 0) {
VP8StatusCode status = WebPIAppend(idec, input, bytes_read);
if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
bytes_remaining -= bytes_read;
} else {
break;
}
}
WebPIDelete(idec);
// F) Decoded image is now in config.output (and config.output.u.RGBA).
// It can be saved, displayed or otherwise processed.
// G) Reclaim memory allocated in config's object. It's safe to call
// this function even if the memory is external and wasn't allocated
// by WebPDecode().
WebPFreeDecBuffer(&config.output);
```
## Webp Mux
WebPMux is a set of two libraries 'Mux' and 'Demux' for creation, extraction and
manipulation of an extended format WebP file, which can have features like color
profile, metadata and animation. Reference command-line tools `webpmux` and
`vwebp` as well as the WebP container specification
'doc/webp-container-spec.txt' are also provided in this package, see the
[tools documentation](tools.md).
### Mux API
The Mux API contains methods for adding data to and reading data from WebP
files. This API currently supports XMP/EXIF metadata, ICC profile and animation.
Other features may be added in subsequent releases.
Example#1 (pseudo code): Creating a WebPMux object with image data, color
profile and XMP metadata.
```c
int copy_data = 0;
WebPMux* mux = WebPMuxNew();
// ... (Prepare image data).
WebPMuxSetImage(mux, &image, copy_data);
// ... (Prepare ICC profile data).
WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
// ... (Prepare XMP metadata).
WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
// Get data from mux in WebP RIFF format.
WebPMuxAssemble(mux, &output_data);
WebPMuxDelete(mux);
// ... (Consume output_data; e.g. write output_data.bytes to file).
WebPDataClear(&output_data);
```
Example#2 (pseudo code): Get image and color profile data from a WebP file.
```c
int copy_data = 0;
// ... (Read data from file).
WebPMux* mux = WebPMuxCreate(&data, copy_data);
WebPMuxGetFrame(mux, 1, &image);
// ... (Consume image; e.g. call WebPDecode() to decode the data).
WebPMuxGetChunk(mux, "ICCP", &icc_profile);
// ... (Consume icc_profile).
WebPMuxDelete(mux);
free(data);
```
For a detailed Mux API reference, please refer to the header file
(src/webp/mux.h).
### Demux API
The Demux API enables extraction of images and extended format data from WebP
files. This API currently supports reading of XMP/EXIF metadata, ICC profile and
animated images. Other features may be added in subsequent releases.
Code example: Demuxing WebP data to extract all the frames, ICC profile and
EXIF/XMP metadata.
```c
WebPDemuxer* demux = WebPDemux(&webp_data);
uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
// ... (Get information about the features present in the WebP file).
uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
// ... (Iterate over all frames).
WebPIterator iter;
if (WebPDemuxGetFrame(demux, 1, &iter)) {
do {
// ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
// ... and get other frame properties like width, height, offsets etc.
// ... see 'struct WebPIterator' below for more info).
} while (WebPDemuxNextFrame(&iter));
WebPDemuxReleaseIterator(&iter);
}
// ... (Extract metadata).
WebPChunkIterator chunk_iter;
if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
// ... (Consume the ICC profile in 'chunk_iter.chunk').
WebPDemuxReleaseChunkIterator(&chunk_iter);
if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
// ... (Consume the EXIF metadata in 'chunk_iter.chunk').
WebPDemuxReleaseChunkIterator(&chunk_iter);
if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
// ... (Consume the XMP metadata in 'chunk_iter.chunk').
WebPDemuxReleaseChunkIterator(&chunk_iter);
WebPDemuxDelete(demux);
```
For a detailed Demux API reference, please refer to the header file
(src/webp/demux.h).
## AnimEncoder API
The AnimEncoder API can be used to create animated WebP images.
Code example:
```c
WebPAnimEncoderOptions enc_options;
WebPAnimEncoderOptionsInit(&enc_options);
// ... (Tune 'enc_options' as needed).
WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
while(<there are more frames>) {
WebPConfig config;
WebPConfigInit(&config);
// ... (Tune 'config' as needed).
WebPAnimEncoderAdd(enc, frame, duration, &config);
}
WebPAnimEncoderAssemble(enc, webp_data);
WebPAnimEncoderDelete(enc);
// ... (Write the 'webp_data' to a file, or re-mux it further).
```
For a detailed AnimEncoder API reference, please refer to the header file
(src/webp/mux.h).
## AnimDecoder API
This AnimDecoder API allows decoding (possibly) animated WebP images.
Code Example:
```c
WebPAnimDecoderOptions dec_options;
WebPAnimDecoderOptionsInit(&dec_options);
// Tune 'dec_options' as needed.
WebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options);
WebPAnimInfo anim_info;
WebPAnimDecoderGetInfo(dec, &anim_info);
for (uint32_t i = 0; i < anim_info.loop_count; ++i) {
while (WebPAnimDecoderHasMoreFrames(dec)) {
uint8_t* buf;
int timestamp;
WebPAnimDecoderGetNext(dec, &buf, &timestamp);
// ... (Render 'buf' based on 'timestamp').
// ... (Do NOT free 'buf', as it is owned by 'dec').
}
WebPAnimDecoderReset(dec);
}
const WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec);
// ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data).
WebPAnimDecoderDelete(dec);
```
For a detailed AnimDecoder API reference, please refer to the header file
(src/webp/demux.h).

213
doc/building.md Normal file
View File

@ -0,0 +1,213 @@
# Building
## Windows build
By running:
```batch
nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output
```
the directory `output\release-static\(x64|x86)\bin` will contain the tools
cwebp.exe and dwebp.exe. The directory `output\release-static\(x64|x86)\lib`
will contain the libwebp static library. The target architecture (x86/x64) is
detected by Makefile.vc from the Visual Studio compiler (cl.exe) available in
the system path.
## Unix build using makefile.unix
On platforms with GNU tools installed (gcc and make), running
```shell
make -f makefile.unix
```
will build the binaries examples/cwebp and examples/dwebp, along with the static
library src/libwebp.a. No system-wide installation is supplied, as this is a
simple alternative to the full installation system based on the autoconf tools
(see below). Please refer to makefile.unix for additional details and
customizations.
## Using autoconf tools
Prerequisites: a compiler (e.g., gcc), make, autoconf, automake, libtool.
On a Debian-like system the following should install everything you need for a
minimal build:
```shell
$ sudo apt-get install gcc make autoconf automake libtool
```
When building from git sources, you will need to run autogen.sh to generate the
configure script.
```shell
./configure
make
make install
```
should be all you need to have the following files
```
/usr/local/include/webp/decode.h
/usr/local/include/webp/encode.h
/usr/local/include/webp/types.h
/usr/local/lib/libwebp.*
/usr/local/bin/cwebp
/usr/local/bin/dwebp
```
installed.
Note: A decode-only library, libwebpdecoder, is available using the
`--enable-libwebpdecoder` flag. The encode library is built separately and can
be installed independently using a minor modification in the corresponding
Makefile.am configure files (see comments there). See `./configure --help` for
more options.
## Building for MIPS Linux
MIPS Linux toolchain stable available releases can be found at:
https://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/available-releases/
```shell
# Add toolchain to PATH
export PATH=$PATH:/path/to/toolchain/bin
# 32-bit build for mips32r5 (p5600)
HOST=mips-mti-linux-gnu
MIPS_CFLAGS="-O3 -mips32r5 -mabi=32 -mtune=p5600 -mmsa -mfp64 \
-msched-weight -mload-store-pairs -fPIE"
MIPS_LDFLAGS="-mips32r5 -mabi=32 -mmsa -mfp64 -pie"
# 64-bit build for mips64r6 (i6400)
HOST=mips-img-linux-gnu
MIPS_CFLAGS="-O3 -mips64r6 -mabi=64 -mtune=i6400 -mmsa -mfp64 \
-msched-weight -mload-store-pairs -fPIE"
MIPS_LDFLAGS="-mips64r6 -mabi=64 -mmsa -mfp64 -pie"
./configure --host=${HOST} --build=`config.guess` \
CC="${HOST}-gcc -EL" \
CFLAGS="$MIPS_CFLAGS" \
LDFLAGS="$MIPS_LDFLAGS"
make
make install
```
## CMake
With CMake, you can compile libwebp, cwebp, dwebp, gif2webp, img2webp, webpinfo
and the JS bindings.
Prerequisites: a compiler (e.g., gcc with autotools) and CMake.
On a Debian-like system the following should install everything you need for a
minimal build:
```shell
$ sudo apt-get install build-essential cmake
```
When building from git sources, you will need to run cmake to generate the
makefiles.
```shell
mkdir build && cd build && cmake ../
make
make install
```
If you also want any of the executables, you will need to enable them through
CMake, e.g.:
```shell
cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../
```
or through your favorite interface (like ccmake or cmake-qt-gui).
Use option `-DWEBP_UNICODE=ON` for Unicode support on Windows (with chcp 65001).
Finally, once installed, you can also use WebP in your CMake project by doing:
```cmake
find_package(WebP)
```
which will define the CMake variables WebP_INCLUDE_DIRS and WebP_LIBRARIES.
## Gradle
The support for Gradle is minimal: it only helps you compile libwebp, cwebp and
dwebp and webpmux_example.
Prerequisites: a compiler (e.g., gcc with autotools) and gradle.
On a Debian-like system the following should install everything you need for a
minimal build:
```shell
$ sudo apt-get install build-essential gradle
```
When building from git sources, you will need to run the Gradle wrapper with the
appropriate target, e.g. :
```shell
./gradlew buildAllExecutables
```
## SWIG bindings
To generate language bindings from swig/libwebp.swig at least swig-1.3
(http://www.swig.org) is required.
Currently the following functions are mapped:
Decode:
```
WebPGetDecoderVersion
WebPGetInfo
WebPDecodeRGBA
WebPDecodeARGB
WebPDecodeBGRA
WebPDecodeBGR
WebPDecodeRGB
```
Encode:
```
WebPGetEncoderVersion
WebPEncodeRGBA
WebPEncodeBGRA
WebPEncodeRGB
WebPEncodeBGR
WebPEncodeLosslessRGBA
WebPEncodeLosslessBGRA
WebPEncodeLosslessRGB
WebPEncodeLosslessBGR
```
See also the [swig documentation](../swig/README.md) for more detailed build
instructions and usage examples.
### Java bindings
To build the swig-generated JNI wrapper code at least JDK-1.5 (or equivalent) is
necessary for enum support. The output is intended to be a shared object / DLL
that can be loaded via `System.loadLibrary("webp_jni")`.
### Python bindings
To build the swig-generated Python extension code at least Python 2.6 is
required. Python < 2.6 may build with some minor changes to libwebp.swig or the
generated code, but is untested.
## Javascript decoder
Libwebp can be compiled into a JavaScript decoder using Emscripten and CMake.
See the [corresponding documentation](../README.md)

26
doc/specs_generation.md Normal file
View File

@ -0,0 +1,26 @@
# Generate libwebp Container Spec Docs from Text Source
HTML generation requires [kramdown](https://kramdown.gettalong.org/), easily
installed as a [rubygem](https://rubygems.org/). Rubygems installation should
satisfy dependencies automatically.
HTML generation can then be done from the project root:
```shell
$ kramdown doc/webp-container-spec.txt --template doc/template.html > \
doc/output/webp-container-spec.html
```
kramdown can optionally syntax highlight code blocks, using
[CodeRay](https://github.com/rubychan/coderay), a dependency of kramdown that
rubygems will install automatically. The following will apply inline CSS
styling; an external stylesheet is not needed.
```shell
$ kramdown doc/webp-lossless-bitstream-spec.txt --template \
doc/template.html --coderay-css style --coderay-line-numbers ' ' \
--coderay-default-lang c > \
doc/output/webp-lossless-bitstream-spec.html
```
Optimally, use kramdown 0.13.7 or newer if syntax highlighting desired.

512
doc/tools.md Normal file
View File

@ -0,0 +1,512 @@
# WebP tools
## Encoding tool
The examples/ directory contains tools for encoding (cwebp) and decoding (dwebp)
images.
The easiest use should look like:
```shell
cwebp input.png -q 80 -o output.webp
```
which will convert the input file to a WebP file using a quality factor of 80 on
a 0->100 scale (0 being the lowest quality, 100 being the best. Default value is
75).
You might want to try the `-lossless` flag too, which will compress the source
(in RGBA format) without any loss. The `-q` quality parameter will in this case
control the amount of processing time spent trying to make the output file as
small as possible.
A longer list of options is available using the `-longhelp` command line flag:
```shell
> cwebp -longhelp
Usage:
cwebp [-preset <...>] [options] in_file [-o out_file]
```
If input size (-s) for an image is not specified, it is assumed to be a PNG,
JPEG, TIFF or WebP file. Note: Animated PNG and WebP files are not supported.
Options:
```
-h / -help ............. short help
-H / -longhelp ......... long help
-q <float> ............. quality factor (0:small..100:big), default=75
-alpha_q <int> ......... transparency-compression quality (0..100),
default=100
-preset <string> ....... preset setting, one of:
default, photo, picture,
drawing, icon, text
-preset must come first, as it overwrites other parameters
-z <int> ............... activates lossless preset with given
level in [0:fast, ..., 9:slowest]
-m <int> ............... compression method (0=fast, 6=slowest), default=4
-segments <int> ........ number of segments to use (1..4), default=4
-size <int> ............ target size (in bytes)
-psnr <float> .......... target PSNR (in dB. typically: 42)
-s <int> <int> ......... input size (width x height) for YUV
-sns <int> ............. spatial noise shaping (0:off, 100:max), default=50
-f <int> ............... filter strength (0=off..100), default=60
-sharpness <int> ....... filter sharpness (0:most .. 7:least sharp), default=0
-strong ................ use strong filter instead of simple (default)
-nostrong .............. use simple filter instead of strong
-sharp_yuv ............. use sharper (and slower) RGB->YUV conversion
-partition_limit <int> . limit quality to fit the 512k limit on
the first partition (0=no degradation ... 100=full)
-pass <int> ............ analysis pass number (1..10)
-qrange <min> <max> .... specifies the permissible quality range
(default: 0 100)
-crop <x> <y> <w> <h> .. crop picture with the given rectangle
-resize <w> <h> ........ resize picture (*after* any cropping)
-mt .................... use multi-threading if available
-low_memory ............ reduce memory usage (slower encoding)
-map <int> ............. print map of extra info
-print_psnr ............ prints averaged PSNR distortion
-print_ssim ............ prints averaged SSIM distortion
-print_lsim ............ prints local-similarity distortion
-d <file.pgm> .......... dump the compressed output (PGM file)
-alpha_method <int> .... transparency-compression method (0..1), default=1
-alpha_filter <string> . predictive filtering for alpha plane,
one of: none, fast (default) or best
-exact ................. preserve RGB values in transparent area, default=off
-blend_alpha <hex> ..... blend colors against background color
expressed as RGB values written in
hexadecimal, e.g. 0xc0e0d0 for red=0xc0
green=0xe0 and blue=0xd0
-noalpha ............... discard any transparency information
-lossless .............. encode image losslessly, default=off
-near_lossless <int> ... use near-lossless image
preprocessing (0..100=off), default=100
-hint <string> ......... specify image characteristics hint,
one of: photo, picture or graph
-metadata <string> ..... comma separated list of metadata to
copy from the input to the output if present.
Valid values: all, none (default), exif, icc, xmp
-short ................. condense printed message
-quiet ................. don't print anything
-version ............... print version number and exit
-noasm ................. disable all assembly optimizations
-v ..................... verbose, e.g. print encoding/decoding times
-progress .............. report encoding progress
```
Experimental Options:
```
-jpeg_like ............. roughly match expected JPEG size
-af .................... auto-adjust filter strength
-pre <int> ............. pre-processing filter
```
The main options you might want to try in order to further tune the visual
quality are:
-preset -sns -f -m
Namely:
* `preset` will set up a default encoding configuration targeting a particular
type of input. It should appear first in the list of options, so that
subsequent options can take effect on top of this preset. Default value is
'default'.
* `sns` will progressively turn on (when going from 0 to 100) some additional
visual optimizations (like: segmentation map re-enforcement). This option
will balance the bit allocation differently. It tries to take bits from the
"easy" parts of the picture and use them in the "difficult" ones instead.
Usually, raising the sns value (at fixed -q value) leads to larger files,
but with better quality. Typical value is around '75'.
* `f` option directly links to the filtering strength used by the codec's
in-loop processing. The higher the value, the smoother the highly-compressed
area will look. This is particularly useful when aiming at very small files.
Typical values are around 20-30. Note that using the option
-strong/-nostrong will change the type of filtering. Use "-f 0" to turn
filtering off.
* `m` controls the trade-off between encoding speed and quality. Default is 4.
You can try -m 5 or -m 6 to explore more (time-consuming) encoding
possibilities. A lower value will result in faster encoding at the expense
of quality.
## Decoding tool
There is a decoding sample in examples/dwebp.c which will take a .webp file and
decode it to a PNG image file (amongst other formats). This is simply to
demonstrate the use of the API. You can verify the file test.webp decodes to
exactly the same as test_ref.ppm by using:
```shell
cd examples
./dwebp test.webp -ppm -o test.ppm
diff test.ppm test_ref.ppm
```
The full list of options is available using -h:
```shell
> dwebp -h
Usage: dwebp in_file [options] [-o out_file]
```
Decodes the WebP image file to PNG format [Default]. Note: Animated WebP files
are not supported.
Use following options to convert into alternate image formats:
```
-pam ......... save the raw RGBA samples as a color PAM
-ppm ......... save the raw RGB samples as a color PPM
-bmp ......... save as uncompressed BMP format
-tiff ........ save as uncompressed TIFF format
-pgm ......... save the raw YUV samples as a grayscale PGM
file with IMC4 layout
-yuv ......... save the raw YUV samples in flat layout
```
Other options are:
```
-version ..... print version number and exit
-nofancy ..... don't use the fancy YUV420 upscaler
-nofilter .... disable in-loop filtering
-nodither .... disable dithering
-dither <d> .. dithering strength (in 0..100)
-alpha_dither use alpha-plane dithering if needed
-mt .......... use multi-threading
-crop <x> <y> <w> <h> ... crop output with the given rectangle
-resize <w> <h> ......... resize output (*after* any cropping)
-flip ........ flip the output vertically
-alpha ....... only save the alpha plane
-incremental . use incremental decoding (useful for tests)
-h ........... this help message
-v ........... verbose (e.g. print encoding/decoding times)
-quiet ....... quiet mode, don't print anything
-noasm ....... disable all assembly optimizations
```
## WebP file analysis tool
`webpinfo` can be used to print out the chunk level structure and bitstream
header information of WebP files. It can also check if the files are of valid
WebP format.
Usage:
```shell
webpinfo [options] in_files
```
Note: there could be multiple input files; options must come before input files.
Options:
```
-version ........... Print version number and exit.
-quiet ............. Do not show chunk parsing information.
-diag .............. Show parsing error diagnosis.
-summary ........... Show chunk stats summary.
-bitstream_info .... Parse bitstream header.
```
## Visualization tool
There's a little self-serve visualization tool called 'vwebp' under the
examples/ directory. It uses OpenGL to open a simple drawing window and show a
decoded WebP file. It's not yet integrated in the automake build system, but you
can try to manually compile it using the recommendations below.
Usage:
```shell
vwebp in_file [options]
```
Decodes the WebP image file and visualize it using OpenGL
Options are:
```
-version ..... print version number and exit
-noicc ....... don't use the icc profile if present
-nofancy ..... don't use the fancy YUV420 upscaler
-nofilter .... disable in-loop filtering
-dither <int> dithering strength (0..100), default=50
-noalphadither disable alpha plane dithering
-usebgcolor .. display background color
-mt .......... use multi-threading
-info ........ print info
-h ........... this help message
```
Keyboard shortcuts:
```
'c' ................ toggle use of color profile
'b' ................ toggle background color display
'i' ................ overlay file information
'd' ................ disable blending & disposal (debug)
'q' / 'Q' / ESC .... quit
```
### Building
Prerequisites:
1. OpenGL & OpenGL Utility Toolkit (GLUT)
Linux: `sudo apt-get install freeglut3-dev mesa-common-dev`
Mac + Xcode: These libraries should be available in the OpenGL / GLUT
frameworks.
Windows: http://freeglut.sourceforge.net/index.php#download
2. (Optional) qcms (Quick Color Management System)
1. Download qcms from Mozilla / Chromium:
https://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
https://source.chromium.org/chromium/chromium/src/+/main:third_party/qcms/;drc=d4a2f8e1ed461d8fc05ed88d1ae2dc94c9773825
2. Build and archive the source files as libqcms.a / qcms.lib
3. Update makefile.unix / Makefile.vc
1. Define WEBP_HAVE_QCMS
2. Update include / library paths to reference the qcms directory.
Build using makefile.unix / Makefile.vc:
```shell
$ make -f makefile.unix examples/vwebp
> nmake /f Makefile.vc CFG=release-static \
../obj/x64/release-static/bin/vwebp.exe
```
## Animation creation tool
The utility `img2webp` can turn a sequence of input images (PNG, JPEG, ...) into
an animated WebP file. It offers fine control over duration, encoding modes,
etc.
Usage:
```shell
img2webp [file_options] [[frame_options] frame_file]...
```
File-level options (only used at the start of compression):
```
-min_size ............ minimize size
-loop <int> .......... loop count (default: 0, = infinite loop)
-kmax <int> .......... maximum number of frame between key-frames
(0=only keyframes)
-kmin <int> .......... minimum number of frame between key-frames
(0=disable key-frames altogether)
-mixed ............... use mixed lossy/lossless automatic mode
-v ................... verbose mode
-h ................... this help
-version ............. print version number and exit
```
Per-frame options (only used for subsequent images input):
```
-d <int> ............. frame duration in ms (default: 100)
-lossless ........... use lossless mode (default)
-lossy ... ........... use lossy mode
-q <float> ........... quality
-m <int> ............. method to use
```
example: `img2webp -loop 2 in0.png -lossy in1.jpg -d 80 in2.tiff -o out.webp`
Note: if a single file name is passed as the argument, the arguments will be
tokenized from this file. The file name must not start with the character '-'.
## Animated GIF conversion
Animated GIF files can be converted to WebP files with animation using the
gif2webp utility available under examples/. The files can then be viewed using
vwebp.
Usage:
```shell
gif2webp [options] gif_file -o webp_file
```
Options:
```
-h / -help ............. this help
-lossy ................. encode image using lossy compression
-mixed ................. for each frame in the image, pick lossy
or lossless compression heuristically
-q <float> ............. quality factor (0:small..100:big)
-m <int> ............... compression method (0=fast, 6=slowest)
-min_size .............. minimize output size (default:off)
lossless compression by default; can be
combined with -q, -m, -lossy or -mixed
options
-kmin <int> ............ min distance between key frames
-kmax <int> ............ max distance between key frames
-f <int> ............... filter strength (0=off..100)
-metadata <string> ..... comma separated list of metadata to
copy from the input to the output if present
Valid values: all, none, icc, xmp (default)
-loop_compatibility .... use compatibility mode for Chrome
version prior to M62 (inclusive)
-mt .................... use multi-threading if available
-version ............... print version number and exit
-v ..................... verbose
-quiet ................. don't print anything
```
### Building
With the libgif development files installed, gif2webp can be built using
makefile.unix:
```shell
$ make -f makefile.unix examples/gif2webp
```
or using autoconf:
```shell
$ ./configure --enable-everything
$ make
```
## Comparison of animated images
Test utility anim_diff under examples/ can be used to compare two animated
images (each can be GIF or WebP).
Usage:
```shell
anim_diff <image1> <image2> [options]
```
Options:
```
-dump_frames <folder> dump decoded frames in PAM format
-min_psnr <float> ... minimum per-frame PSNR
-raw_comparison ..... if this flag is not used, RGB is
premultiplied before comparison
-max_diff <int> ..... maximum allowed difference per channel
between corresponding pixels in subsequent
frames
-h .................. this help
-version ............ print version number and exit
```
### Building
With the libgif development files installed, anim_diff can be built using
makefile.unix:
```shell
$ make -f makefile.unix examples/anim_diff
```
or using autoconf:
```shell
$ ./configure --enable-everything
$ make
```
## WebP Mux tool
The examples/ directory contains a tool (webpmux) for manipulating WebP files.
The webpmux tool can be used to create an extended format WebP file and also to
extract or strip relevant data from such a file.
A list of options is available using the -help command line flag:
```shell
> webpmux -help
Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT
webpmux -set SET_OPTIONS INPUT -o OUTPUT
webpmux -duration DURATION_OPTIONS [-duration ...]
INPUT -o OUTPUT
webpmux -strip STRIP_OPTIONS INPUT -o OUTPUT
webpmux -frame FRAME_OPTIONS [-frame...] [-loop LOOP_COUNT]
[-bgcolor BACKGROUND_COLOR] -o OUTPUT
webpmux -info INPUT
webpmux [-h|-help]
webpmux -version
webpmux argument_file_name
GET_OPTIONS:
Extract relevant data:
icc get ICC profile
exif get EXIF metadata
xmp get XMP metadata
frame n get nth frame
SET_OPTIONS:
Set color profile/metadata/parameters:
loop LOOP_COUNT set the loop count
bgcolor BACKGROUND_COLOR set the animation background color
icc file.icc set ICC profile
exif file.exif set EXIF metadata
xmp file.xmp set XMP metadata
where: 'file.icc' contains the ICC profile to be set,
'file.exif' contains the EXIF metadata to be set
'file.xmp' contains the XMP metadata to be set
DURATION_OPTIONS:
Set duration of selected frames:
duration set duration for all frames
duration,frame set duration of a particular frame
duration,start,end set duration of frames in the
interval [start,end])
where: 'duration' is the duration in milliseconds
'start' is the start frame index
'end' is the inclusive end frame index
The special 'end' value '0' means: last frame.
STRIP_OPTIONS:
Strip color profile/metadata:
icc strip ICC profile
exif strip EXIF metadata
xmp strip XMP metadata
FRAME_OPTIONS(i):
Create animation:
file_i +di[+xi+yi[+mi[bi]]]
where: 'file_i' is the i'th animation frame (WebP format),
'di' is the pause duration before next frame,
'xi','yi' specify the image offset for this frame,
'mi' is the dispose method for this frame (0 or 1),
'bi' is the blending method for this frame (+b or -b)
LOOP_COUNT:
Number of times to repeat the animation.
Valid range is 0 to 65535 [Default: 0 (infinite)].
BACKGROUND_COLOR:
Background color of the canvas.
A,R,G,B
where: 'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying
the Alpha, Red, Green and Blue component values respectively
[Default: 255,255,255,255]
INPUT & OUTPUT are in WebP format.
Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be
valid.
Note: if a single file name is passed as the argument, the arguments will be
tokenized from this file. The file name must not start with the character '-'.
```

View File

@ -2,10 +2,10 @@
Although you may be viewing an alternate representation, this document
is sourced in Markdown, a light-duty markup scheme, and is optimized for
the [kramdown](http://kramdown.rubyforge.org/) transformer.
the [kramdown](https://kramdown.gettalong.org/) transformer.
See the accompanying README. External link targets are referenced at the
end of this file.
See the accompanying specs_generation.md. External link targets are referenced
at the end of this file.
-->
@ -36,7 +36,7 @@ for:
* **Lossless compression.** An image can be losslessly compressed, using the
WebP Lossless Format.
* **Metadata.** An image may have metadata stored in EXIF or XMP formats.
* **Metadata.** An image may have metadata stored in Exif or XMP formats.
* **Transparency.** An image may have transparency, i.e., an alpha channel.
@ -53,10 +53,6 @@ document are to be interpreted as described in [RFC 2119][].
Bit numbering in chunk diagrams starts at `0` for the most significant bit
('MSB 0') as described in [RFC 1166][].
**Note:** Out of the features mentioned above, lossy compression, lossless
compression, transparency, metadata, color profile and animation are finalized
and are to be considered stable.
Terminology &amp; Basics
------------------------
@ -98,7 +94,7 @@ _1-based_
RIFF File Format
----------------
The WebP file format is based on the RIFF (resource interchange file format)
The WebP file format is based on the RIFF (Resource Interchange File Format)
document format.
The basic element of a RIFF file is a _chunk_. It consists of:
@ -265,11 +261,11 @@ An extended format file consists of:
* Image data.
* An optional 'EXIF' chunk with EXIF metadata.
* An optional 'EXIF' chunk with Exif metadata.
* An optional 'XMP ' chunk with XMP metadata.
* An optional list of [unknown chunks](#unknown-chunks). _\[status: experimental\]_
* An optional list of [unknown chunks](#unknown-chunks).
For a _still image_, the _image data_ consists of a single frame, which is made
up of:
@ -321,9 +317,9 @@ Alpha (L): 1 bit
: Set if any of the frames of the image contain transparency information
("alpha").
EXIF metadata (E): 1 bit
Exif metadata (E): 1 bit
: Set if the file contains EXIF metadata.
: Set if the file contains Exif metadata.
XMP metadata (X): 1 bit
@ -345,12 +341,12 @@ Reserved: 24 bits
Canvas Width Minus One: 24 bits
: _1-based_ width of the canvas in pixels.
The actual canvas width is '1 + Canvas Width Minus One'
The actual canvas width is `1 + Canvas Width Minus One`.
Canvas Height Minus One: 24 bits
: _1-based_ height of the canvas in pixels.
The actual canvas height is '1 + Canvas Height Minus One'
The actual canvas height is `1 + Canvas Height Minus One`.
The product of _Canvas Width_ and _Canvas Height_ MUST be at most `2^32 - 1`.
@ -427,27 +423,28 @@ If the _Animation flag_ is not set, then this chunk SHOULD NOT be present.
Frame X: 24 bits (_uint24_)
: The X coordinate of the upper left corner of the frame is `Frame X * 2`
: The X coordinate of the upper left corner of the frame is `Frame X * 2`.
Frame Y: 24 bits (_uint24_)
: The Y coordinate of the upper left corner of the frame is `Frame Y * 2`
: The Y coordinate of the upper left corner of the frame is `Frame Y * 2`.
Frame Width Minus One: 24 bits (_uint24_)
: The _1-based_ width of the frame.
The frame width is `1 + Frame Width Minus One`
The frame width is `1 + Frame Width Minus One`.
Frame Height Minus One: 24 bits (_uint24_)
: The _1-based_ height of the frame.
The frame height is `1 + Frame Height Minus One`
The frame height is `1 + Frame Height Minus One`.
Frame Duration: 24 bits (_uint24_)
: The time to wait before displaying the next frame, in 1 millisecond units.
In particular, frame duration of 0 is useful when one wants to update
multiple areas of the canvas at once during the animation.
Note the interpretation of frame duration of 0 (and often <= 10) is
implementation defined. Many tools and browsers assign a minimum duration
similar to GIF.
Reserved: 6 bits
@ -680,12 +677,12 @@ EXIF chunk:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('EXIF') |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| EXIF Metadata |
| Exif Metadata |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
EXIF Metadata: _Chunk Size_ bytes
Exif Metadata: _Chunk Size_ bytes
: image metadata in EXIF format.
: image metadata in Exif format.
XMP chunk:
@ -704,7 +701,7 @@ XMP Metadata: _Chunk Size_ bytes
Additional guidance about handling metadata can be found in the
Metadata Working Group's [Guidelines for Handling Metadata][metadata].
#### Unknown Chunks _\[status: experimental\]_
#### Unknown Chunks
A RIFF chunk (described in [this](#terminology-amp-basics) section) whose _chunk
tag_ is different from any of the chunks described in this document, is
@ -801,7 +798,7 @@ RIFF/WEBP
+- XMP (metadata)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An animated image with EXIF metadata may look as follows:
An animated image with Exif metadata may look as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RIFF/WEBP
@ -814,9 +811,9 @@ RIFF/WEBP
+- EXIF (metadata)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[vp8spec]: http://tools.ietf.org/html/rfc6386
[webpllspec]: https://chromium.googlesource.com/webm/libwebp/+/master/doc/webp-lossless-bitstream-spec.txt
[iccspec]: http://www.color.org/icc_specs2.xalter
[metadata]: http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
[rfc 1166]: http://tools.ietf.org/html/rfc1166
[rfc 2119]: http://tools.ietf.org/html/rfc2119
[vp8spec]: https://datatracker.ietf.org/doc/html/rfc6386
[webpllspec]: https://chromium.googlesource.com/webm/libwebp/+/HEAD/doc/webp-lossless-bitstream-spec.txt
[iccspec]: https://www.color.org/icc_specs2.xalter
[metadata]: https://web.archive.org/web/20180919181934/http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
[rfc 1166]: https://datatracker.ietf.org/doc/html/rfc1166
[rfc 2119]: https://datatracker.ietf.org/doc/html/rfc2119

View File

@ -2,10 +2,10 @@
Although you may be viewing an alternate representation, this document
is sourced in Markdown, a light-duty markup scheme, and is optimized for
the [kramdown](http://kramdown.rubyforge.org/) transformer.
the [kramdown](https://kramdown.gettalong.org/) transformer.
See the accompanying README. External link targets are referenced at the
end of this file.
See the accompanying specs_generation.md. External link targets are referenced
at the end of this file.
-->
@ -16,6 +16,8 @@ _Jyrki Alakuijala, Ph.D., Google, Inc., 2012-06-19_
Paragraphs marked as \[AMENDED\] were amended on 2014-09-16.
Paragraphs marked as \[AMENDED2\] were amended on 2022-05-13.
Abstract
--------
@ -25,7 +27,7 @@ exactly, including the color values for zero alpha pixels. The
format uses subresolution images, recursively embedded into the format
itself, for storing statistical data about the images, such as the used
entropy codes, spatial predictors, color space conversion, and color
table. LZ77, Huffman coding, and a color cache are used for compression
table. LZ77, prefix coding, and a color cache are used for compression
of the bulk data. Decoding speeds faster than PNG have been
demonstrated, as well as 25% denser compression than can be achieved
using today's PNG format.
@ -63,9 +65,9 @@ distance mapping
entropy image
: A two-dimensional subresolution image indicating which entropy coding
should be used in a respective square in the image, i.e., each pixel
is a meta Huffman code.
is a meta prefix code.
Huffman code
prefix code
: A classic way to do entropy coding where a smaller number of bits are
used for more frequent codes.
@ -73,9 +75,9 @@ LZ77
: Dictionary-based sliding window compression algorithm that either
emits symbols or describes them as sequences of past symbols.
meta Huffman code
meta prefix code
: A small integer (up to 16 bits) that indexes an element in the meta
Huffman table.
prefix table.
predictor image
: A two-dimensional subresolution image indicating which spatial
@ -235,7 +237,7 @@ transform, the current pixel value is predicted from the pixels already
decoded (in scan-line order) and only the residual value (actual -
predicted) is encoded. The _prediction mode_ determines the type of
prediction to use. We divide the image into squares and all the pixels
in a square use same prediction mode.
in a square use the same prediction mode.
The first 3 bits of prediction data define the block width and height in
number of bits. The number of block columns, `block_xsize`, is used in
@ -367,15 +369,17 @@ the predicted value for the left-topmost pixel of the image is
0xff000000, L-pixel for all pixels on the top row, and T-pixel for all
pixels on the leftmost column.
\[AMENDED2\]
Addressing the TR-pixel for pixels on the rightmost column is
exceptional. The pixels on the rightmost column are predicted by using
the modes \[0..13\] just like pixels not on border, but by using the
leftmost pixel on the same row as the current TR-pixel. The TR-pixel
offset in memory is the same for border and non-border pixels.
the modes \[0..13\] just like pixels not on the border, but the leftmost pixel
on the same row as the current pixel is instead used as the TR-pixel.
### Color Transform
\[AMENDED2\]
The goal of the color transform is to decorrelate the R, G and B values
of each pixel. Color transform keeps the green (G) value as it is,
transforms red (R) based on green and transforms blue (B) based on green
@ -396,8 +400,8 @@ typedef struct {
The actual color transformation is done by defining a color transform
delta. The color transform delta depends on the `ColorTransformElement`,
which is the same for all the pixels in a particular block. The delta is
added during color transform. The inverse color transform then is just
subtracting those deltas.
subtracted during color transform. The inverse color transform then is just
adding those deltas.
The color transform function is defined as follows:
@ -406,13 +410,13 @@ void ColorTransform(uint8 red, uint8 blue, uint8 green,
ColorTransformElement *trans,
uint8 *new_red, uint8 *new_blue) {
// Transformed values of red and blue components
uint32 tmp_red = red;
uint32 tmp_blue = blue;
int tmp_red = red;
int tmp_blue = blue;
// Applying transform is just adding the transform deltas
tmp_red += ColorTransformDelta(trans->green_to_red, green);
tmp_blue += ColorTransformDelta(trans->green_to_blue, green);
tmp_blue += ColorTransformDelta(trans->red_to_blue, red);
// Applying the transform is just subtracting the transform deltas
tmp_red -= ColorTransformDelta(p->green_to_red_, green);
tmp_blue -= ColorTransformDelta(p->green_to_blue_, green);
tmp_blue -= ColorTransformDelta(p->red_to_blue_, red);
*new_red = tmp_red & 0xff;
*new_blue = tmp_blue & 0xff;
@ -430,7 +434,7 @@ int8 ColorTransformDelta(int8 t, int8 c) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A conversion from the 8-bit unsigned representation (uint8) to the 8-bit
signed one (int8) is required before calling ColorTransformDelta().
signed one (int8) is required before calling `ColorTransformDelta()`.
It should be performed using 8-bit two's complement (that is: uint8 range
\[128-255\] is mapped to the \[-128, -1\] range of its converted int8 value).
@ -468,14 +472,18 @@ channels.
void InverseTransform(uint8 red, uint8 green, uint8 blue,
ColorTransformElement *p,
uint8 *new_red, uint8 *new_blue) {
// Applying inverse transform is just subtracting the
// color transform deltas
red -= ColorTransformDelta(p->green_to_red_, green);
blue -= ColorTransformDelta(p->green_to_blue_, green);
blue -= ColorTransformDelta(p->red_to_blue_, red & 0xff);
// Transformed values of red and blue components
int tmp_red = red;
int tmp_blue = blue;
*new_red = red & 0xff;
*new_blue = blue & 0xff;
// Applying inverse transform is just adding the
// color transform deltas
tmp_red += ColorTransformDelta(trans->green_to_red, green);
tmp_blue += ColorTransformDelta(trans->green_to_blue, green);
tmp_blue += ColorTransformDelta(trans->red_to_blue, tmp_red & 0xff);
*new_red = tmp_red & 0xff;
*new_blue = tmp_blue & 0xff;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -590,12 +598,12 @@ The values are packed into the green component as follows:
4 most-significant bits of the green value at x / 2.
* `width_bits` = 2: for every x value where x ≡ 0 (mod 4), a green
value at x is positioned into the 2 least-significant bits of the
green value at x / 4, green values at x + 1 to x + 3 in order to the
more significant bits of the green value at x / 4.
green value at x / 4, green values at x + 1 to x + 3 are positioned in order
to the more significant bits of the green value at x / 4.
* `width_bits` = 3: for every x value where x ≡ 0 (mod 8), a green
value at x is positioned into the least-significant bit of the green
value at x / 8, green values at x + 1 to x + 7 in order to the more
significant bits of the green value at x / 8.
value at x / 8, green values at x + 1 to x + 7 are positioned in order to
the more significant bits of the green value at x / 8.
4 Image Data
@ -609,8 +617,8 @@ We use image data in five different roles:
1. ARGB image: Stores the actual pixels of the image.
1. Entropy image: Stores the
[meta Huffman codes](#decoding-of-meta-huffman-codes). The red and green
components of a pixel define the meta Huffman code used in a particular
[meta prefix codes](#decoding-of-meta-prefix-codes). The red and green
components of a pixel define the meta prefix code used in a particular
block of the ARGB image.
1. Predictor image: Stores the metadata for [Predictor
Transform](#predictor-transform). The green component of a pixel defines
@ -621,7 +629,7 @@ We use image data in five different roles:
the image. Each `ColorTransformElement` `'cte'` is treated as a pixel whose
alpha component is `255`, red component is `cte.red_to_blue`, green
component is `cte.green_to_blue` and blue component is `cte.green_to_red`.
1. Color indexing image: An array of of size `color_table_size` (up to 256
1. Color indexing image: An array of size `color_table_size` (up to 256
ARGB values) storing the metadata for the
[Color Indexing Transform](#color-indexing-transform). This is stored as an
image of width `color_table_size` and height `1`.
@ -643,7 +651,7 @@ the image.
Each pixel is encoded using one of the three possible methods:
1. Huffman coded literal: each channel (green, red, blue and alpha) is
1. prefix coded literal: each channel (green, red, blue and alpha) is
entropy-coded independently;
2. LZ77 backward reference: a sequence of pixels are copied from elsewhere
in the image; or
@ -652,9 +660,9 @@ Each pixel is encoded using one of the three possible methods:
The following sub-sections describe each of these in detail.
#### 4.2.1 Huffman Coded Literals
#### 4.2.1 Prefix Coded Literals
The pixel is stored as Huffman coded values of green, red, blue and alpha (in
The pixel is stored as prefix coded values of green, red, blue and alpha (in
that order). See [this section](#decoding-entropy-coded-image-data) for details.
#### 4.2.2 LZ77 Backward Reference
@ -678,7 +686,7 @@ very few values in the image. Thus, this approach results in a better
compression overall.
The following table denotes the prefix codes and extra bits used for storing
different range of values.
different ranges of values.
Note: The maximum backward reference length is limited to 4096. Hence, only the
first 24 prefix codes (with the respective extra bits) are meaningful for length
@ -753,13 +761,13 @@ The mapping between distance code `i` and the neighboring pixel offset
(-6, 7), (7, 6), (-7, 6), (8, 5), (7, 7), (-7, 7), (8, 6), (8, 7)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For example, distance code `1` indicates offset of `(0, 1)` for the neighboring
pixel, that is, the pixel above the current pixel (0-pixel difference in
X-direction and 1 pixel difference in Y-direction). Similarly, distance code
`3` indicates left-top pixel.
For example, distance code `1` indicates an offset of `(0, 1)` for the
neighboring pixel, that is, the pixel above the current pixel (0 pixel
difference in X-direction and 1 pixel difference in Y-direction). Similarly,
distance code `3` indicates left-top pixel.
The decoder can convert a distances code 'i' to a scan-line order distance
'dist' as follows:
The decoder can convert a distance code `i` to a scan-line order distance
`dist` as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(xi, yi) = distance_map[i]
@ -769,21 +777,22 @@ if (dist < 1) {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
where 'distance_map' is the mapping noted above and `xsize` is the width of the
where `distance_map` is the mapping noted above and `xsize` is the width of the
image in pixels.
#### 4.2.3 Color Cache Coding
{:#color-cache-code}
Color cache stores a set of colors that have been recently used in the image.
**Rationale:** This way, the recently used colors can sometimes be referred to
more efficiently than emitting them using other two methods (described in
[4.2.1](#huffman-coded-literals) and [4.2.2](#lz77-backward-reference)).
more efficiently than emitting them using the other two methods (described in
[4.2.1](#prefix-coded-literals) and [4.2.2](#lz77-backward-reference)).
Color cache codes are stored as follows. First, there is a 1-bit value that
indicates if the color cache is used. If this bit is 0, no color cache codes
exist, and they are not transmitted in the Huffman code that decodes the green
exist, and they are not transmitted in the prefix code that decodes the green
symbols and the length prefix codes. However, if this bit is 1, the color cache
size is read next:
@ -814,130 +823,245 @@ literals, into the cache in the order they appear in the stream.
### 5.1 Overview
Most of the data is coded using [canonical Huffman code][canonical_huff]. Hence,
the codes are transmitted by sending the _Huffman code lengths_, as opposed to
the actual _Huffman codes_.
Most of the data is coded using a [canonical prefix code][canonical_huff].
Hence, the codes are transmitted by sending the _prefix code lengths_, as
opposed to the actual _prefix codes_.
In particular, the format uses **spatially-variant Huffman coding**. In other
In particular, the format uses **spatially-variant prefix coding**. In other
words, different blocks of the image can potentially use different entropy
codes.
**Rationale**: Different areas of the image may have different characteristics. So, allowing them to use different entropy codes provides more flexibility and
potentially a better compression.
**Rationale**: Different areas of the image may have different characteristics.
So, allowing them to use different entropy codes provides more flexibility and
potentially better compression.
### 5.2 Details
The encoded image data consists of two parts:
The encoded image data consists of several parts:
1. Meta Huffman codes
1. Decoding and building the prefix codes \[AMENDED2\]
1. Meta prefix codes
1. Entropy-coded image data
#### 5.2.1 Decoding of Meta Huffman Codes
#### 5.2.1 Decoding and Building the Prefix Codes
As noted earlier, the format allows the use of different Huffman codes for
different blocks of the image. _Meta Huffman codes_ are indexes identifying
which Huffman codes to use in different parts of the image.
There are several steps in decoding the prefix codes.
Meta Huffman codes may be used _only_ when the image is being used in the
**Decoding the Code Lengths:**
{:#decoding-the-code-lengths}
This section describes how to read the prefix code lengths from the bitstream.
The prefix code lengths can be coded in two ways. The method used is specified
by a 1-bit value.
* If this bit is 1, it is a _simple code length code_, and
* If this bit is 0, it is a _normal code length code_.
In both cases, there can be unused code lengths that are still part of the
stream. This may be inefficient, but it is allowed by the format.
**(i) Simple Code Length Code:**
\[AMENDED2\]
This variant is used in the special case when only 1 or 2 prefix symbols are
in the range \[0..255\] with code length `1`. All other prefix code lengths
are implicitly zeros.
The first bit indicates the number of symbols:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int num_symbols = ReadBits(1) + 1;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Following are the symbol values.
This first symbol is coded using 1 or 8 bits depending on the value of
`is_first_8bits`. The range is \[0..1\] or \[0..255\], respectively.
The second symbol, if present, is always assumed to be in the range \[0..255\]
and coded using 8 bits.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int is_first_8bits = ReadBits(1);
symbol0 = ReadBits(1 + 7 * is_first_8bits);
code_lengths[symbol0] = 1;
if (num_symbols == 2) {
symbol1 = ReadBits(8);
code_lengths[symbol1] = 1;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Note:** Another special case is when _all_ prefix code lengths are _zeros_
(an empty prefix code). For example, a prefix code for distance can be empty
if there are no backward references. Similarly, prefix codes for alpha, red,
and blue can be empty if all pixels within the same meta prefix code are
produced using the color cache. However, this case doesn't need a special
handling, as empty prefix codes can be coded as those containing a single
symbol `0`.
**(ii) Normal Code Length Code:**
The code lengths of the prefix code fit in 8 bits and are read as follows.
First, `num_code_lengths` specifies the number of code lengths.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int num_code_lengths = 4 + ReadBits(4);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If `num_code_lengths` is > 18, the bitstream is invalid.
The code lengths are themselves encoded using prefix codes: lower level code
lengths `code_length_code_lengths` first have to be read. The rest of those
`code_length_code_lengths` (according to the order in `kCodeLengthCodeOrder`)
are zeros.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int kCodeLengthCodes = 19;
int kCodeLengthCodeOrder[kCodeLengthCodes] = {
17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
};
int code_length_code_lengths[kCodeLengthCodes] = { 0 }; // All zeros.
for (i = 0; i < num_code_lengths; ++i) {
code_length_code_lengths[kCodeLengthCodeOrder[i]] = ReadBits(3);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Next, if `ReadBits(1) == 0`, the maximum number of different read symbols is
`num_code_lengths`. Otherwise, it is defined as:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int length_nbits = 2 + 2 * ReadBits(3);
int max_symbol = 2 + ReadBits(length_nbits);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A prefix table is then built from `code_length_code_lengths` and used to read
up to `max_symbol` code lengths.
* Code \[0..15\] indicates literal code lengths.
* Value 0 means no symbols have been coded.
* Values \[1..15\] indicate the bit length of the respective code.
* Code 16 repeats the previous non-zero value \[3..6\] times, i.e.,
`3 + ReadBits(2)` times. If code 16 is used before a non-zero
value has been emitted, a value of 8 is repeated.
* Code 17 emits a streak of zeros \[3..10\], i.e., `3 + ReadBits(3)`
times.
* Code 18 emits a streak of zeros of length \[11..138\], i.e.,
`11 + ReadBits(7)` times.
Once code lengths are read, a prefix code for each symbol type (A, R, G, B,
distance) is formed using their respective alphabet sizes:
* G channel: 256 + 24 + `color_cache_size`
* other literals (A,R,B): 256
* distance code: 40
#### 5.2.2 Decoding of Meta Prefix Codes
As noted earlier, the format allows the use of different prefix codes for
different blocks of the image. _Meta prefix codes_ are indexes identifying
which prefix codes to use in different parts of the image.
Meta prefix codes may be used _only_ when the image is being used in the
[role](#roles-of-image-data) of an _ARGB image_.
There are two possibilities for the meta Huffman codes, indicated by a 1-bit
There are two possibilities for the meta prefix codes, indicated by a 1-bit
value:
* If this bit is zero, there is only one meta Huffman code used everywhere in
* If this bit is zero, there is only one meta prefix code used everywhere in
the image. No more data is stored.
* If this bit is one, the image uses multiple meta Huffman codes. These meta
Huffman codes are stored as an _entropy image_ (described below).
* If this bit is one, the image uses multiple meta prefix codes. These meta
prefix codes are stored as an _entropy image_ (described below).
**Entropy image:**
The entropy image defines which Huffman codes are used in different parts of the
The entropy image defines which prefix codes are used in different parts of the
image, as described below.
The first 3-bits contain the `huffman_bits` value. The dimensions of the entropy
image are derived from 'huffman_bits'.
The first 3-bits contain the `prefix_bits` value. The dimensions of the entropy
image are derived from 'prefix_bits'.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int huffman_bits = ReadBits(3) + 2;
int huffman_xsize = DIV_ROUND_UP(xsize, 1 << huffman_bits);
int huffman_ysize = DIV_ROUND_UP(ysize, 1 << huffman_bits);
int prefix_bits = ReadBits(3) + 2;
int prefix_xsize = DIV_ROUND_UP(xsize, 1 << prefix_bits);
int prefix_ysize = DIV_ROUND_UP(ysize, 1 << prefix_bits);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
where `DIV_ROUND_UP` is as defined [earlier](#predictor-transform).
Next bits contain an entropy image of width `huffman_xsize` and height
`huffman_ysize`.
The next bits contain an entropy image of width `prefix_xsize` and height
`prefix_ysize`.
**Interpretation of Meta Huffman Codes:**
**Interpretation of Meta Prefix Codes:**
For any given pixel (x, y), there is a set of five Huffman codes associated with
For any given pixel (x, y), there is a set of five prefix codes associated with
it. These codes are (in bitstream order):
* **Huffman code #1**: used for green channel, backward-reference length and
* **prefix code #1**: used for green channel, backward-reference length and
color cache
* **Huffman code #2, #3 and #4**: used for red, blue and alpha channels
* **prefix code #2, #3 and #4**: used for red, blue and alpha channels
respectively.
* **Huffman code #5**: used for backward-reference distance.
* **prefix code #5**: used for backward-reference distance.
From here on, we refer to this set as a **Huffman code group**.
From here on, we refer to this set as a **prefix code group**.
The number of Huffman code groups in the ARGB image can be obtained by finding
the _largest meta Huffman code_ from the entropy image:
The number of prefix code groups in the ARGB image can be obtained by finding
the _largest meta prefix code_ from the entropy image:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int num_huff_groups = max(entropy image) + 1;
int num_prefix_groups = max(entropy image) + 1;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
where `max(entropy image)` indicates the largest Huffman code stored in the
where `max(entropy image)` indicates the largest prefix code stored in the
entropy image.
As each Huffman code groups contains five Huffman codes, the total number of
Huffman codes is:
As each prefix code group contains five prefix codes, the total number of
prefix codes is:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int num_huff_codes = 5 * num_huff_groups;
int num_prefix_codes = 5 * num_prefix_groups;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Given a pixel (x, y) in the ARGB image, we can obtain the corresponding Huffman
Given a pixel (x, y) in the ARGB image, we can obtain the corresponding prefix
codes to be used as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int position = (y >> huffman_bits) * huffman_xsize + (x >> huffman_bits);
int meta_huff_code = (entropy_image[pos] >> 8) & 0xffff;
HuffmanCodeGroup huff_group = huffman_code_groups[meta_huff_code];
int position = (y >> prefix_bits) * prefix_xsize + (x >> prefix_bits);
int meta_prefix_code = (entropy_image[pos] >> 8) & 0xffff;
PrefixCodeGroup prefix_group = prefix_code_groups[meta_prefix_code];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
where, we have assumed the existence of `HuffmanCodeGroup` structure, which
represents a set of five Huffman codes. Also, `huffman_code_groups` is an array
of `HuffmanCodeGroup` (of size `num_huff_groups`).
where, we have assumed the existence of `PrefixCodeGroup` structure, which
represents a set of five prefix codes. Also, `prefix_code_groups` is an array
of `PrefixCodeGroup` (of size `num_prefix_groups`).
The decoder then uses Huffman code group `huff_group` to decode the pixel
The decoder then uses prefix code group `prefix_group` to decode the pixel
(x, y) as explained in the [next section](#decoding-entropy-coded-image-data).
#### 5.2.2 Decoding Entropy-coded Image Data
#### 5.2.3 Decoding Entropy-coded Image Data
\[AMENDED2\]
For the current position (x, y) in the image, the decoder first identifies the
corresponding Huffman code group (as explained in the last section). Given the
Huffman code group, the pixel is read and decoded as follows:
corresponding prefix code group (as explained in the last section). Given the
prefix code group, the pixel is read and decoded as follows:
Read next symbol S from the bitstream using Huffman code #1. \[See
[next section](#decoding-the-code-lengths) for details on decoding the Huffman
code lengths\]. Note that S is any integer in the range `0` to
`(256 + 24 + ` [`color_cache_size`](#color-cache-code)`- 1)`.
Read next symbol S from the bitstream using prefix code #1. Note that S is any
integer in the range `0` to
`(256 + 24 + ` [`color_cache_size`](#color-cache-code)` - 1)`.
The interpretation of S depends on its value:
1. if S < 256
1. Use S as the green component
1. Read red from the bitstream using Huffman code #2
1. Read blue from the bitstream using Huffman code #3
1. Read alpha from the bitstream using Huffman code #4
1. if S < 256 + 24
1. Use S - 256 as a length prefix code
1. Read extra bits for length from the bitstream
1. Use S as the green component.
1. Read red from the bitstream using prefix code #2.
1. Read blue from the bitstream using prefix code #3.
1. Read alpha from the bitstream using prefix code #4.
1. if S >= 256 && S < 256 + 24
1. Use S - 256 as a length prefix code.
1. Read extra bits for length from the bitstream.
1. Determine backward-reference length L from length prefix code and the
extra bits read.
1. Read distance prefix code from the bitstream using Huffman code #5
1. Read extra bits for distance from the bitstream
1. Read distance prefix code from the bitstream using prefix code #5.
1. Read extra bits for distance from the bitstream.
1. Determine backward-reference distance D from distance prefix code and
the extra bits read.
1. Copy the L pixels (in scan-line order) from the sequence of pixels
@ -947,80 +1071,6 @@ The interpretation of S depends on its value:
1. Get ARGB color from the color cache at that index.
**Decoding the Code Lengths:**
{:#decoding-the-code-lengths}
This section describes the details about reading a symbol from the bitstream by
decoding the Huffman code length.
The Huffman code lengths can be coded in two ways. The method used is specified
by a 1-bit value.
* If this bit is 1, it is a _simple code length code_, and
* If this bit is 0, it is a _normal code length code_.
**(i) Simple Code Length Code:**
This variant is used in the special case when only 1 or 2 Huffman code lengths
are non-zero, and are in the range of \[0, 255\]. All other Huffman code lengths
are implicitly zeros.
The first bit indicates the number of non-zero code lengths:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int num_code_lengths = ReadBits(1) + 1;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The first code length is stored either using a 1-bit code for values of 0 and 1,
or using an 8-bit code for values in range \[0, 255\]. The second code length,
when present, is coded as an 8-bit code.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int is_first_8bits = ReadBits(1);
code_lengths[0] = ReadBits(1 + 7 * is_first_8bits);
if (num_code_lengths == 2) {
code_lengths[1] = ReadBits(8);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Note:** Another special case is when _all_ Huffman code lengths are _zeros_
(an empty Huffman code). For example, a Huffman code for distance can be empty
if there are no backward references. Similarly, Huffman codes for alpha, red,
and blue can be empty if all pixels within the same meta Huffman code are
produced using the color cache. However, this case doesn't need a special
handling, as empty Huffman codes can be coded as those containing a single
symbol `0`.
**(ii) Normal Code Length Code:**
The code lengths of a Huffman code are read as follows: `num_code_lengths`
specifies the number of code lengths; the rest of the code lengths
(according to the order in `kCodeLengthCodeOrder`) are zeros.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int kCodeLengthCodes = 19;
int kCodeLengthCodeOrder[kCodeLengthCodes] = {
17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
};
int code_lengths[kCodeLengthCodes] = { 0 }; // All zeros.
int num_code_lengths = 4 + ReadBits(4);
for (i = 0; i < num_code_lengths; ++i) {
code_lengths[kCodeLengthCodeOrder[i]] = ReadBits(3);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Code length code \[0..15\] indicates literal code lengths.
* Value 0 means no symbols have been coded.
* Values \[1..15\] indicate the bit length of the respective code.
* Code 16 repeats the previous non-zero value \[3..6\] times, i.e.,
3 + `ReadBits(2)` times. If code 16 is used before a non-zero
value has been emitted, a value of 8 is repeated.
* Code 17 emits a streak of zeros \[3..10\], i.e., 3 + `ReadBits(3)`
times.
* Code 18 emits a streak of zeros of length \[11..138\], i.e.,
11 + `ReadBits(7)` times.
6 Overall Structure of the Format
---------------------------------
@ -1056,23 +1106,26 @@ of pixels (xsize * ysize).
#### Structure of the Image Data
\[AMENDED2\]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<spatially-coded image> ::= <meta huffman><entropy-coded image>
<entropy-coded image> ::= <color cache info><huffman codes><lz77-coded image>
<meta huffman> ::= 1-bit value 0 |
(1-bit value 1; <entropy image>)
<entropy image> ::= 3-bit subsample value; <entropy-coded image>
<spatially-coded image> ::= <color cache info><meta prefix><data>
<entropy-coded image> ::= <color cache info><data>
<color cache info> ::= 1 bit value 0 |
(1-bit value 1; 4-bit value for color cache size)
<huffman codes> ::= <huffman code group> | <huffman code group><huffman codes>
<huffman code group> ::= <huffman code><huffman code><huffman code>
<huffman code><huffman code>
See "Interpretation of Meta Huffman codes" to
understand what each of these five Huffman codes are
for.
<huffman code> ::= <simple huffman code> | <normal huffman code>
<simple huffman code> ::= see "Simple code length code" for details
<normal huffman code> ::= <code length code>; encoded code lengths
<meta prefix> ::= 1-bit value 0 |
(1-bit value 1; <entropy image>)
<data> ::= <prefix codes><lz77-coded image>
<entropy image> ::= 3-bit subsample value; <entropy-coded image>
<prefix codes> ::= <prefix code group> | <prefix code group><prefix codes>
<prefix code group> ::= <prefix code><prefix code><prefix code>
<prefix code><prefix code>
See "Interpretation of Meta Prefix Codes" to
understand what each of these five prefix codes are
for.
<prefix code> ::= <simple prefix code> | <normal prefix code>
<simple prefix code> ::= see "Simple code length code" for details
<normal prefix code> ::= <code length code>; encoded code lengths
<code length code> ::= see section "Normal code length code"
<lz77-coded image> ::= ((<argb-pixel> | <lz77-copy> | <color-cache-code>)
<lz77-coded image>) | ""
@ -1082,9 +1135,8 @@ A possible example sequence:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<RIFF header><image size>1-bit value 1<subtract-green-tx>
1-bit value 1<predictor-tx>1-bit value 0<meta huffman>
<color cache info><huffman codes>
<lz77-coded image>
1-bit value 1<predictor-tx>1-bit value 0<color cache info>1-bit value 0
<prefix codes><lz77-coded image>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[canonical_huff]: http://en.wikipedia.org/wiki/Canonical_Huffman_code
[canonical_huff]: https://en.wikipedia.org/wiki/Canonical_Huffman_code

View File

@ -26,8 +26,7 @@ LOCAL_SRC_FILES := \
cwebp.c \
LOCAL_CFLAGS := $(WEBP_CFLAGS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webp
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpdemux webp
LOCAL_MODULE := cwebp
@ -42,9 +41,7 @@ LOCAL_SRC_FILES := \
dwebp.c \
LOCAL_CFLAGS := $(WEBP_CFLAGS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
LOCAL_STATIC_LIBRARIES := example_util imagedec imageenc webp
LOCAL_STATIC_LIBRARIES := example_util imagedec imageenc webpdemux webp
LOCAL_MODULE := dwebp
include $(BUILD_EXECUTABLE)
@ -58,7 +55,6 @@ LOCAL_SRC_FILES := \
webpmux.c \
LOCAL_CFLAGS := $(WEBP_CFLAGS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
LOCAL_STATIC_LIBRARIES := example_util imageio_util webpmux webp
LOCAL_MODULE := webpmux_example
@ -74,9 +70,24 @@ LOCAL_SRC_FILES := \
img2webp.c \
LOCAL_CFLAGS := $(WEBP_CFLAGS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpmux webp
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpmux webpdemux \
webp
LOCAL_MODULE := img2webp_example
include $(BUILD_EXECUTABLE)
################################################################################
# webpinfo
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
webpinfo.c \
LOCAL_CFLAGS := $(WEBP_CFLAGS)
LOCAL_STATIC_LIBRARIES := example_util imageio_util webp
LOCAL_MODULE := webpinfo_example
include $(BUILD_EXECUTABLE)

View File

@ -1,8 +1,11 @@
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
bin_PROGRAMS = dwebp cwebp
bin_PROGRAMS =
if BUILD_DEMUX
bin_PROGRAMS += dwebp cwebp
endif
if BUILD_ANIMDIFF
noinst_PROGRAMS = anim_diff
noinst_PROGRAMS = anim_diff anim_dump
endif
if BUILD_GIF2WEBP
bin_PROGRAMS += gif2webp
@ -10,34 +13,53 @@ endif
if BUILD_IMG2WEBP
bin_PROGRAMS += img2webp
endif
if WANT_MUX
if BUILD_MUX
bin_PROGRAMS += webpmux
endif
if BUILD_VWEBP
bin_PROGRAMS += vwebp
endif
if BUILD_WEBPINFO
bin_PROGRAMS += webpinfo
endif
noinst_LTLIBRARIES = libexample_util.la
libexample_util_la_SOURCES = example_util.c example_util.h
libexample_util_la_LIBADD = ../src/libwebp.la
anim_diff_SOURCES = anim_diff.c anim_util.c anim_util.h
anim_diff_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GIF_INCLUDES)
anim_diff_LDADD = ../src/demux/libwebpdemux.la
anim_diff_LDADD += libexample_util.la ../imageio/libimageio_util.la
anim_diff_SOURCES = anim_diff.c anim_util.c anim_util.h gifdec.c gifdec.h
anim_diff_CPPFLAGS = $(AM_CPPFLAGS) $(GIF_INCLUDES)
anim_diff_LDADD =
anim_diff_LDADD += ../src/demux/libwebpdemux.la
anim_diff_LDADD += libexample_util.la
anim_diff_LDADD += ../imageio/libimageio_util.la
anim_diff_LDADD += $(GIF_LIBS) -lm
anim_dump_SOURCES = anim_dump.c anim_util.c anim_util.h gifdec.c gifdec.h
anim_dump_CPPFLAGS = $(AM_CPPFLAGS) $(PNG_INCLUDES)
anim_dump_CPPFLAGS += $(GIF_INCLUDES)
anim_dump_LDADD =
anim_dump_LDADD += ../src/demux/libwebpdemux.la
anim_dump_LDADD += libexample_util.la
anim_dump_LDADD += ../imageio/libimageio_util.la
anim_dump_LDADD += ../imageio/libimageenc.la
anim_dump_LDADD += $(PNG_LIBS) $(GIF_LIBS) $(TIFF_LIBS) -lm
cwebp_SOURCES = cwebp.c stopwatch.h
cwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
cwebp_LDADD = libexample_util.la ../imageio/libimageio_util.la
cwebp_LDADD += ../imageio/libimagedec.la ../src/libwebp.la
cwebp_CPPFLAGS = $(AM_CPPFLAGS)
cwebp_LDADD =
cwebp_LDADD += libexample_util.la
cwebp_LDADD += ../imageio/libimageio_util.la
cwebp_LDADD += ../imageio/libimagedec.la
cwebp_LDADD += ../src/libwebp.la
cwebp_LDADD += $(JPEG_LIBS) $(PNG_LIBS) $(TIFF_LIBS)
dwebp_SOURCES = dwebp.c stopwatch.h
dwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
dwebp_CPPFLAGS = $(AM_CPPFLAGS)
dwebp_CPPFLAGS += $(JPEG_INCLUDES) $(PNG_INCLUDES)
dwebp_LDADD = libexample_util.la
dwebp_LDADD =
dwebp_LDADD += libexample_util.la
dwebp_LDADD += ../imageio/libimagedec.la
dwebp_LDADD += ../imageio/libimageenc.la
dwebp_LDADD += ../imageio/libimageio_util.la
@ -45,31 +67,53 @@ dwebp_LDADD += ../src/libwebp.la
dwebp_LDADD +=$(PNG_LIBS) $(JPEG_LIBS)
gif2webp_SOURCES = gif2webp.c gifdec.c gifdec.h
gif2webp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GIF_INCLUDES)
gif2webp_LDADD = libexample_util.la ../imageio/libimageio_util.la
gif2webp_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la $(GIF_LIBS)
gif2webp_CPPFLAGS = $(AM_CPPFLAGS) $(GIF_INCLUDES)
gif2webp_LDADD =
gif2webp_LDADD += libexample_util.la
gif2webp_LDADD += ../imageio/libimageio_util.la
gif2webp_LDADD += ../src/mux/libwebpmux.la
gif2webp_LDADD += ../src/libwebp.la
gif2webp_LDADD += $(GIF_LIBS)
vwebp_SOURCES = vwebp.c
vwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GL_INCLUDES)
vwebp_LDADD = libexample_util.la ../imageio/libimageio_util.la
vwebp_LDADD += ../src/demux/libwebpdemux.la $(GL_LIBS)
vwebp_CPPFLAGS = $(AM_CPPFLAGS) $(GL_INCLUDES)
vwebp_LDADD =
vwebp_LDADD += libexample_util.la
vwebp_LDADD += ../imageio/libimageio_util.la
vwebp_LDADD += ../src/demux/libwebpdemux.la
vwebp_LDADD += $(GL_LIBS)
webpmux_SOURCES = webpmux.c
webpmux_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
webpmux_LDADD = libexample_util.la ../imageio/libimageio_util.la
webpmux_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la
webpmux_CPPFLAGS = $(AM_CPPFLAGS)
webpmux_LDADD =
webpmux_LDADD += libexample_util.la
webpmux_LDADD += ../imageio/libimageio_util.la
webpmux_LDADD += ../src/mux/libwebpmux.la
webpmux_LDADD += ../src/libwebp.la
img2webp_SOURCES = img2webp.c
img2webp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
img2webp_LDADD = libexample_util.la ../imageio/libimageio_util.la
img2webp_CPPFLAGS = $(AM_CPPFLAGS)
img2webp_LDADD =
img2webp_LDADD += libexample_util.la
img2webp_LDADD += ../imageio/libimageio_util.la
img2webp_LDADD += ../imageio/libimagedec.la
img2webp_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la
img2webp_LDADD += ../src/mux/libwebpmux.la
img2webp_LDADD += ../src/libwebp.la
img2webp_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS)
webpinfo_SOURCES = webpinfo.c
webpinfo_CPPFLAGS = $(AM_CPPFLAGS)
webpinfo_LDADD =
webpinfo_LDADD += libexample_util.la
webpinfo_LDADD += ../imageio/libimageio_util.la
webpinfo_LDADD += ../src/libwebp.la
if BUILD_LIBWEBPDECODER
anim_diff_LDADD += ../src/libwebpdecoder.la
anim_dump_LDADD += ../src/libwebpdecoder.la
vwebp_LDADD += ../src/libwebpdecoder.la
else
anim_diff_LDADD += ../src/libwebp.la
anim_dump_LDADD += ../src/libwebp.la
vwebp_LDADD += ../src/libwebp.la
endif

View File

@ -20,6 +20,8 @@
#include <string.h> // for 'strcmp'.
#include "./anim_util.h"
#include "./example_util.h"
#include "./unicode.h"
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
@ -143,8 +145,18 @@ static int CompareAnimatedImagePair(const AnimatedImage* const img1,
if (!ok) return 0; // These are fatal failures, can't proceed.
if (is_multi_frame_image) { // Checks relevant for multi-frame images only.
ok = CompareValues(img1->loop_count, img2->loop_count,
"Loop count mismatch") && ok;
int max_loop_count_workaround = 0;
// Transcodes to webp increase the gif loop count by 1 for compatibility.
// When the gif has the maximum value the webp value will be off by one.
if ((img1->format == ANIM_GIF && img1->loop_count == 65536 &&
img2->format == ANIM_WEBP && img2->loop_count == 65535) ||
(img1->format == ANIM_WEBP && img1->loop_count == 65535 &&
img2->format == ANIM_GIF && img2->loop_count == 65536)) {
max_loop_count_workaround = 1;
}
ok = (max_loop_count_workaround ||
CompareValues(img1->loop_count, img2->loop_count,
"Loop count mismatch")) && ok;
ok = CompareBackgroundColor(img1->bgcolor, img2->bgcolor,
premultiply) && ok;
}
@ -187,11 +199,11 @@ static void Help(void) {
printf(" -min_psnr <float> ... minimum per-frame PSNR\n");
printf(" -raw_comparison ..... if this flag is not used, RGB is\n");
printf(" premultiplied before comparison\n");
#ifdef WEBP_EXPERIMENTAL_FEATURES
printf(" -max_diff <int> ..... maximum allowed difference per channel "
" between corresponding pixels in subsequent"
printf(" -max_diff <int> ..... maximum allowed difference per channel\n"
" between corresponding pixels in subsequent\n"
" frames\n");
#endif
printf(" -h .................. this help\n");
printf(" -version ............ print version number and exit\n");
}
int main(int argc, const char* argv[]) {
@ -207,56 +219,49 @@ int main(int argc, const char* argv[]) {
const char* files[2] = { NULL, NULL };
AnimatedImage images[2];
if (argc < 3) {
Help();
return -1;
}
INIT_WARGV(argc, argv);
for (c = 1; c < argc; ++c) {
int parse_error = 0;
if (!strcmp(argv[c], "-dump_frames")) {
if (c < argc - 1) {
dump_frames = 1;
dump_folder = argv[++c];
dump_folder = (const char*)GET_WARGV(argv, ++c);
} else {
parse_error = 1;
}
} else if (!strcmp(argv[c], "-min_psnr")) {
if (c < argc - 1) {
const char* const v = argv[++c];
char* end = NULL;
const double d = strtod(v, &end);
if (end == v) {
parse_error = 1;
fprintf(stderr, "Error! '%s' is not a floating point number.\n", v);
}
min_psnr = d;
min_psnr = ExUtilGetFloat(argv[++c], &parse_error);
} else {
parse_error = 1;
}
} else if (!strcmp(argv[c], "-raw_comparison")) {
premultiply = 0;
#ifdef WEBP_EXPERIMENTAL_FEATURES
} else if (!strcmp(argv[c], "-max_diff")) {
if (c < argc - 1) {
const char* const v = argv[++c];
char* end = NULL;
const int n = (int)strtol(v, &end, 10);
if (end == v) {
parse_error = 1;
fprintf(stderr, "Error! '%s' is not an integer.\n", v);
}
max_diff = n;
max_diff = ExUtilGetInt(argv[++c], 0, &parse_error);
} else {
parse_error = 1;
}
#endif
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
Help();
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-version")) {
int dec_version, demux_version;
GetAnimatedImageVersions(&dec_version, &demux_version);
printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n",
(dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
(dec_version >> 0) & 0xff,
(demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff,
(demux_version >> 0) & 0xff);
FREE_WARGV_AND_RETURN(0);
} else {
if (!got_input1) {
files[0] = argv[c];
files[0] = (const char*)GET_WARGV(argv, c);
got_input1 = 1;
} else if (!got_input2) {
files[1] = argv[c];
files[1] = (const char*)GET_WARGV(argv, c);
got_input2 = 1;
} else {
parse_error = 1;
@ -264,23 +269,30 @@ int main(int argc, const char* argv[]) {
}
if (parse_error) {
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
}
if (argc < 3) {
Help();
FREE_WARGV_AND_RETURN(-1);
}
if (!got_input2) {
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
if (dump_frames) {
printf("Dumping decoded frames in: %s\n", dump_folder);
WPRINTF("Dumping decoded frames in: %s\n", (const W_CHAR*)dump_folder);
}
memset(images, 0, sizeof(images));
for (i = 0; i < 2; ++i) {
printf("Decoding file: %s\n", files[i]);
WPRINTF("Decoding file: %s\n", (const W_CHAR*)files[i]);
if (!ReadAnimatedImage(files[i], &images[i], dump_frames, dump_folder)) {
fprintf(stderr, "Error decoding file: %s\n Aborting.\n", files[i]);
WFPRINTF(stderr, "Error decoding file: %s\n Aborting.\n",
(const W_CHAR*)files[i]);
return_code = -2;
goto End;
} else {
@ -290,14 +302,16 @@ int main(int argc, const char* argv[]) {
if (!CompareAnimatedImagePair(&images[0], &images[1],
premultiply, min_psnr)) {
fprintf(stderr, "\nFiles %s and %s differ.\n", files[0], files[1]);
WFPRINTF(stderr, "\nFiles %s and %s differ.\n", (const W_CHAR*)files[0],
(const W_CHAR*)files[1]);
return_code = -3;
} else {
printf("\nFiles %s and %s are identical.\n", files[0], files[1]);
WPRINTF("\nFiles %s and %s are identical.\n", (const W_CHAR*)files[0],
(const W_CHAR*)files[1]);
return_code = 0;
}
End:
ClearAnimatedImage(&images[0]);
ClearAnimatedImage(&images[1]);
return return_code;
FREE_WARGV_AND_RETURN(return_code);
}

121
examples/anim_dump.c Normal file
View File

@ -0,0 +1,121 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Decodes an animated WebP file and dumps the decoded frames as PNG or TIFF.
//
// Author: Skal (pascal.massimino@gmail.com)
#include <stdio.h>
#include <string.h> // for 'strcmp'.
#include "./anim_util.h"
#include "webp/decode.h"
#include "../imageio/image_enc.h"
#include "./unicode.h"
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
#endif
static void Help(void) {
printf("Usage: anim_dump [options] files...\n");
printf("\nOptions:\n");
printf(" -folder <string> .... dump folder (default: '.')\n");
printf(" -prefix <string> .... prefix for dumped frames "
"(default: 'dump_')\n");
printf(" -tiff ............... save frames as TIFF\n");
printf(" -pam ................ save frames as PAM\n");
printf(" -h .................. this help\n");
printf(" -version ............ print version number and exit\n");
}
int main(int argc, const char* argv[]) {
int error = 0;
const W_CHAR* dump_folder = TO_W_CHAR(".");
const W_CHAR* prefix = TO_W_CHAR("dump_");
const W_CHAR* suffix = TO_W_CHAR("png");
WebPOutputFileFormat format = PNG;
int c;
INIT_WARGV(argc, argv);
if (argc < 2) {
Help();
FREE_WARGV_AND_RETURN(-1);
}
for (c = 1; !error && c < argc; ++c) {
if (!strcmp(argv[c], "-folder")) {
if (c + 1 == argc) {
fprintf(stderr, "missing argument after option '%s'\n", argv[c]);
error = 1;
break;
}
dump_folder = GET_WARGV(argv, ++c);
} else if (!strcmp(argv[c], "-prefix")) {
if (c + 1 == argc) {
fprintf(stderr, "missing argument after option '%s'\n", argv[c]);
error = 1;
break;
}
prefix = GET_WARGV(argv, ++c);
} else if (!strcmp(argv[c], "-tiff")) {
format = TIFF;
suffix = TO_W_CHAR("tiff");
} else if (!strcmp(argv[c], "-pam")) {
format = PAM;
suffix = TO_W_CHAR("pam");
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
Help();
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-version")) {
int dec_version, demux_version;
GetAnimatedImageVersions(&dec_version, &demux_version);
printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n",
(dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
(dec_version >> 0) & 0xff,
(demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff,
(demux_version >> 0) & 0xff);
FREE_WARGV_AND_RETURN(0);
} else {
uint32_t i;
AnimatedImage image;
const W_CHAR* const file = GET_WARGV(argv, c);
memset(&image, 0, sizeof(image));
WPRINTF("Decoding file: %s as %s/%sxxxx.%s\n",
file, dump_folder, prefix, suffix);
if (!ReadAnimatedImage((const char*)file, &image, 0, NULL)) {
WFPRINTF(stderr, "Error decoding file: %s\n Aborting.\n", file);
error = 1;
break;
}
for (i = 0; !error && i < image.num_frames; ++i) {
W_CHAR out_file[1024];
WebPDecBuffer buffer;
WebPInitDecBuffer(&buffer);
buffer.colorspace = MODE_RGBA;
buffer.is_external_memory = 1;
buffer.width = image.canvas_width;
buffer.height = image.canvas_height;
buffer.u.RGBA.rgba = image.frames[i].rgba;
buffer.u.RGBA.stride = buffer.width * sizeof(uint32_t);
buffer.u.RGBA.size = buffer.u.RGBA.stride * buffer.height;
WSNPRINTF(out_file, sizeof(out_file), "%s/%s%.4d.%s",
dump_folder, prefix, i, suffix);
if (!WebPSaveImage(&buffer, format, (const char*)out_file)) {
WFPRINTF(stderr, "Error while saving image '%s'\n", out_file);
error = 1;
}
WebPFreeDecBuffer(&buffer);
}
ClearAnimatedImage(&image);
}
}
FREE_WARGV_AND_RETURN(error ? 1 : 0);
}

View File

@ -16,13 +16,16 @@
#include <stdio.h>
#include <string.h>
#ifdef WEBP_HAVE_GIF
#if defined(WEBP_HAVE_GIF)
#include <gif_lib.h>
#endif
#include "webp/format_constants.h"
#include "webp/decode.h"
#include "webp/demux.h"
#include "../imageio/imageio_util.h"
#include "./gifdec.h"
#include "./unicode.h"
#include "./unicode_gif.h"
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
@ -33,11 +36,13 @@ static const int kNumChannels = 4;
// -----------------------------------------------------------------------------
// Common utilities.
#if defined(WEBP_HAVE_GIF)
// Returns true if the frame covers the full canvas.
static int IsFullFrame(int width, int height,
int canvas_width, int canvas_height) {
return (width == canvas_width && height == canvas_height);
}
#endif // WEBP_HAVE_GIF
static int CheckSizeForOverflow(uint64_t size) {
return (size == (size_t)size);
@ -55,15 +60,15 @@ static int AllocateFrames(AnimatedImage* const image, uint32_t num_frames) {
!CheckSizeForOverflow(total_frame_size)) {
return 0;
}
mem = (uint8_t*)malloc((size_t)total_size);
frames = (DecodedFrame*)malloc((size_t)total_frame_size);
mem = (uint8_t*)WebPMalloc((size_t)total_size);
frames = (DecodedFrame*)WebPMalloc((size_t)total_frame_size);
if (mem == NULL || frames == NULL) {
free(mem);
free(frames);
WebPFree(mem);
WebPFree(frames);
return 0;
}
free(image->raw_mem);
WebPFree(image->raw_mem);
image->num_frames = num_frames;
image->frames = frames;
for (i = 0; i < num_frames; ++i) {
@ -77,14 +82,15 @@ static int AllocateFrames(AnimatedImage* const image, uint32_t num_frames) {
void ClearAnimatedImage(AnimatedImage* const image) {
if (image != NULL) {
free(image->raw_mem);
free(image->frames);
WebPFree(image->raw_mem);
WebPFree(image->frames);
image->num_frames = 0;
image->frames = NULL;
image->raw_mem = NULL;
}
}
#if defined(WEBP_HAVE_GIF)
// Clear the canvas to transparent.
static void ZeroFillCanvas(uint8_t* rgba,
uint32_t canvas_width, uint32_t canvas_height) {
@ -126,6 +132,7 @@ static void CopyFrameRectangle(const uint8_t* src, uint8_t* dst, int stride,
dst += stride;
}
}
#endif // WEBP_HAVE_GIF
// Canonicalize all transparent pixels to transparent black to aid comparison.
static void CleanupTransparentPixels(uint32_t* rgba,
@ -147,40 +154,42 @@ static int DumpFrame(const char filename[], const char dump_folder[],
int ok = 0;
size_t max_len;
int y;
const char* base_name = NULL;
char* file_name = NULL;
const W_CHAR* base_name = NULL;
W_CHAR* file_name = NULL;
FILE* f = NULL;
const char* row;
base_name = strrchr(filename, '/');
base_name = (base_name == NULL) ? filename : base_name + 1;
max_len = strlen(dump_folder) + 1 + strlen(base_name)
if (dump_folder == NULL) dump_folder = (const char*)TO_W_CHAR(".");
base_name = WSTRRCHR(filename, '/');
base_name = (base_name == NULL) ? (const W_CHAR*)filename : base_name + 1;
max_len = WSTRLEN(dump_folder) + 1 + WSTRLEN(base_name)
+ strlen("_frame_") + strlen(".pam") + 8;
file_name = (char*)malloc(max_len * sizeof(*file_name));
file_name = (W_CHAR*)WebPMalloc(max_len * sizeof(*file_name));
if (file_name == NULL) goto End;
if (snprintf(file_name, max_len, "%s/%s_frame_%d.pam",
dump_folder, base_name, frame_num) < 0) {
if (WSNPRINTF(file_name, max_len, "%s/%s_frame_%d.pam",
(const W_CHAR*)dump_folder, base_name, frame_num) < 0) {
fprintf(stderr, "Error while generating file name\n");
goto End;
}
f = fopen(file_name, "wb");
f = WFOPEN(file_name, "wb");
if (f == NULL) {
fprintf(stderr, "Error opening file for writing: %s\n", file_name);
WFPRINTF(stderr, "Error opening file for writing: %s\n", file_name);
ok = 0;
goto End;
}
if (fprintf(f, "P7\nWIDTH %d\nHEIGHT %d\n"
"DEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n",
canvas_width, canvas_height) < 0) {
fprintf(stderr, "Write error for file %s\n", file_name);
WFPRINTF(stderr, "Write error for file %s\n", file_name);
goto End;
}
row = (const char*)rgba;
for (y = 0; y < canvas_height; ++y) {
if (fwrite(row, canvas_width * kNumChannels, 1, f) != 1) {
fprintf(stderr, "Error writing to file: %s\n", file_name);
WFPRINTF(stderr, "Error writing to file: %s\n", file_name);
goto End;
}
row += canvas_width * kNumChannels;
@ -188,7 +197,7 @@ static int DumpFrame(const char filename[], const char dump_folder[],
ok = 1;
End:
if (f != NULL) fclose(f);
free(file_name);
WebPFree(file_name);
return ok;
}
@ -200,7 +209,7 @@ static int IsWebP(const WebPData* const webp_data) {
return (WebPGetInfo(webp_data->bytes, webp_data->size, NULL, NULL) != 0);
}
// Read animated WebP bitstream 'file_str' into 'AnimatedImage' struct.
// Read animated WebP bitstream 'webp_data' into 'AnimatedImage' struct.
static int ReadAnimatedWebP(const char filename[],
const WebPData* const webp_data,
AnimatedImage* const image, int dump_frames,
@ -216,7 +225,7 @@ static int ReadAnimatedWebP(const char filename[],
dec = WebPAnimDecoderNew(webp_data, NULL);
if (dec == NULL) {
fprintf(stderr, "Error parsing image: %s\n", filename);
WFPRINTF(stderr, "Error parsing image: %s\n", (const W_CHAR*)filename);
goto End;
}
@ -232,7 +241,7 @@ static int ReadAnimatedWebP(const char filename[],
image->bgcolor = anim_info.bgcolor;
// Allocate frames.
if (!AllocateFrames(image, anim_info.frame_count)) return 0;
if (!AllocateFrames(image, anim_info.frame_count)) goto End;
// Decode frames.
while (WebPAnimDecoderHasMoreFrames(dec)) {
@ -269,6 +278,7 @@ static int ReadAnimatedWebP(const char filename[],
prev_frame_timestamp = timestamp;
}
ok = dump_ok;
if (ok) image->format = ANIM_WEBP;
End:
WebPAnimDecoderDelete(dec);
@ -278,7 +288,7 @@ static int ReadAnimatedWebP(const char filename[],
// -----------------------------------------------------------------------------
// GIF Decoding.
#ifdef WEBP_HAVE_GIF
#if defined(WEBP_HAVE_GIF)
// Returns true if this is a valid GIF bitstream.
static int IsGIF(const WebPData* const data) {
@ -363,26 +373,6 @@ static int DGifSavedExtensionToGCB(GifFileType* GifFile, int ImageIndex,
#define DGifCloseFile(a, b) DGifCloseFile(a)
#endif
static void GIFDisplayError(const GifFileType* const gif, int gif_error) {
// libgif 4.2.0 has retired PrintGifError() and added GifErrorString().
#if LOCAL_GIF_PREREQ(4, 2)
#if LOCAL_GIF_PREREQ(5, 0)
const char* error_str =
GifErrorString((gif == NULL) ? gif_error : gif->Error);
#else
const char* error_str = GifErrorString();
(void)gif;
#endif
if (error_str == NULL) error_str = "Unknown error";
fprintf(stderr, "GIFLib Error %d: %s\n", gif_error, error_str);
#else
(void)gif;
fprintf(stderr, "GIFLib Error %d: ", gif_error);
PrintGifError();
fprintf(stderr, "\n");
#endif
}
static int IsKeyFrameGIF(const GifImageDesc* prev_desc, int prev_dispose,
const DecodedFrame* const prev_frame,
int canvas_width, int canvas_height) {
@ -415,7 +405,7 @@ static uint32_t GetBackgroundColorGIF(GifFileType* gif) {
return 0xffffffff; // Invalid: assume white.
} else {
const GifColorType color = color_map->Colors[gif->SBackGroundColor];
return (0xff << 24) |
return (0xffu << 24) |
(color.Red << 16) |
(color.Green << 8) |
(color.Blue << 0);
@ -423,6 +413,11 @@ static uint32_t GetBackgroundColorGIF(GifFileType* gif) {
}
// Find appropriate app extension and get loop count from the next extension.
// We use Chrome's interpretation of the 'loop_count' semantics:
// if not present -> loop once
// if present and loop_count == 0, return 0 ('infinite').
// if present and loop_count != 0, it's the number of *extra* loops
// so we need to return loop_count + 1 as total loop number.
static uint32_t GetLoopCountGIF(const GifFileType* const gif) {
int i;
for (i = 0; i < gif->ImageCount; ++i) {
@ -440,12 +435,13 @@ static uint32_t GetLoopCountGIF(const GifFileType* const gif) {
if (signature_is_ok &&
eb2->Function == CONTINUE_EXT_FUNC_CODE && eb2->ByteCount >= 3 &&
eb2->Bytes[0] == 1) {
return ((uint32_t)(eb2->Bytes[2]) << 8) +
((uint32_t)(eb2->Bytes[1]) << 0);
const uint32_t extra_loop = ((uint32_t)(eb2->Bytes[2]) << 8) +
((uint32_t)(eb2->Bytes[1]) << 0);
return (extra_loop > 0) ? extra_loop + 1 : 0;
}
}
}
return 0; // Default.
return 1; // Default.
}
// Get duration of 'n'th frame in milliseconds.
@ -517,15 +513,15 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
int gif_error;
GifFileType* gif;
gif = DGifOpenFileName(filename, NULL);
gif = DGifOpenFileUnicode((const W_CHAR*)filename, NULL);
if (gif == NULL) {
fprintf(stderr, "Could not read file: %s.\n", filename);
WFPRINTF(stderr, "Could not read file: %s.\n", (const W_CHAR*)filename);
return 0;
}
gif_error = DGifSlurp(gif);
if (gif_error != GIF_OK) {
fprintf(stderr, "Could not parse image: %s.\n", filename);
WFPRINTF(stderr, "Could not parse image: %s.\n", (const W_CHAR*)filename);
GIFDisplayError(gif, gif_error);
DGifCloseFile(gif, NULL);
return 0;
@ -562,7 +558,10 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
}
}
// Allocate frames.
AllocateFrames(image, frame_count);
if (!AllocateFrames(image, frame_count)) {
DGifCloseFile(gif, NULL);
return 0;
}
canvas_width = image->canvas_width;
canvas_height = image->canvas_height;
@ -581,6 +580,9 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
curr_frame = &image->frames[i];
curr_rgba = curr_frame->rgba;
curr_frame->duration = GetFrameDurationGIF(gif, i);
// Force frames with a small or no duration to 100ms to be consistent
// with web browsers and other transcoding tools (like gif2webp itself).
if (curr_frame->duration <= 10) curr_frame->duration = 100;
if (i == 0) { // Initialize as transparent.
curr_frame->is_key_frame = 1;
@ -672,6 +674,7 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
}
}
}
image->format = ANIM_GIF;
DGifCloseFile(gif, NULL);
return 1;
}
@ -707,7 +710,7 @@ int ReadAnimatedImage(const char filename[], AnimatedImage* const image,
memset(image, 0, sizeof(*image));
if (!ImgIoUtilReadFile(filename, &webp_data.bytes, &webp_data.size)) {
fprintf(stderr, "Error reading file: %s\n", filename);
WFPRINTF(stderr, "Error reading file: %s\n", (const W_CHAR*)filename);
return 0;
}
@ -717,9 +720,9 @@ int ReadAnimatedImage(const char filename[], AnimatedImage* const image,
} else if (IsGIF(&webp_data)) {
ok = ReadAnimatedGIF(filename, image, dump_frames, dump_folder);
} else {
fprintf(stderr,
"Unknown file type: %s. Supported file types are WebP and GIF\n",
filename);
WFPRINTF(stderr,
"Unknown file type: %s. Supported file types are WebP and GIF\n",
(const W_CHAR*)filename);
ok = 0;
}
if (!ok) ClearAnimatedImage(image);
@ -771,3 +774,9 @@ void GetDiffAndPSNR(const uint8_t rgba1[], const uint8_t rgba2[],
*psnr = 4.3429448 * log(255. * 255. / sse);
}
}
void GetAnimatedImageVersions(int* const decoder_version,
int* const demux_version) {
*decoder_version = WebPGetDecoderVersion();
*demux_version = WebPGetDemuxVersion();
}

View File

@ -22,6 +22,11 @@
extern "C" {
#endif
typedef enum {
ANIM_GIF,
ANIM_WEBP
} AnimatedFileFormat;
typedef struct {
uint8_t* rgba; // Decoded and reconstructed full frame.
int duration; // Frame duration in milliseconds.
@ -29,6 +34,7 @@ typedef struct {
} DecodedFrame;
typedef struct {
AnimatedFileFormat format;
uint32_t canvas_width;
uint32_t canvas_height;
uint32_t bgcolor;
@ -56,6 +62,10 @@ void GetDiffAndPSNR(const uint8_t rgba1[], const uint8_t rgba2[],
uint32_t width, uint32_t height, int premultiply,
int* const max_diff, double* const psnr);
// Return library versions used by anim_util.
void GetAnimatedImageVersions(int* const decoder_version,
int* const demux_version);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@ -12,6 +12,7 @@
//
// Author: Skal (pascal.massimino@gmail.com)
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -23,7 +24,9 @@
#include "../examples/example_util.h"
#include "../imageio/image_dec.h"
#include "../imageio/imageio_util.h"
#include "../imageio/webpdec.h"
#include "./stopwatch.h"
#include "./unicode.h"
#include "webp/encode.h"
#ifndef WEBP_DLL
@ -88,9 +91,10 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
}
}
if (!ok) {
fprintf(stderr, "Error! Could not process file %s\n", filename);
WFPRINTF(stderr, "Error! Could not process file %s\n",
(const W_CHAR*)filename);
}
free((void*)data);
WebPFree((void*)data);
return ok;
}
@ -114,9 +118,10 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
}
End:
if (!ok) {
fprintf(stderr, "Error! Could not process file %s\n", filename);
WFPRINTF(stderr, "Error! Could not process file %s\n",
(const W_CHAR*)filename);
}
free((void*)data);
WebPFree((void*)data);
return ok;
}
@ -125,7 +130,8 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
static void AllocExtraInfo(WebPPicture* const pic) {
const int mb_w = (pic->width + 15) / 16;
const int mb_h = (pic->height + 15) / 16;
pic->extra_info = (uint8_t*)malloc(mb_w * mb_h * sizeof(*pic->extra_info));
pic->extra_info =
(uint8_t*)WebPMalloc(mb_w * mb_h * sizeof(*pic->extra_info));
}
static void PrintByteCount(const int bytes[4], int total_size,
@ -140,10 +146,11 @@ static void PrintByteCount(const int bytes[4], int total_size,
fprintf(stderr, "| %7d (%.1f%%)\n", total, 100.f * total / total_size);
}
static void PrintPercents(const int counts[4], int total) {
static void PrintPercents(const int counts[4]) {
int s;
const int total = counts[0] + counts[1] + counts[2] + counts[3];
for (s = 0; s < 4; ++s) {
fprintf(stderr, "| %2d%%", 100 * counts[s] / total);
fprintf(stderr, "| %3d%%", (int)(100. * counts[s] / total + .5));
}
fprintf(stderr, "| %7d\n", total);
}
@ -184,9 +191,10 @@ static void PrintExtraInfoLossless(const WebPPicture* const pic,
if (short_output) {
fprintf(stderr, "%7d %2.2f\n", stats->coded_size, stats->PSNR[3]);
} else {
fprintf(stderr, "File: %s\n", file_name);
WFPRINTF(stderr, "File: %s\n", (const W_CHAR*)file_name);
fprintf(stderr, "Dimension: %d x %d\n", pic->width, pic->height);
fprintf(stderr, "Output: %d bytes\n", stats->coded_size);
fprintf(stderr, "Output: %d bytes (%.2f bpp)\n", stats->coded_size,
8.f * stats->coded_size / pic->width / pic->height);
PrintFullLosslessInfo(stats, "ARGB");
}
}
@ -202,20 +210,23 @@ static void PrintExtraInfoLossy(const WebPPicture* const pic, int short_output,
const int num_i16 = stats->block_count[1];
const int num_skip = stats->block_count[2];
const int total = num_i4 + num_i16;
fprintf(stderr, "File: %s\n", file_name);
WFPRINTF(stderr, "File: %s\n", (const W_CHAR*)file_name);
fprintf(stderr, "Dimension: %d x %d%s\n",
pic->width, pic->height,
stats->alpha_data_size ? " (with alpha)" : "");
fprintf(stderr, "Output: "
"%d bytes Y-U-V-All-PSNR %2.2f %2.2f %2.2f %2.2f dB\n",
"%d bytes Y-U-V-All-PSNR %2.2f %2.2f %2.2f %2.2f dB\n"
" (%.2f bpp)\n",
stats->coded_size,
stats->PSNR[0], stats->PSNR[1], stats->PSNR[2], stats->PSNR[3]);
stats->PSNR[0], stats->PSNR[1], stats->PSNR[2], stats->PSNR[3],
8.f * stats->coded_size / pic->width / pic->height);
if (total > 0) {
int totals[4] = { 0, 0, 0, 0 };
fprintf(stderr, "block count: intra4: %d\n"
" intra16: %d (-> %.2f%%)\n",
num_i4, num_i16, 100.f * num_i16 / total);
fprintf(stderr, " skipped block: %d (%.2f%%)\n",
fprintf(stderr, "block count: intra4: %6d (%.2f%%)\n"
" intra16: %6d (%.2f%%)\n"
" skipped: %6d (%.2f%%)\n",
num_i4, 100.f * num_i4 / total,
num_i16, 100.f * num_i16 / total,
num_skip, 100.f * num_skip / total);
fprintf(stderr, "bytes used: header: %6d (%.1f%%)\n"
" mode-partition: %6d (%.1f%%)\n",
@ -239,7 +250,7 @@ static void PrintExtraInfoLossy(const WebPPicture* const pic, int short_output,
PrintByteCount(stats->residual_bytes[2], stats->coded_size, totals);
}
fprintf(stderr, " macroblocks: ");
PrintPercents(stats->segment_size, total);
PrintPercents(stats->segment_size);
fprintf(stderr, " quantizer: ");
PrintValues(stats->segment_quant);
fprintf(stderr, " filter level: ");
@ -304,7 +315,7 @@ static int DumpPicture(const WebPPicture* const picture, const char* PGM_name) {
const int alpha_height =
WebPPictureHasTransparency(picture) ? picture->height : 0;
const int height = picture->height + uv_height + alpha_height;
FILE* const f = fopen(PGM_name, "wb");
FILE* const f = WFOPEN(PGM_name, "wb");
if (f == NULL) return 0;
fprintf(f, "P5\n%d %d\n255\n", stride, height);
for (y = 0; y < picture->height; ++y) {
@ -463,8 +474,9 @@ static int WriteWebPWithMetadata(FILE* const out,
} else {
const int is_lossless = !memcmp(webp, "VP8L", kTagSize);
if (is_lossless) {
// Presence of alpha is stored in the 29th bit of VP8L data.
if (webp[kChunkHeaderSize + 3] & (1 << 5)) flags |= kAlphaFlag;
// Presence of alpha is stored in the 37th bit (29th after the
// signature) of VP8L data.
if (webp[kChunkHeaderSize + 4] & (1 << 4)) flags |= kAlphaFlag;
}
ok = ok && (fwrite(kVP8XHeader, kChunkHeaderSize, 1, out) == 1);
ok = ok && WriteLE32(out, flags);
@ -486,10 +498,10 @@ static int WriteWebPWithMetadata(FILE* const out,
*metadata_written |= METADATA_XMP;
}
return ok;
} else {
// No metadata, just write the original image file.
return (fwrite(webp, webp_size, 1, out) == 1);
}
// No metadata, just write the original image file.
return (fwrite(webp, webp_size, 1, out) == 1);
}
//------------------------------------------------------------------------------
@ -515,6 +527,7 @@ static void HelpLong(void) {
printf(" cwebp [-preset <...>] [options] in_file [-o out_file]\n\n");
printf("If input size (-s) for an image is not specified, it is\n"
"assumed to be a PNG, JPEG, TIFF or WebP file.\n");
printf("Note: Animated PNG and WebP files are not supported.\n");
#ifdef HAVE_WINCODEC_H
printf("Windows builds can take as input any of the files handled by WIC.\n");
#endif
@ -555,8 +568,10 @@ static void HelpLong(void) {
printf(" "
"the first partition (0=no degradation ... 100=full)\n");
printf(" -pass <int> ............ analysis pass number (1..10)\n");
printf(" -qrange <min> <max> .... specifies the permissible quality range\n"
" (default: 0 100)\n");
printf(" -crop <x> <y> <w> <h> .. crop picture with the given rectangle\n");
printf(" -resize <w> <h> ........ resize picture (after any cropping)\n");
printf(" -resize <w> <h> ........ resize picture (*after* any cropping)\n");
printf(" -mt .................... use multi-threading if available\n");
printf(" -low_memory ............ reduce memory usage (slower encoding)\n");
printf(" -map <int> ............. print map of extra info\n");
@ -579,9 +594,6 @@ static void HelpLong(void) {
printf(" -near_lossless <int> ... use near-lossless image\n"
" preprocessing (0..100=off), "
"default=100\n");
#ifdef WEBP_EXPERIMENTAL_FEATURES /* not documented yet */
printf(" -delta_palette ......... use delta palettization\n");
#endif // WEBP_EXPERIMENTAL_FEATURES
printf(" -hint <string> ......... specify image characteristics hint,\n");
printf(" one of: photo, picture or graph\n");
@ -608,6 +620,7 @@ static void HelpLong(void) {
printf(" -af .................... auto-adjust filter strength\n");
printf(" -pre <int> ............. pre-processing filter\n");
printf("\n");
printf("Supported input formats:\n %s\n", WebPGetEnabledInputFileFormats());
}
//------------------------------------------------------------------------------
@ -634,10 +647,10 @@ static const char* const kErrorMessages[VP8_ENC_ERROR_LAST] = {
//------------------------------------------------------------------------------
int main(int argc, const char *argv[]) {
int main(int argc, const char* argv[]) {
int return_value = -1;
const char *in_file = NULL, *out_file = NULL, *dump_file = NULL;
FILE *out = NULL;
const char* in_file = NULL, *out_file = NULL, *dump_file = NULL;
FILE* out = NULL;
int c;
int short_output = 0;
int quiet = 0;
@ -657,35 +670,38 @@ int main(int argc, const char *argv[]) {
WebPConfig config;
WebPAuxStats stats;
WebPMemoryWriter memory_writer;
int use_memory_writer;
Metadata metadata;
Stopwatch stop_watch;
INIT_WARGV(argc, argv);
MetadataInit(&metadata);
WebPMemoryWriterInit(&memory_writer);
if (!WebPPictureInit(&picture) ||
!WebPPictureInit(&original_picture) ||
!WebPConfigInit(&config)) {
fprintf(stderr, "Error! Version mismatch!\n");
return -1;
FREE_WARGV_AND_RETURN(-1);
}
if (argc == 1) {
HelpShort();
return 0;
FREE_WARGV_AND_RETURN(0);
}
for (c = 1; c < argc; ++c) {
int parse_error = 0;
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
HelpShort();
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) {
HelpLong();
return 0;
} else if (!strcmp(argv[c], "-o") && c < argc - 1) {
out_file = argv[++c];
} else if (!strcmp(argv[c], "-d") && c < argc - 1) {
dump_file = argv[++c];
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-o") && c + 1 < argc) {
out_file = (const char*)GET_WARGV(argv, ++c);
} else if (!strcmp(argv[c], "-d") && c + 1 < argc) {
dump_file = (const char*)GET_WARGV(argv, ++c);
config.show_compressed = 1;
} else if (!strcmp(argv[c], "-print_psnr")) {
config.show_compressed = 1;
@ -698,7 +714,7 @@ int main(int argc, const char *argv[]) {
print_distortion = 2;
} else if (!strcmp(argv[c], "-short")) {
++short_output;
} else if (!strcmp(argv[c], "-s") && c < argc - 2) {
} else if (!strcmp(argv[c], "-s") && c + 2 < argc) {
picture.width = ExUtilGetInt(argv[++c], 0, &parse_error);
picture.height = ExUtilGetInt(argv[++c], 0, &parse_error);
if (picture.width > WEBP_MAX_DIMENSION || picture.width < 0 ||
@ -708,30 +724,30 @@ int main(int argc, const char *argv[]) {
picture.width, picture.height);
goto Error;
}
} else if (!strcmp(argv[c], "-m") && c < argc - 1) {
} else if (!strcmp(argv[c], "-m") && c + 1 < argc) {
config.method = ExUtilGetInt(argv[++c], 0, &parse_error);
use_lossless_preset = 0; // disable -z option
} else if (!strcmp(argv[c], "-q") && c < argc - 1) {
} else if (!strcmp(argv[c], "-q") && c + 1 < argc) {
config.quality = ExUtilGetFloat(argv[++c], &parse_error);
use_lossless_preset = 0; // disable -z option
} else if (!strcmp(argv[c], "-z") && c < argc - 1) {
} else if (!strcmp(argv[c], "-z") && c + 1 < argc) {
lossless_preset = ExUtilGetInt(argv[++c], 0, &parse_error);
if (use_lossless_preset != 0) use_lossless_preset = 1;
} else if (!strcmp(argv[c], "-alpha_q") && c < argc - 1) {
} else if (!strcmp(argv[c], "-alpha_q") && c + 1 < argc) {
config.alpha_quality = ExUtilGetInt(argv[++c], 0, &parse_error);
} else if (!strcmp(argv[c], "-alpha_method") && c < argc - 1) {
} else if (!strcmp(argv[c], "-alpha_method") && c + 1 < argc) {
config.alpha_compression = ExUtilGetInt(argv[++c], 0, &parse_error);
} else if (!strcmp(argv[c], "-alpha_cleanup")) {
// This flag is obsolete, does opposite of -exact.
config.exact = 0;
} else if (!strcmp(argv[c], "-exact")) {
config.exact = 1;
} else if (!strcmp(argv[c], "-blend_alpha") && c < argc - 1) {
} else if (!strcmp(argv[c], "-blend_alpha") && c + 1 < argc) {
blend_alpha = 1;
// background color is given in hex with an optional '0x' prefix
background_color = ExUtilGetInt(argv[++c], 16, &parse_error);
background_color = background_color & 0x00ffffffu;
} else if (!strcmp(argv[c], "-alpha_filter") && c < argc - 1) {
} else if (!strcmp(argv[c], "-alpha_filter") && c + 1 < argc) {
++c;
if (!strcmp(argv[c], "none")) {
config.alpha_filtering = 0;
@ -747,15 +763,10 @@ int main(int argc, const char *argv[]) {
keep_alpha = 0;
} else if (!strcmp(argv[c], "-lossless")) {
config.lossless = 1;
} else if (!strcmp(argv[c], "-near_lossless") && c < argc - 1) {
} else if (!strcmp(argv[c], "-near_lossless") && c + 1 < argc) {
config.near_lossless = ExUtilGetInt(argv[++c], 0, &parse_error);
config.lossless = 1; // use near-lossless only with lossless
#ifdef WEBP_EXPERIMENTAL_FEATURES
} else if (!strcmp(argv[c], "-delta_palette")) {
config.use_delta_palette = 1;
config.lossless = 1; // delta-palette is for lossless only
#endif // WEBP_EXPERIMENTAL_FEATURES
} else if (!strcmp(argv[c], "-hint") && c < argc - 1) {
} else if (!strcmp(argv[c], "-hint") && c + 1 < argc) {
++c;
if (!strcmp(argv[c], "photo")) {
config.image_hint = WEBP_HINT_PHOTO;
@ -767,13 +778,13 @@ int main(int argc, const char *argv[]) {
fprintf(stderr, "Error! Unrecognized image hint: %s\n", argv[c]);
goto Error;
}
} else if (!strcmp(argv[c], "-size") && c < argc - 1) {
} else if (!strcmp(argv[c], "-size") && c + 1 < argc) {
config.target_size = ExUtilGetInt(argv[++c], 0, &parse_error);
} else if (!strcmp(argv[c], "-psnr") && c < argc - 1) {
} else if (!strcmp(argv[c], "-psnr") && c + 1 < argc) {
config.target_PSNR = ExUtilGetFloat(argv[++c], &parse_error);
} else if (!strcmp(argv[c], "-sns") && c < argc - 1) {
} else if (!strcmp(argv[c], "-sns") && c + 1 < argc) {
config.sns_strength = ExUtilGetInt(argv[++c], 0, &parse_error);
} else if (!strcmp(argv[c], "-f") && c < argc - 1) {
} else if (!strcmp(argv[c], "-f") && c + 1 < argc) {
config.filter_strength = ExUtilGetInt(argv[++c], 0, &parse_error);
} else if (!strcmp(argv[c], "-af")) {
config.autofilter = 1;
@ -787,27 +798,32 @@ int main(int argc, const char *argv[]) {
config.filter_type = 1;
} else if (!strcmp(argv[c], "-nostrong")) {
config.filter_type = 0;
} else if (!strcmp(argv[c], "-sharpness") && c < argc - 1) {
} else if (!strcmp(argv[c], "-sharpness") && c + 1 < argc) {
config.filter_sharpness = ExUtilGetInt(argv[++c], 0, &parse_error);
} else if (!strcmp(argv[c], "-sharp_yuv")) {
config.use_sharp_yuv = 1;
} else if (!strcmp(argv[c], "-pass") && c < argc - 1) {
} else if (!strcmp(argv[c], "-pass") && c + 1 < argc) {
config.pass = ExUtilGetInt(argv[++c], 0, &parse_error);
} else if (!strcmp(argv[c], "-pre") && c < argc - 1) {
} else if (!strcmp(argv[c], "-qrange") && c + 2 < argc) {
config.qmin = ExUtilGetInt(argv[++c], 0, &parse_error);
config.qmax = ExUtilGetInt(argv[++c], 0, &parse_error);
if (config.qmin < 0) config.qmin = 0;
if (config.qmax > 100) config.qmax = 100;
} else if (!strcmp(argv[c], "-pre") && c + 1 < argc) {
config.preprocessing = ExUtilGetInt(argv[++c], 0, &parse_error);
} else if (!strcmp(argv[c], "-segments") && c < argc - 1) {
} else if (!strcmp(argv[c], "-segments") && c + 1 < argc) {
config.segments = ExUtilGetInt(argv[++c], 0, &parse_error);
} else if (!strcmp(argv[c], "-partition_limit") && c < argc - 1) {
} else if (!strcmp(argv[c], "-partition_limit") && c + 1 < argc) {
config.partition_limit = ExUtilGetInt(argv[++c], 0, &parse_error);
} else if (!strcmp(argv[c], "-map") && c < argc - 1) {
} else if (!strcmp(argv[c], "-map") && c + 1 < argc) {
picture.extra_info_type = ExUtilGetInt(argv[++c], 0, &parse_error);
} else if (!strcmp(argv[c], "-crop") && c < argc - 4) {
} else if (!strcmp(argv[c], "-crop") && c + 4 < argc) {
crop = 1;
crop_x = ExUtilGetInt(argv[++c], 0, &parse_error);
crop_y = ExUtilGetInt(argv[++c], 0, &parse_error);
crop_w = ExUtilGetInt(argv[++c], 0, &parse_error);
crop_h = ExUtilGetInt(argv[++c], 0, &parse_error);
} else if (!strcmp(argv[c], "-resize") && c < argc - 2) {
} else if (!strcmp(argv[c], "-resize") && c + 2 < argc) {
resize_w = ExUtilGetInt(argv[++c], 0, &parse_error);
resize_h = ExUtilGetInt(argv[++c], 0, &parse_error);
#ifndef WEBP_DLL
@ -818,12 +834,12 @@ int main(int argc, const char *argv[]) {
const int version = WebPGetEncoderVersion();
printf("%d.%d.%d\n",
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-progress")) {
show_progress = 1;
} else if (!strcmp(argv[c], "-quiet")) {
quiet = 1;
} else if (!strcmp(argv[c], "-preset") && c < argc - 1) {
} else if (!strcmp(argv[c], "-preset") && c + 1 < argc) {
WebPPreset preset;
++c;
if (!strcmp(argv[c], "default")) {
@ -846,7 +862,7 @@ int main(int argc, const char *argv[]) {
fprintf(stderr, "Error! Could initialize configuration with preset.\n");
goto Error;
}
} else if (!strcmp(argv[c], "-metadata") && c < argc - 1) {
} else if (!strcmp(argv[c], "-metadata") && c + 1 < argc) {
static const struct {
const char* option;
int flag;
@ -880,8 +896,7 @@ int main(int argc, const char *argv[]) {
if (i == kNumTokens) {
fprintf(stderr, "Error! Unknown metadata type '%.*s'\n",
(int)(token - start), start);
HelpLong();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
start = token + 1;
}
@ -895,19 +910,19 @@ int main(int argc, const char *argv[]) {
} else if (!strcmp(argv[c], "-v")) {
verbose = 1;
} else if (!strcmp(argv[c], "--")) {
if (c < argc - 1) in_file = argv[++c];
if (c + 1 < argc) in_file = (const char*)GET_WARGV(argv, ++c);
break;
} else if (argv[c][0] == '-') {
fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]);
HelpLong();
return -1;
FREE_WARGV_AND_RETURN(-1);
} else {
in_file = argv[c];
in_file = (const char*)GET_WARGV(argv, c);
}
if (parse_error) {
HelpLong();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
}
if (in_file == NULL) {
@ -957,7 +972,8 @@ int main(int argc, const char *argv[]) {
}
if (!ReadPicture(in_file, &picture, keep_alpha,
(keep_metadata == 0) ? NULL : &metadata)) {
fprintf(stderr, "Error! Cannot read input picture file '%s'\n", in_file);
WFPRINTF(stderr, "Error! Cannot read input picture file '%s'\n",
(const W_CHAR*)in_file);
goto Error;
}
picture.progress_hook = (show_progress && !quiet) ? ProgressReport : NULL;
@ -970,28 +986,41 @@ int main(int argc, const char *argv[]) {
const double read_time = StopwatchReadAndReset(&stop_watch);
fprintf(stderr, "Time to read input: %.3fs\n", read_time);
}
// The bitstream should be kept in memory when metadata must be appended
// before writing it to a file/stream, and/or when the near-losslessly encoded
// bitstream must be decoded for distortion computation (lossy will modify the
// 'picture' but not the lossless pipeline).
// Otherwise directly write the bitstream to a file.
use_memory_writer = (out_file != NULL && keep_metadata) ||
(!quiet && print_distortion >= 0 && config.lossless &&
config.near_lossless < 100);
// Open the output
if (out_file != NULL) {
const int use_stdout = !strcmp(out_file, "-");
out = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : fopen(out_file, "wb");
const int use_stdout = !WSTRCMP(out_file, "-");
out = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : WFOPEN(out_file, "wb");
if (out == NULL) {
fprintf(stderr, "Error! Cannot open output file '%s'\n", out_file);
WFPRINTF(stderr, "Error! Cannot open output file '%s'\n",
(const W_CHAR*)out_file);
goto Error;
} else {
if (!short_output && !quiet) {
fprintf(stderr, "Saving file '%s'\n", out_file);
WFPRINTF(stderr, "Saving file '%s'\n", (const W_CHAR*)out_file);
}
}
if (keep_metadata == 0) {
picture.writer = MyWriter;
picture.custom_ptr = (void*)out;
} else {
if (use_memory_writer) {
picture.writer = WebPMemoryWrite;
picture.custom_ptr = (void*)&memory_writer;
} else {
picture.writer = MyWriter;
picture.custom_ptr = (void*)out;
}
} else {
out = NULL;
if (use_memory_writer) {
picture.writer = WebPMemoryWrite;
picture.custom_ptr = (void*)&memory_writer;
}
if (!quiet && !short_output) {
fprintf(stderr, "No output file specified (no -o flag). Encoding will\n");
fprintf(stderr, "be performed, but its results discarded.\n\n");
@ -1014,10 +1043,53 @@ int main(int argc, const char *argv[]) {
}
}
if ((resize_w | resize_h) > 0) {
WebPPicture picture_no_alpha;
if (config.exact) {
// If -exact, we can't premultiply RGB by A otherwise RGB is lost if A=0.
// We rescale an opaque copy and assemble scaled A and non-premultiplied
// RGB channels. This is slower but it's a very uncommon use case. Color
// leak at sharp alpha edges is possible.
if (!WebPPictureCopy(&picture, &picture_no_alpha)) {
fprintf(stderr, "Error! Cannot copy temporary picture\n");
goto Error;
}
// We enforced picture.use_argb = 1 above. Now, remove the alpha values.
{
int x, y;
uint32_t* argb_no_alpha = picture_no_alpha.argb;
for (y = 0; y < picture_no_alpha.height; ++y) {
for (x = 0; x < picture_no_alpha.width; ++x) {
argb_no_alpha[x] |= 0xff000000; // Opaque copy.
}
argb_no_alpha += picture_no_alpha.argb_stride;
}
}
if (!WebPPictureRescale(&picture_no_alpha, resize_w, resize_h)) {
fprintf(stderr, "Error! Cannot resize temporary picture\n");
goto Error;
}
}
if (!WebPPictureRescale(&picture, resize_w, resize_h)) {
fprintf(stderr, "Error! Cannot resize picture\n");
goto Error;
}
if (config.exact) { // Put back the alpha information.
int x, y;
uint32_t* argb_no_alpha = picture_no_alpha.argb;
uint32_t* argb = picture.argb;
for (y = 0; y < picture_no_alpha.height; ++y) {
for (x = 0; x < picture_no_alpha.width; ++x) {
argb[x] = (argb[x] & 0xff000000) | (argb_no_alpha[x] & 0x00ffffff);
}
argb_no_alpha += picture_no_alpha.argb_stride;
argb += picture.argb_stride;
}
WebPPictureFree(&picture_no_alpha);
}
}
if (verbose && (crop != 0 || (resize_w | resize_h) > 0)) {
const double preproc_time = StopwatchReadAndReset(&stop_watch);
@ -1027,8 +1099,12 @@ int main(int argc, const char *argv[]) {
if (picture.extra_info_type > 0) {
AllocExtraInfo(&picture);
}
if (print_distortion >= 0) { // Save original picture for later comparison
WebPPictureCopy(&picture, &original_picture);
// Save original picture for later comparison. Only for lossy as lossless does
// not modify 'picture' (even near-lossless).
if (print_distortion >= 0 && !config.lossless &&
!WebPPictureCopy(&picture, &original_picture)) {
fprintf(stderr, "Error! Cannot copy temporary picture\n");
goto Error;
}
// Compress.
@ -1046,40 +1122,71 @@ int main(int argc, const char *argv[]) {
fprintf(stderr, "Time to encode picture: %.3fs\n", encode_time);
}
// Write info
// Get the decompressed image for the lossless pipeline.
if (!quiet && print_distortion >= 0 && config.lossless) {
if (config.near_lossless == 100) {
// Pure lossless: image was not modified, make 'original_picture' a view
// of 'picture' by copying all members except the freeable pointers.
original_picture = picture;
original_picture.memory_ = original_picture.memory_argb_ = NULL;
} else {
// Decode the bitstream stored in 'memory_writer' to get the altered image
// to 'picture'; save the 'original_picture' beforehand.
assert(use_memory_writer);
original_picture = picture;
if (!WebPPictureInit(&picture)) { // Do not free 'picture'.
fprintf(stderr, "Error! Version mismatch!\n");
goto Error;
}
picture.use_argb = 1;
if (!ReadWebP(memory_writer.mem, memory_writer.size, &picture,
/*keep_alpha=*/WebPPictureHasTransparency(&picture),
/*metadata=*/NULL)) {
fprintf(stderr, "Error! Cannot decode encoded WebP bitstream\n");
fprintf(stderr, "Error code: %d (%s)\n", picture.error_code,
kErrorMessages[picture.error_code]);
goto Error;
}
picture.stats = original_picture.stats;
}
original_picture.stats = NULL;
}
// Write the YUV planes to a PGM file. Only available for lossy.
if (dump_file) {
if (picture.use_argb) {
fprintf(stderr, "Warning: can't dump file (-d option) in lossless mode.");
fprintf(stderr, "Warning: can't dump file (-d option) "
"in lossless mode.\n");
} else if (!DumpPicture(&picture, dump_file)) {
fprintf(stderr, "Warning, couldn't dump picture %s\n", dump_file);
WFPRINTF(stderr, "Warning, couldn't dump picture %s\n",
(const W_CHAR*)dump_file);
}
}
if (keep_metadata != 0) {
if (out != NULL) {
if (!WriteWebPWithMetadata(out, &picture, &memory_writer,
&metadata, keep_metadata, &metadata_written)) {
fprintf(stderr, "Error writing WebP file with metadata!\n");
goto Error;
}
} else { // output is disabled, just display the metadata stats.
const struct {
const MetadataPayload* const payload;
int flag;
} *iter, info[] = {
{ &metadata.exif, METADATA_EXIF },
{ &metadata.iccp, METADATA_ICC },
{ &metadata.xmp, METADATA_XMP },
{ NULL, 0 }
};
uint32_t unused1 = 0;
uint64_t unused2 = 0;
if (use_memory_writer && out != NULL &&
!WriteWebPWithMetadata(out, &picture, &memory_writer, &metadata,
keep_metadata, &metadata_written)) {
fprintf(stderr, "Error writing WebP file!\n");
goto Error;
}
for (iter = info; iter->payload != NULL; ++iter) {
if (UpdateFlagsAndSize(iter->payload, !!(keep_metadata & iter->flag),
0, &unused1, &unused2)) {
metadata_written |= iter->flag;
}
if (out == NULL && keep_metadata) {
// output is disabled, just display the metadata stats.
const struct {
const MetadataPayload* const payload;
int flag;
} *iter, info[] = {{&metadata.exif, METADATA_EXIF},
{&metadata.iccp, METADATA_ICC},
{&metadata.xmp, METADATA_XMP},
{NULL, 0}};
uint32_t unused1 = 0;
uint64_t unused2 = 0;
for (iter = info; iter->payload != NULL; ++iter) {
if (UpdateFlagsAndSize(iter->payload, !!(keep_metadata & iter->flag),
/*flag=*/0, &unused1, &unused2)) {
metadata_written |= iter->flag;
}
}
}
@ -1119,7 +1226,7 @@ int main(int argc, const char *argv[]) {
Error:
WebPMemoryWriterClear(&memory_writer);
free(picture.extra_info);
WebPFree(picture.extra_info);
MetadataFree(&metadata);
WebPPictureFree(&picture);
WebPPictureFree(&original_picture);
@ -1127,7 +1234,7 @@ int main(int argc, const char *argv[]) {
fclose(out);
}
return return_value;
FREE_WARGV_AND_RETURN(return_value);
}
//------------------------------------------------------------------------------

View File

@ -24,6 +24,7 @@
#include "../imageio/image_enc.h"
#include "../imageio/webpdec.h"
#include "./stopwatch.h"
#include "./unicode.h"
static int verbose = 0;
static int quiet = 0;
@ -42,7 +43,7 @@ extern void* VP8GetCPUInfo; // opaque forward declaration.
static int SaveOutput(const WebPDecBuffer* const buffer,
WebPOutputFileFormat format, const char* const out_file) {
const int use_stdout = (out_file != NULL) && !strcmp(out_file, "-");
const int use_stdout = (out_file != NULL) && !WSTRCMP(out_file, "-");
int ok = 1;
Stopwatch stop_watch;
@ -56,7 +57,7 @@ static int SaveOutput(const WebPDecBuffer* const buffer,
if (use_stdout) {
fprintf(stderr, "Saved to stdout\n");
} else {
fprintf(stderr, "Saved file %s\n", out_file);
WFPRINTF(stderr, "Saved file %s\n", (const W_CHAR*)out_file);
}
}
if (verbose) {
@ -67,7 +68,7 @@ static int SaveOutput(const WebPDecBuffer* const buffer,
if (use_stdout) {
fprintf(stderr, "Error writing to stdout !!\n");
} else {
fprintf(stderr, "Error writing file %s !!\n", out_file);
WFPRINTF(stderr, "Error writing file %s !!\n", (const W_CHAR*)out_file);
}
}
return ok;
@ -75,7 +76,8 @@ static int SaveOutput(const WebPDecBuffer* const buffer,
static void Help(void) {
printf("Usage: dwebp in_file [options] [-o out_file]\n\n"
"Decodes the WebP image file to PNG format [Default]\n"
"Decodes the WebP image file to PNG format [Default].\n"
"Note: Animated WebP files are not supported.\n\n"
"Use following options to convert into alternate image formats:\n"
" -pam ......... save the raw RGBA samples as a color PAM\n"
" -ppm ......... save the raw RGB samples as a color PPM\n"
@ -94,7 +96,7 @@ static void Help(void) {
" -alpha_dither use alpha-plane dithering if needed\n"
" -mt .......... use multi-threading\n"
" -crop <x> <y> <w> <h> ... crop output with the given rectangle\n"
" -resize <w> <h> ......... scale the output (*after* any cropping)\n"
" -resize <w> <h> ......... resize output (*after* any cropping)\n"
" -flip ........ flip the output vertically\n"
" -alpha ....... only save the alpha plane\n"
" -incremental . use incremental decoding (useful for tests)\n"
@ -131,7 +133,7 @@ static uint8_t* AllocateExternalBuffer(WebPDecoderConfig* config,
format == RGB_565) ? 2
: 4;
uint32_t stride = bpp * w + 7; // <- just for exercising
external_buffer = (uint8_t*)malloc(stride * h);
external_buffer = (uint8_t*)WebPMalloc(stride * h);
if (external_buffer == NULL) return NULL;
output_buffer->u.RGBA.stride = stride;
output_buffer->u.RGBA.size = stride * h;
@ -144,7 +146,7 @@ static uint8_t* AllocateExternalBuffer(WebPDecoderConfig* config,
uint32_t total_size = stride * h * (has_alpha ? 2 : 1)
+ 2 * uv_stride * (h + 1) / 2;
assert(format >= YUV && format <= YUVA);
external_buffer = (uint8_t*)malloc(total_size);
external_buffer = (uint8_t*)WebPMalloc(total_size);
if (external_buffer == NULL) return NULL;
tmp = external_buffer;
output_buffer->u.YUVA.y = tmp;
@ -175,10 +177,10 @@ static uint8_t* AllocateExternalBuffer(WebPDecoderConfig* config,
return external_buffer;
}
int main(int argc, const char *argv[]) {
int main(int argc, const char* argv[]) {
int ok = 0;
const char *in_file = NULL;
const char *out_file = NULL;
const char* in_file = NULL;
const char* out_file = NULL;
WebPDecoderConfig config;
WebPDecBuffer* const output_buffer = &config.output;
@ -191,18 +193,20 @@ int main(int argc, const char *argv[]) {
int incremental = 0;
int c;
INIT_WARGV(argc, argv);
if (!WebPInitDecoderConfig(&config)) {
fprintf(stderr, "Library version mismatch!\n");
return -1;
FREE_WARGV_AND_RETURN(-1);
}
for (c = 1; c < argc; ++c) {
int parse_error = 0;
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
Help();
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-o") && c < argc - 1) {
out_file = argv[++c];
out_file = (const char*)GET_WARGV(argv, ++c);
} else if (!strcmp(argv[c], "-alpha")) {
format = ALPHA_PLANE_ONLY;
} else if (!strcmp(argv[c], "-nofancy")) {
@ -223,7 +227,7 @@ int main(int argc, const char *argv[]) {
const int version = WebPGetDecoderVersion();
printf("%d.%d.%d\n",
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-pgm")) {
format = PGM;
} else if (!strcmp(argv[c], "-yuv")) {
@ -284,26 +288,26 @@ int main(int argc, const char *argv[]) {
} else if (!strcmp(argv[c], "-incremental")) {
incremental = 1;
} else if (!strcmp(argv[c], "--")) {
if (c < argc - 1) in_file = argv[++c];
if (c < argc - 1) in_file = (const char*)GET_WARGV(argv, ++c);
break;
} else if (argv[c][0] == '-') {
fprintf(stderr, "Unknown option '%s'\n", argv[c]);
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
} else {
in_file = argv[c];
in_file = (const char*)GET_WARGV(argv, c);
}
if (parse_error) {
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
}
if (in_file == NULL) {
fprintf(stderr, "missing input file!!\n");
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
if (quiet) verbose = 0;
@ -312,7 +316,7 @@ int main(int argc, const char *argv[]) {
VP8StatusCode status = VP8_STATUS_OK;
size_t data_size = 0;
if (!LoadWebP(in_file, &data, &data_size, bitstream)) {
return -1;
FREE_WARGV_AND_RETURN(-1);
}
switch (format) {
@ -332,9 +336,8 @@ int main(int argc, const char *argv[]) {
case BMP:
output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR;
break;
case TIFF: // note: force pre-multiplied alpha
output_buffer->colorspace =
bitstream->has_alpha ? MODE_rgbA : MODE_RGB;
case TIFF:
output_buffer->colorspace = bitstream->has_alpha ? MODE_RGBA : MODE_RGB;
break;
case PGM:
case RAW_YUV:
@ -390,18 +393,18 @@ int main(int argc, const char *argv[]) {
if (out_file != NULL) {
if (!quiet) {
fprintf(stderr, "Decoded %s. Dimensions: %d x %d %s. Format: %s. "
"Now saving...\n",
in_file, output_buffer->width, output_buffer->height,
WFPRINTF(stderr, "Decoded %s.", (const W_CHAR*)in_file);
fprintf(stderr, " Dimensions: %d x %d %s. Format: %s. Now saving...\n",
output_buffer->width, output_buffer->height,
bitstream->has_alpha ? " (with alpha)" : "",
kFormatType[bitstream->format]);
}
ok = SaveOutput(output_buffer, format, out_file);
} else {
if (!quiet) {
fprintf(stderr, "File %s can be decoded "
"(dimensions: %d x %d %s. Format: %s).\n",
in_file, output_buffer->width, output_buffer->height,
WFPRINTF(stderr, "File %s can be decoded ", (const W_CHAR*)in_file);
fprintf(stderr, "(dimensions: %d x %d %s. Format: %s).\n",
output_buffer->width, output_buffer->height,
bitstream->has_alpha ? " (with alpha)" : "",
kFormatType[bitstream->format]);
fprintf(stderr, "Nothing written; "
@ -410,9 +413,9 @@ int main(int argc, const char *argv[]) {
}
Exit:
WebPFreeDecBuffer(output_buffer);
free((void*)external_buffer);
free((void*)data);
return ok ? 0 : -1;
WebPFree((void*)external_buffer);
WebPFree((void*)data);
FREE_WARGV_AND_RETURN(ok ? 0 : -1);
}
//------------------------------------------------------------------------------

View File

@ -12,10 +12,14 @@
#include "./example_util.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "webp/mux_types.h"
#include "../imageio/imageio_util.h"
//------------------------------------------------------------------------------
// String parsing
@ -56,3 +60,80 @@ float ExUtilGetFloat(const char* const v, int* const error) {
}
return f;
}
//------------------------------------------------------------------------------
static void ResetCommandLineArguments(int argc, const char* argv[],
CommandLineArguments* const args) {
assert(args != NULL);
args->argc_ = argc;
args->argv_ = argv;
args->own_argv_ = 0;
WebPDataInit(&args->argv_data_);
}
void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args) {
if (args != NULL) {
if (args->own_argv_) {
WebPFree((void*)args->argv_);
WebPDataClear(&args->argv_data_);
}
ResetCommandLineArguments(0, NULL, args);
}
}
#define MAX_ARGC 16384
int ExUtilInitCommandLineArguments(int argc, const char* argv[],
CommandLineArguments* const args) {
if (args == NULL || argv == NULL) return 0;
ResetCommandLineArguments(argc, argv, args);
if (argc == 1 && argv[0][0] != '-') {
char* cur;
const char sep[] = " \t\r\n\f\v";
#if defined(_WIN32) && defined(_UNICODE)
fprintf(stderr,
"Error: Reading arguments from a file is a feature unavailable "
"with Unicode binaries.\n");
return 0;
#endif
if (!ExUtilReadFileToWebPData(argv[0], &args->argv_data_)) {
return 0;
}
args->own_argv_ = 1;
args->argv_ = (const char**)WebPMalloc(MAX_ARGC * sizeof(*args->argv_));
if (args->argv_ == NULL) {
ExUtilDeleteCommandLineArguments(args);
return 0;
}
argc = 0;
for (cur = strtok((char*)args->argv_data_.bytes, sep);
cur != NULL;
cur = strtok(NULL, sep)) {
if (argc == MAX_ARGC) {
fprintf(stderr, "ERROR: Arguments limit %d reached\n", MAX_ARGC);
ExUtilDeleteCommandLineArguments(args);
return 0;
}
assert(strlen(cur) != 0);
args->argv_[argc++] = cur;
}
args->argc_ = argc;
}
return 1;
}
//------------------------------------------------------------------------------
int ExUtilReadFileToWebPData(const char* const filename,
WebPData* const webp_data) {
const uint8_t* data;
size_t size;
if (webp_data == NULL) return 0;
if (!ImgIoUtilReadFile(filename, &data, &size)) return 0;
webp_data->bytes = data;
webp_data->size = size;
return 1;
}

View File

@ -14,6 +14,7 @@
#define WEBP_EXAMPLES_EXAMPLE_UTIL_H_
#include "webp/types.h"
#include "webp/mux_types.h"
#ifdef __cplusplus
extern "C" {
@ -35,6 +36,33 @@ float ExUtilGetFloat(const char* const v, int* const error);
// actually parsed is returned, or -1 if an error occurred.
int ExUtilGetInts(const char* v, int base, int max_output, int output[]);
// Reads a file named 'filename' into a WebPData structure. The content of
// webp_data is overwritten. Returns false in case of error.
int ExUtilReadFileToWebPData(const char* const filename,
WebPData* const webp_data);
//------------------------------------------------------------------------------
// Command-line arguments
typedef struct {
int argc_;
const char** argv_;
WebPData argv_data_;
int own_argv_;
} CommandLineArguments;
// Initializes the structure from the command-line parameters. If there is
// only one parameter and it does not start with a '-', then it is assumed to
// be a file name. This file will be read and tokenized into command-line
// arguments. The content of 'args' is overwritten.
// Returns false in case of error (memory allocation failure, non
// existing file, too many arguments, ...).
int ExUtilInitCommandLineArguments(int argc, const char* argv[],
CommandLineArguments* const args);
// Deallocate all memory and reset 'args'.
void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@ -23,12 +23,22 @@
#ifdef WEBP_HAVE_GIF
#if defined(HAVE_UNISTD_H) && HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <gif_lib.h>
#include "webp/encode.h"
#include "webp/mux.h"
#include "../examples/example_util.h"
#include "../imageio/imageio_util.h"
#include "./gifdec.h"
#include "./unicode.h"
#include "./unicode_gif.h"
#if !defined(STDIN_FILENO)
#define STDIN_FILENO 0
#endif
//------------------------------------------------------------------------------
@ -72,8 +82,10 @@ static void Help(void) {
printf(" -metadata <string> ..... comma separated list of metadata to\n");
printf(" ");
printf("copy from the input to the output if present\n");
printf(" "
"Valid values: all, none, icc, xmp (default)\n");
printf(" ");
printf("Valid values: all, none, icc, xmp (default)\n");
printf(" -loop_compatibility .... use compatibility mode for Chrome\n");
printf(" version prior to M62 (inclusive)\n");
printf(" -mt .................... use multi-threading if available\n");
printf("\n");
printf(" -version ............... print version number and exit\n");
@ -84,13 +96,12 @@ static void Help(void) {
//------------------------------------------------------------------------------
int main(int argc, const char *argv[]) {
int main(int argc, const char* argv[]) {
int verbose = 0;
int gif_error = GIF_ERROR;
WebPMuxError err = WEBP_MUX_OK;
int ok = 0;
const char *in_file = NULL, *out_file = NULL;
FILE* out = NULL;
const W_CHAR* in_file = NULL, *out_file = NULL;
GifFileType* gif = NULL;
int frame_duration = 0;
int frame_timestamp = 0;
@ -104,7 +115,7 @@ int main(int argc, const char *argv[]) {
WebPAnimEncoderOptions enc_options;
WebPConfig config;
int is_first_frame = 1; // Whether we are processing the first frame.
int frame_number = 0; // Whether we are processing the first frame.
int done;
int c;
int quiet = 0;
@ -115,18 +126,21 @@ int main(int argc, const char *argv[]) {
int stored_icc = 0; // Whether we have already stored an ICC profile.
WebPData xmp_data;
int stored_xmp = 0; // Whether we have already stored an XMP profile.
int loop_count = 0;
int loop_count = 0; // default: infinite
int stored_loop_count = 0; // Whether we have found an explicit loop count.
int loop_compatibility = 0;
WebPMux* mux = NULL;
int default_kmin = 1; // Whether to use default kmin value.
int default_kmax = 1;
INIT_WARGV(argc, argv);
if (!WebPConfigInit(&config) || !WebPAnimEncoderOptionsInit(&enc_options) ||
!WebPPictureInit(&frame) || !WebPPictureInit(&curr_canvas) ||
!WebPPictureInit(&prev_canvas)) {
fprintf(stderr, "Error! Version mismatch!\n");
return -1;
FREE_WARGV_AND_RETURN(-1);
}
config.lossless = 1; // Use lossless compression by default.
@ -136,21 +150,23 @@ int main(int argc, const char *argv[]) {
if (argc == 1) {
Help();
return 0;
FREE_WARGV_AND_RETURN(0);
}
for (c = 1; c < argc; ++c) {
int parse_error = 0;
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
Help();
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-o") && c < argc - 1) {
out_file = argv[++c];
out_file = GET_WARGV(argv, ++c);
} else if (!strcmp(argv[c], "-lossy")) {
config.lossless = 0;
} else if (!strcmp(argv[c], "-mixed")) {
enc_options.allow_mixed = 1;
config.lossless = 0;
} else if (!strcmp(argv[c], "-loop_compatibility")) {
loop_compatibility = 1;
} else if (!strcmp(argv[c], "-q") && c < argc - 1) {
config.quality = ExUtilGetFloat(argv[++c], &parse_error);
} else if (!strcmp(argv[c], "-m") && c < argc - 1) {
@ -200,7 +216,7 @@ int main(int argc, const char *argv[]) {
fprintf(stderr, "Error! Unknown metadata type '%.*s'\n",
(int)(token - start), start);
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
start = token + 1;
}
@ -213,7 +229,7 @@ int main(int argc, const char *argv[]) {
(enc_version >> 16) & 0xff, (enc_version >> 8) & 0xff,
enc_version & 0xff, (mux_version >> 16) & 0xff,
(mux_version >> 8) & 0xff, mux_version & 0xff);
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-quiet")) {
quiet = 1;
enc_options.verbose = 0;
@ -221,19 +237,19 @@ int main(int argc, const char *argv[]) {
verbose = 1;
enc_options.verbose = 1;
} else if (!strcmp(argv[c], "--")) {
if (c < argc - 1) in_file = argv[++c];
if (c < argc - 1) in_file = GET_WARGV(argv, ++c);
break;
} else if (argv[c][0] == '-') {
fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]);
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
} else {
in_file = argv[c];
in_file = GET_WARGV(argv, c);
}
if (parse_error) {
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
}
@ -257,11 +273,7 @@ int main(int argc, const char *argv[]) {
}
// Start the decoder object
#if LOCAL_GIF_PREREQ(5,0)
gif = DGifOpenFileName(in_file, &gif_error);
#else
gif = DGifOpenFileName(in_file);
#endif
gif = DGifOpenFileUnicode(in_file, &gif_error);
if (gif == NULL) goto End;
// Loop over GIF images
@ -277,7 +289,7 @@ int main(int argc, const char *argv[]) {
if (!DGifGetImageDesc(gif)) goto End;
if (is_first_frame) {
if (frame_number == 0) {
if (verbose) {
printf("Canvas screen: %d x %d\n", gif->SWidth, gif->SHeight);
}
@ -302,8 +314,11 @@ int main(int argc, const char *argv[]) {
frame.use_argb = 1;
if (!WebPPictureAlloc(&frame)) goto End;
GIFClearPic(&frame, NULL);
WebPPictureCopy(&frame, &curr_canvas);
WebPPictureCopy(&frame, &prev_canvas);
if (!(WebPPictureCopy(&frame, &curr_canvas) &&
WebPPictureCopy(&frame, &prev_canvas))) {
fprintf(stderr, "Error allocating canvas.\n");
goto End;
}
// Background color.
GIFGetBackgroundColor(gif->SColorMap, gif->SBackGroundColor,
@ -319,7 +334,6 @@ int main(int argc, const char *argv[]) {
"a memory error.\n");
goto End;
}
is_first_frame = 0;
}
// Some even more broken GIF can have sub-rect with zero width/height.
@ -336,13 +350,25 @@ int main(int argc, const char *argv[]) {
GIFBlendFrames(&frame, &gif_rect, &curr_canvas);
if (!WebPAnimEncoderAdd(enc, &curr_canvas, frame_timestamp, &config)) {
fprintf(stderr, "%s\n", WebPAnimEncoderGetError(enc));
fprintf(stderr, "Error while adding frame #%d: %s\n", frame_number,
WebPAnimEncoderGetError(enc));
goto End;
} else {
++frame_number;
}
// Update canvases.
GIFDisposeFrame(orig_dispose, &gif_rect, &prev_canvas, &curr_canvas);
GIFCopyPixels(&curr_canvas, &prev_canvas);
// Force frames with a small or no duration to 100ms to be consistent
// with web browsers and other transcoding tools. This also avoids
// incorrect durations between frames when padding frames are
// discarded.
if (frame_duration <= 10) {
frame_duration = 100;
}
// Update timestamp (for next frame).
frame_timestamp += frame_duration;
@ -356,7 +382,7 @@ int main(int argc, const char *argv[]) {
}
case EXTENSION_RECORD_TYPE: {
int extension;
GifByteType *data = NULL;
GifByteType* data = NULL;
if (DGifGetExtension(gif, &extension, &data) == GIF_ERROR) {
goto End;
}
@ -386,7 +412,7 @@ int main(int argc, const char *argv[]) {
if (verbose) {
fprintf(stderr, "Loop count: %d\n", loop_count);
}
stored_loop_count = (loop_count != 0);
stored_loop_count = loop_compatibility ? (loop_count != 0) : 1;
} else { // An extension containing metadata.
// We only store the first encountered chunk of each type, and
// only if requested by the user.
@ -442,6 +468,25 @@ int main(int argc, const char *argv[]) {
fprintf(stderr, "%s\n", WebPAnimEncoderGetError(enc));
goto End;
}
// If there's only one frame, we don't need to handle loop count.
if (frame_number == 1) {
loop_count = 0;
} else if (!loop_compatibility) {
if (!stored_loop_count) {
// if no loop-count element is seen, the default is '1' (loop-once)
// and we need to signal it explicitly in WebP. Note however that
// in case there's a single frame, we still don't need to store it.
if (frame_number > 1) {
stored_loop_count = 1;
loop_count = 1;
}
} else if (loop_count > 0 && loop_count < 65535) {
// adapt GIF's semantic to WebP's (except in the infinite-loop case)
loop_count += 1;
}
}
// loop_count of 0 is the default (infinite), so no need to signal it
if (loop_count == 0) stored_loop_count = 0;
if (stored_loop_count || stored_icc || stored_xmp) {
// Re-mux to add loop count and/or metadata as needed.
@ -502,13 +547,19 @@ int main(int argc, const char *argv[]) {
}
if (out_file != NULL) {
if (!ImgIoUtilWriteFile(out_file, webp_data.bytes, webp_data.size)) {
fprintf(stderr, "Error writing output file: %s\n", out_file);
if (!ImgIoUtilWriteFile((const char*)out_file, webp_data.bytes,
webp_data.size)) {
WFPRINTF(stderr, "Error writing output file: %s\n", out_file);
goto End;
}
if (!quiet) {
fprintf(stderr, "Saved output file (%d bytes): %s\n",
(int)webp_data.size, out_file);
if (!WSTRCMP(out_file, "-")) {
fprintf(stderr, "Saved %d bytes to STDIO\n",
(int)webp_data.size);
} else {
WFPRINTF(stderr, "Saved output file (%d bytes): %s\n",
(int)webp_data.size, out_file);
}
}
} else {
if (!quiet) {
@ -530,7 +581,6 @@ int main(int argc, const char *argv[]) {
WebPPictureFree(&curr_canvas);
WebPPictureFree(&prev_canvas);
WebPAnimEncoderDelete(enc);
if (out != NULL && out_file != NULL) fclose(out);
if (gif_error != GIF_OK) {
GIFDisplayError(gif, gif_error);
@ -543,12 +593,12 @@ int main(int argc, const char *argv[]) {
#endif
}
return !ok;
FREE_WARGV_AND_RETURN(!ok);
}
#else // !WEBP_HAVE_GIF
int main(int argc, const char *argv[]) {
int main(int argc, const char* argv[]) {
fprintf(stderr, "GIF support not enabled in %s.\n", argv[0]);
(void)argc;
return 0;

View File

@ -28,11 +28,17 @@
#define GIF_DISPOSE_SHIFT 2
// from utils/utils.h
#ifdef __cplusplus
extern "C" {
#endif
extern void WebPCopyPlane(const uint8_t* src, int src_stride,
uint8_t* dst, int dst_stride,
int width, int height);
extern void WebPCopyPixels(const WebPPicture* const src,
WebPPicture* const dst);
#ifdef __cplusplus
}
#endif
void GIFGetBackgroundColor(const ColorMapObject* const color_map,
int bgcolor_index, int transparent_index,
@ -131,7 +137,7 @@ int GIFReadFrame(GifFileType* const gif, int transparent_index,
}
dst = sub_image.argb;
tmp = (uint8_t*)malloc(rect.width * sizeof(*tmp));
tmp = (uint8_t*)WebPMalloc(rect.width * sizeof(*tmp));
if (tmp == NULL) goto End;
if (image_desc->Interlace) { // Interlaced image.
@ -162,7 +168,7 @@ int GIFReadFrame(GifFileType* const gif, int transparent_index,
End:
if (!ok) picture->error_code = sub_image.error_code;
WebPPictureFree(&sub_image);
free(tmp);
WebPFree(tmp);
return ok;
}

View File

@ -27,6 +27,7 @@
#include "../imageio/image_dec.h"
#include "../imageio/imageio_util.h"
#include "./stopwatch.h"
#include "./unicode.h"
#include "webp/encode.h"
#include "webp/mux.h"
@ -34,8 +35,7 @@
static void Help(void) {
printf("Usage:\n\n");
printf(" img2webp [file-level options] [image files...] "
"[per-frame options...]\n");
printf(" img2webp [file_options] [[frame_options] frame_file]...\n");
printf("\n");
printf("File-level options (only used at the start of compression):\n");
@ -48,6 +48,7 @@ static void Help(void) {
printf(" -mixed ............... use mixed lossy/lossless automatic mode\n");
printf(" -v ................... verbose mode\n");
printf(" -h ................... this help\n");
printf(" -version ............. print version number and exit\n");
printf("\n");
printf("Per-frame options (only used for subsequent images input):\n");
@ -60,6 +61,12 @@ static void Help(void) {
printf("\n");
printf("example: img2webp -loop 2 in0.png -lossy in1.jpg\n"
" -d 80 in2.tiff -o out.webp\n");
printf("\nNote: if a single file name is passed as the argument, the "
"arguments will be\n");
printf("tokenized from this file. The file name must not start with "
"the character '-'.\n");
printf("\nSupported input formats:\n %s\n",
WebPGetEnabledInputFileFormats());
}
//------------------------------------------------------------------------------
@ -78,7 +85,7 @@ static int ReadImage(const char filename[], WebPPicture* const pic) {
if (!ImgIoUtilReadFile(filename, &data, &data_size)) return 0;
reader = WebPGuessImageReader(data, data_size);
ok = reader(data, data_size, pic, 1, NULL);
free((void*)data);
WebPFree((void*)data);
return ok;
}
@ -117,14 +124,13 @@ static int SetLoopCount(int loop_count, WebPData* const webp_data) {
//------------------------------------------------------------------------------
int main(int argc, char* argv[]) {
int main(int argc, const char* argv[]) {
const char* output = NULL;
WebPAnimEncoder* enc = NULL;
int verbose = 0;
int pic_num = 0;
int duration = 100;
int timestamp_ms = 0;
int ok = 1;
int loop_count = 0;
int width = 0, height = 0;
WebPAnimEncoderOptions anim_config;
@ -133,22 +139,33 @@ int main(int argc, char* argv[]) {
WebPData webp_data;
int c;
int have_input = 0;
CommandLineArguments cmd_args;
int ok;
INIT_WARGV(argc, argv);
ok = ExUtilInitCommandLineArguments(argc - 1, argv + 1, &cmd_args);
if (!ok) FREE_WARGV_AND_RETURN(1);
argc = cmd_args.argc_;
argv = cmd_args.argv_;
WebPDataInit(&webp_data);
if (!WebPAnimEncoderOptionsInit(&anim_config) ||
!WebPConfigInit(&config) ||
!WebPPictureInit(&pic)) {
fprintf(stderr, "Library version mismatch!\n");
return 1;
ok = 0;
goto End;
}
// 1st pass of option parsing
for (c = 1; ok && c < argc; ++c) {
for (c = 0; ok && c < argc; ++c) {
if (argv[c][0] == '-') {
int parse_error = 0;
if (!strcmp(argv[c], "-o") && c + 1 < argc) {
argv[c] = NULL;
output = argv[++c];
output = (const char*)GET_WARGV_SHIFTED(argv, ++c);
} else if (!strcmp(argv[c], "-kmin") && c + 1 < argc) {
argv[c] = NULL;
anim_config.kmin = ExUtilGetInt(argv[++c], 0, &parse_error);
@ -171,7 +188,15 @@ int main(int argc, char* argv[]) {
verbose = 1;
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
Help();
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-version")) {
const int enc_version = WebPGetEncoderVersion();
const int mux_version = WebPGetMuxVersion();
printf("WebP Encoder version: %d.%d.%d\nWebP Mux version: %d.%d.%d\n",
(enc_version >> 16) & 0xff, (enc_version >> 8) & 0xff,
enc_version & 0xff, (mux_version >> 16) & 0xff,
(mux_version >> 8) & 0xff, mux_version & 0xff);
goto End;
} else {
continue;
}
@ -184,13 +209,13 @@ int main(int argc, char* argv[]) {
}
if (!have_input) {
fprintf(stderr, "No input file(s) for generating animation!\n");
return 0;
goto End;
}
// image-reading pass
pic_num = 0;
config.lossless = 1;
for (c = 1; ok && c < argc; ++c) {
for (c = 0; ok && c < argc; ++c) {
if (argv[c] == NULL) continue;
if (argv[c][0] == '-') { // parse local options
int parse_error = 0;
@ -227,7 +252,7 @@ int main(int argc, char* argv[]) {
// read next input image
pic.use_argb = 1;
ok = ReadImage(argv[c], &pic);
ok = ReadImage((const char*)GET_WARGV_SHIFTED(argv, c), &pic);
if (!ok) goto End;
if (enc == NULL) {
@ -259,8 +284,8 @@ int main(int argc, char* argv[]) {
if (!ok) goto End;
if (verbose) {
fprintf(stderr, "Added frame #%3d at time %4d (file: %s)\n",
pic_num, timestamp_ms, argv[c]);
WFPRINTF(stderr, "Added frame #%3d at time %4d (file: %s)\n",
pic_num, timestamp_ms, GET_WARGV_SHIFTED(argv, c));
}
timestamp_ms += duration;
++pic_num;
@ -284,7 +309,7 @@ int main(int argc, char* argv[]) {
if (ok) {
if (output != NULL) {
ok = ImgIoUtilWriteFile(output, webp_data.bytes, webp_data.size);
if (ok) fprintf(stderr, "output file: %s ", output);
if (ok) WFPRINTF(stderr, "output file: %s ", (const W_CHAR*)output);
} else {
fprintf(stderr, "[no output file specified] ");
}
@ -294,7 +319,7 @@ int main(int argc, char* argv[]) {
fprintf(stderr, "[%d frames, %u bytes].\n",
pic_num, (unsigned int)webp_data.size);
}
WebPDataClear(&webp_data);
return ok ? 0 : 1;
ExUtilDeleteCommandLineArguments(&cmd_args);
FREE_WARGV_AND_RETURN(ok ? 0 : 1);
}

View File

@ -60,4 +60,4 @@ static WEBP_INLINE double StopwatchReadAndReset(Stopwatch* watch) {
#endif /* _WIN32 */
#endif /* WEBP_EXAMPLES_STOPWATCH_H_ */
#endif // WEBP_EXAMPLES_STOPWATCH_H_

116
examples/unicode.h Normal file
View File

@ -0,0 +1,116 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Unicode support for Windows. The main idea is to maintain an array of Unicode
// arguments (wargv) and use it only for file paths. The regular argv is used
// for everything else.
//
// Author: Yannis Guyon (yguyon@google.com)
#ifndef WEBP_EXAMPLES_UNICODE_H_
#define WEBP_EXAMPLES_UNICODE_H_
#include <stdio.h>
#if defined(_WIN32) && defined(_UNICODE)
// wchar_t is used instead of TCHAR because we only perform additional work when
// Unicode is enabled and because the output of CommandLineToArgvW() is wchar_t.
#include <fcntl.h>
#include <io.h>
#include <wchar.h>
#include <windows.h>
#include <shellapi.h>
// Create a wchar_t array containing Unicode parameters.
#define INIT_WARGV(ARGC, ARGV) \
int wargc; \
const W_CHAR** const wargv = \
(const W_CHAR**)CommandLineToArgvW(GetCommandLineW(), &wargc); \
do { \
if (wargv == NULL || wargc != (ARGC)) { \
fprintf(stderr, "Error: Unable to get Unicode arguments.\n"); \
FREE_WARGV_AND_RETURN(-1); \
} \
} while (0)
// Use this to get a Unicode argument (e.g. file path).
#define GET_WARGV(UNUSED, C) wargv[C]
// For cases where argv is shifted by one compared to wargv.
#define GET_WARGV_SHIFTED(UNUSED, C) wargv[(C) + 1]
#define GET_WARGV_OR_NULL() wargv
// Release resources. LocalFree() is needed after CommandLineToArgvW().
#define FREE_WARGV() LOCAL_FREE((W_CHAR** const)wargv)
#define LOCAL_FREE(WARGV) \
do { \
if ((WARGV) != NULL) LocalFree(WARGV); \
} while (0)
#define W_CHAR wchar_t // WCHAR without underscore might already be defined.
#define TO_W_CHAR(STR) (L##STR)
#define WFOPEN(ARG, OPT) _wfopen((const W_CHAR*)ARG, TO_W_CHAR(OPT))
#define WFPRINTF(STREAM, STR, ...) \
do { \
int prev_mode; \
fflush(STREAM); \
prev_mode = _setmode(_fileno(STREAM), _O_U8TEXT); \
fwprintf(STREAM, TO_W_CHAR(STR), __VA_ARGS__); \
fflush(STREAM); \
(void)_setmode(_fileno(STREAM), prev_mode); \
} while (0)
#define WPRINTF(STR, ...) WFPRINTF(stdout, STR, __VA_ARGS__)
#define WSTRLEN(FILENAME) wcslen((const W_CHAR*)FILENAME)
#define WSTRCMP(FILENAME, STR) wcscmp((const W_CHAR*)FILENAME, TO_W_CHAR(STR))
#define WSTRRCHR(FILENAME, STR) wcsrchr((const W_CHAR*)FILENAME, TO_W_CHAR(STR))
#define WSNPRINTF(A, B, STR, ...) _snwprintf(A, B, TO_W_CHAR(STR), __VA_ARGS__)
#else
#include <string.h>
// Unicode file paths work as is on Unix platforms, and no extra work is done on
// Windows either if Unicode is disabled.
#define INIT_WARGV(ARGC, ARGV)
#define GET_WARGV(ARGV, C) (ARGV)[C]
#define GET_WARGV_SHIFTED(ARGV, C) (ARGV)[C]
#define GET_WARGV_OR_NULL() NULL
#define FREE_WARGV()
#define LOCAL_FREE(WARGV)
#define W_CHAR char
#define TO_W_CHAR(STR) (STR)
#define WFOPEN(ARG, OPT) fopen(ARG, OPT)
#define WPRINTF(STR, ...) printf(STR, __VA_ARGS__)
#define WFPRINTF(STREAM, STR, ...) fprintf(STREAM, STR, __VA_ARGS__)
#define WSTRLEN(FILENAME) strlen(FILENAME)
#define WSTRCMP(FILENAME, STR) strcmp(FILENAME, STR)
#define WSTRRCHR(FILENAME, STR) strrchr(FILENAME, STR)
#define WSNPRINTF(A, B, STR, ...) snprintf(A, B, STR, __VA_ARGS__)
#endif // defined(_WIN32) && defined(_UNICODE)
// Don't forget to free wargv before returning (e.g. from main).
#define FREE_WARGV_AND_RETURN(VALUE) \
do { \
FREE_WARGV(); \
return (VALUE); \
} while (0)
#endif // WEBP_EXAMPLES_UNICODE_H_

76
examples/unicode_gif.h Normal file
View File

@ -0,0 +1,76 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// giflib doesn't have a Unicode DGifOpenFileName(). Let's make one.
//
// Author: Yannis Guyon (yguyon@google.com)
#ifndef WEBP_EXAMPLES_UNICODE_GIF_H_
#define WEBP_EXAMPLES_UNICODE_GIF_H_
#include "./unicode.h"
#ifdef HAVE_CONFIG_H
#include "webp/config.h" // For WEBP_HAVE_GIF
#endif
#if defined(WEBP_HAVE_GIF)
#ifdef _WIN32
#include <fcntl.h> // Not standard, needed for _topen and flags.
#include <io.h>
#endif
#include <gif_lib.h>
#include <string.h>
#include "./gifdec.h"
#if !defined(STDIN_FILENO)
#define STDIN_FILENO 0
#endif
static GifFileType* DGifOpenFileUnicode(const W_CHAR* file_name, int* error) {
if (!WSTRCMP(file_name, "-")) {
#if LOCAL_GIF_PREREQ(5, 0)
return DGifOpenFileHandle(STDIN_FILENO, error);
#else
(void)error;
return DGifOpenFileHandle(STDIN_FILENO);
#endif
}
#if defined(_WIN32) && defined(_UNICODE)
{
int file_handle = _wopen(file_name, _O_RDONLY | _O_BINARY);
if (file_handle == -1) {
if (error != NULL) *error = D_GIF_ERR_OPEN_FAILED;
return NULL;
}
#if LOCAL_GIF_PREREQ(5, 0)
return DGifOpenFileHandle(file_handle, error);
#else
return DGifOpenFileHandle(file_handle);
#endif
}
#else
#if LOCAL_GIF_PREREQ(5, 0)
return DGifOpenFileName(file_name, error);
#else
return DGifOpenFileName(file_name);
#endif
#endif // defined(_WIN32) && defined(_UNICODE)
// DGifCloseFile() is called later.
}
#endif // defined(WEBP_HAVE_GIF)
#endif // WEBP_EXAMPLES_UNICODE_GIF_H_

View File

@ -42,6 +42,7 @@
#include "../examples/example_util.h"
#include "../imageio/imageio_util.h"
#include "./unicode.h"
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
@ -56,6 +57,7 @@ static struct {
int print_info;
int only_deltas;
int use_color_profile;
int draw_anim_background_color;
int canvas_width, canvas_height;
int loop_count;
@ -205,6 +207,11 @@ static void decode_callback(int what) {
}
}
duration = curr->duration;
// Behavior copied from Chrome, cf:
// https://cs.chromium.org/chromium/src/third_party/WebKit/Source/
// platform/graphics/DeferredImageDecoder.cpp?
// rcl=b4c33049f096cd283f32be9a58b9a9e768227c26&l=246
if (duration <= 10) duration = 100;
}
if (!Decode()) {
kParams.decoding_error = 1;
@ -220,6 +227,9 @@ static void decode_callback(int what) {
// Callbacks
static void HandleKey(unsigned char key, int pos_x, int pos_y) {
// Note: rescaling the window or toggling some features during an animation
// generates visual artifacts. This is not fixed because refreshing the frame
// may require rendering the whole animation from start till current frame.
(void)pos_x;
(void)pos_y;
if (key == 'q' || key == 'Q' || key == 27 /* Esc */) {
@ -247,10 +257,12 @@ static void HandleKey(unsigned char key, int pos_x, int pos_y) {
glutPostRedisplay();
}
}
} else if (key == 'b') {
kParams.draw_anim_background_color = 1 - kParams.draw_anim_background_color;
if (!kParams.has_animation) ClearPreviousFrame();
glutPostRedisplay();
} else if (key == 'i') {
kParams.print_info = 1 - kParams.print_info;
// TODO(skal): handle refresh of animation's last-frame too. It's quite
// more involved though (need to save the previous frame).
if (!kParams.has_animation) ClearPreviousFrame();
glutPostRedisplay();
} else if (key == 'd') {
@ -260,8 +272,8 @@ static void HandleKey(unsigned char key, int pos_x, int pos_y) {
}
static void HandleReshape(int width, int height) {
// TODO(skal): should we preserve aspect ratio?
// Also: handle larger-than-screen pictures correctly.
// Note: reshape doesn't preserve aspect ratio, and might
// be handling larger-than-screen pictures incorrectly.
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@ -280,8 +292,21 @@ static void PrintString(const char* const text) {
}
}
static void PrintStringW(const char* const text) {
#if defined(_WIN32) && defined(_UNICODE)
void* const font = GLUT_BITMAP_9_BY_15;
const W_CHAR* const wtext = (const W_CHAR*)text;
int i;
for (i = 0; wtext[i]; ++i) {
glutBitmapCharacter(font, wtext[i]);
}
#else
PrintString(text);
#endif
}
static float GetColorf(uint32_t color, int shift) {
return (color >> shift) / 255.f;
return ((color >> shift) & 0xff) / 255.f;
}
static void DrawCheckerBoard(void) {
@ -304,6 +329,43 @@ static void DrawCheckerBoard(void) {
glPopMatrix();
}
static void DrawBackground(void) {
// Whole window cleared with clear color, checkerboard rendered on top of it.
glClear(GL_COLOR_BUFFER_BIT);
DrawCheckerBoard();
// ANIM background color rendered (blend) on top. Default is white for still
// images (without ANIM chunk). glClear() can't be used for that (no blend).
if (kParams.draw_anim_background_color) {
glPushMatrix();
glLoadIdentity();
glColor4f(GetColorf(kParams.bg_color, 16), // BGRA from spec
GetColorf(kParams.bg_color, 8),
GetColorf(kParams.bg_color, 0),
GetColorf(kParams.bg_color, 24));
glRecti(-1, -1, +1, +1);
glPopMatrix();
}
}
// Draw background in a scissored rectangle.
static void DrawBackgroundScissored(int window_x, int window_y, int frame_w,
int frame_h) {
// Only update the requested area, not the whole canvas.
window_x = window_x * kParams.viewport_width / kParams.canvas_width;
window_y = window_y * kParams.viewport_height / kParams.canvas_height;
frame_w = frame_w * kParams.viewport_width / kParams.canvas_width;
frame_h = frame_h * kParams.viewport_height / kParams.canvas_height;
// glScissor() takes window coordinates (0,0 at bottom left).
window_y = kParams.viewport_height - window_y - frame_h;
glEnable(GL_SCISSOR_TEST);
glScissor(window_x, window_y, frame_w, frame_h);
DrawBackground();
glDisable(GL_SCISSOR_TEST);
}
static void HandleDisplay(void) {
const WebPDecBuffer* const pic = kParams.pic;
const WebPIterator* const curr = &kParams.curr_frame;
@ -320,38 +382,21 @@ static void HandleDisplay(void) {
glPixelStorei(GL_UNPACK_ROW_LENGTH, pic->u.RGBA.stride / 4);
if (kParams.only_deltas) {
DrawCheckerBoard();
} else if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND ||
curr->blend_method == WEBP_MUX_NO_BLEND) {
// glScissor() takes window coordinates (0,0 at bottom left).
int window_x, window_y;
int frame_w, frame_h;
DrawBackground();
} else {
// The rectangle of the previous frame might be different than the current
// frame, so we may need to DrawBackgroundScissored for both.
if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) {
// Clear the previous frame rectangle.
window_x = prev->x_offset;
window_y = kParams.canvas_height - prev->y_offset - prev->height;
frame_w = prev->width;
frame_h = prev->height;
} else { // curr->blend_method == WEBP_MUX_NO_BLEND.
// We simulate no-blending behavior by first clearing the current frame
// rectangle (to a checker-board) and then alpha-blending against it.
window_x = curr->x_offset;
window_y = kParams.canvas_height - curr->y_offset - curr->height;
frame_w = curr->width;
frame_h = curr->height;
DrawBackgroundScissored(prev->x_offset, prev->y_offset, prev->width,
prev->height);
}
if (curr->blend_method == WEBP_MUX_NO_BLEND) {
// We simulate no-blending behavior by first clearing the current frame
// rectangle and then alpha-blending against it.
DrawBackgroundScissored(curr->x_offset, curr->y_offset, curr->width,
curr->height);
}
glEnable(GL_SCISSOR_TEST);
// Only update the requested area, not the whole canvas.
window_x = window_x * kParams.viewport_width / kParams.canvas_width;
window_y = window_y * kParams.viewport_height / kParams.canvas_height;
frame_w = frame_w * kParams.viewport_width / kParams.canvas_width;
frame_h = frame_h * kParams.viewport_height / kParams.canvas_height;
glScissor(window_x, window_y, frame_w, frame_h);
glClear(GL_COLOR_BUFFER_BIT); // use clear color
DrawCheckerBoard();
glDisable(GL_SCISSOR_TEST);
}
*prev = *curr;
@ -364,7 +409,7 @@ static void HandleDisplay(void) {
glColor4f(0.90f, 0.0f, 0.90f, 1.0f);
glRasterPos2f(-0.95f, 0.90f);
PrintString(kParams.file_name);
PrintStringW(kParams.file_name);
snprintf(tmp, sizeof(tmp), "Dimension:%d x %d", pic->width, pic->height);
glColor4f(0.90f, 0.0f, 0.90f, 1.0f);
@ -378,13 +423,36 @@ static void HandleDisplay(void) {
}
}
glPopMatrix();
#if defined(__APPLE__) || defined(_WIN32)
glFlush();
#else
glutSwapBuffers();
#endif
}
static void StartDisplay(void) {
const int width = kParams.canvas_width;
const int height = kParams.canvas_height;
int width = kParams.canvas_width;
int height = kParams.canvas_height;
int screen_width, screen_height;
// TODO(webp:365) GLUT_DOUBLE results in flickering / old frames to be
// partially displayed with animated webp + alpha.
#if defined(__APPLE__) || defined(_WIN32)
glutInitDisplayMode(GLUT_RGBA);
#else
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
#endif
screen_width = glutGet(GLUT_SCREEN_WIDTH);
screen_height = glutGet(GLUT_SCREEN_HEIGHT);
if (width > screen_width || height > screen_height) {
if (width > screen_width) {
height = (height * screen_width + width - 1) / width;
width = screen_width;
}
if (height > screen_height) {
width = (width * screen_height + height - 1) / height;
height = screen_height;
}
}
glutInitWindowSize(width, height);
glutCreateWindow("WebP viewer");
glutDisplayFunc(HandleDisplay);
@ -393,57 +461,59 @@ static void StartDisplay(void) {
glutKeyboardFunc(HandleKey);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glClearColor(GetColorf(kParams.bg_color, 0),
GetColorf(kParams.bg_color, 8),
GetColorf(kParams.bg_color, 16),
GetColorf(kParams.bg_color, 24));
glClear(GL_COLOR_BUFFER_BIT);
DrawCheckerBoard();
glClearColor(0, 0, 0, 0); // window will be cleared to black (no blend)
DrawBackground();
}
//------------------------------------------------------------------------------
// Main
static void Help(void) {
printf("Usage: vwebp in_file [options]\n\n"
"Decodes the WebP image file and visualize it using OpenGL\n"
"Options are:\n"
" -version ..... print version number and exit\n"
" -noicc ....... don't use the icc profile if present\n"
" -nofancy ..... don't use the fancy YUV420 upscaler\n"
" -nofilter .... disable in-loop filtering\n"
" -dither <int> dithering strength (0..100), default=50\n"
" -noalphadither disable alpha plane dithering\n"
" -mt .......... use multi-threading\n"
" -info ........ print info\n"
" -h ........... this help message\n"
"\n"
"Keyboard shortcuts:\n"
" 'c' ................ toggle use of color profile\n"
" 'i' ................ overlay file information\n"
" 'd' ................ disable blending & disposal (debug)\n"
" 'q' / 'Q' / ESC .... quit\n"
);
printf(
"Usage: vwebp in_file [options]\n\n"
"Decodes the WebP image file and visualize it using OpenGL\n"
"Options are:\n"
" -version ..... print version number and exit\n"
" -noicc ....... don't use the icc profile if present\n"
" -nofancy ..... don't use the fancy YUV420 upscaler\n"
" -nofilter .... disable in-loop filtering\n"
" -dither <int> dithering strength (0..100), default=50\n"
" -noalphadither disable alpha plane dithering\n"
" -usebgcolor .. display background color\n"
" -mt .......... use multi-threading\n"
" -info ........ print info\n"
" -h ........... this help message\n"
"\n"
"Keyboard shortcuts:\n"
" 'c' ................ toggle use of color profile\n"
" 'b' ................ toggle background color display\n"
" 'i' ................ overlay file information\n"
" 'd' ................ disable blending & disposal (debug)\n"
" 'q' / 'Q' / ESC .... quit\n");
}
int main(int argc, char *argv[]) {
int main(int argc, char* argv[]) {
int c;
WebPDecoderConfig* const config = &kParams.config;
WebPIterator* const curr = &kParams.curr_frame;
INIT_WARGV(argc, argv);
if (!WebPInitDecoderConfig(config)) {
fprintf(stderr, "Library version mismatch!\n");
return -1;
FREE_WARGV_AND_RETURN(-1);
}
config->options.dithering_strength = 50;
config->options.alpha_dithering_strength = 100;
kParams.use_color_profile = 1;
// Background color hidden by default to see transparent areas.
kParams.draw_anim_background_color = 0;
for (c = 1; c < argc; ++c) {
int parse_error = 0;
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
Help();
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-noicc")) {
kParams.use_color_profile = 0;
} else if (!strcmp(argv[c], "-nofancy")) {
@ -452,6 +522,8 @@ int main(int argc, char *argv[]) {
config->options.bypass_filtering = 1;
} else if (!strcmp(argv[c], "-noalphadither")) {
config->options.alpha_dithering_strength = 0;
} else if (!strcmp(argv[c], "-usebgcolor")) {
kParams.draw_anim_background_color = 1;
} else if (!strcmp(argv[c], "-dither") && c + 1 < argc) {
config->options.dithering_strength =
ExUtilGetInt(argv[++c], 0, &parse_error);
@ -464,30 +536,30 @@ int main(int argc, char *argv[]) {
(dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
dec_version & 0xff, (dmux_version >> 16) & 0xff,
(dmux_version >> 8) & 0xff, dmux_version & 0xff);
return 0;
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-mt")) {
config->options.use_threads = 1;
} else if (!strcmp(argv[c], "--")) {
if (c < argc - 1) kParams.file_name = argv[++c];
if (c < argc - 1) kParams.file_name = (const char*)GET_WARGV(argv, ++c);
break;
} else if (argv[c][0] == '-') {
printf("Unknown option '%s'\n", argv[c]);
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
} else {
kParams.file_name = argv[c];
kParams.file_name = (const char*)GET_WARGV(argv, c);
}
if (parse_error) {
Help();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
}
if (kParams.file_name == NULL) {
printf("missing input file!!\n");
Help();
return 0;
FREE_WARGV_AND_RETURN(0);
}
if (!ImgIoUtilReadFile(kParams.file_name,
@ -562,16 +634,16 @@ int main(int argc, char *argv[]) {
// Should only be reached when using FREEGLUT:
ClearParams();
return 0;
FREE_WARGV_AND_RETURN(0);
Error:
ClearParams();
return -1;
FREE_WARGV_AND_RETURN(-1);
}
#else // !WEBP_HAVE_GL
int main(int argc, const char *argv[]) {
int main(int argc, const char* argv[]) {
fprintf(stderr, "OpenGL support not enabled in %s.\n", argv[0]);
(void)argc;
return 0;

1186
examples/webpinfo.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@
webpmux -set icc image_profile.icc in.webp -o out_icc_container.webp
webpmux -set exif image_metadata.exif in.webp -o out_exif_container.webp
webpmux -set xmp image_metadata.xmp in.webp -o out_xmp_container.webp
webpmux -set loop 1 in.webp -o out_looped.webp
Extract relevant data from WebP container file:
webpmux -get frame n in.webp -o out_frame.webp
@ -47,6 +48,7 @@
webpmux -info in.webp
webpmux [ -h | -help ]
webpmux -version
webpmux argument_file_name
*/
#ifdef HAVE_CONFIG_H
@ -61,6 +63,7 @@
#include "webp/mux.h"
#include "../examples/example_util.h"
#include "../imageio/imageio_util.h"
#include "./unicode.h"
//------------------------------------------------------------------------------
// Config object to parse command-line arguments.
@ -95,6 +98,8 @@ typedef enum {
FEATURE_ICCP,
FEATURE_ANMF,
FEATURE_DURATION,
FEATURE_LOOP,
FEATURE_BGCOLOR,
LAST_FEATURE
} FeatureType;
@ -108,28 +113,26 @@ static const char* const kDescriptions[LAST_FEATURE] = {
};
typedef struct {
FeatureType type_;
FeatureArg* args_;
int arg_count_;
} Feature;
CommandLineArguments cmd_args_;
typedef struct {
ActionType action_type_;
const char* input_;
const char* output_;
Feature feature_;
} WebPMuxConfig;
FeatureType type_;
FeatureArg* args_;
int arg_count_;
} Config;
//------------------------------------------------------------------------------
// Helper functions.
static int CountOccurrences(const char* arglist[], int list_length,
const char* arg) {
static int CountOccurrences(const CommandLineArguments* const args,
const char* const arg) {
int i;
int num_occurences = 0;
for (i = 0; i < list_length; ++i) {
if (!strcmp(arglist[i], arg)) {
for (i = 0; i < args->argc_; ++i) {
if (!strcmp(args->argv_[i], arg)) {
++num_occurences;
}
}
@ -301,6 +304,7 @@ static void PrintHelp(void) {
printf(" webpmux -info INPUT\n");
printf(" webpmux [-h|-help]\n");
printf(" webpmux -version\n");
printf(" webpmux argument_file_name\n");
printf("\n");
printf("GET_OPTIONS:\n");
@ -312,10 +316,12 @@ static void PrintHelp(void) {
printf("\n");
printf("SET_OPTIONS:\n");
printf(" Set color profile/metadata:\n");
printf(" icc file.icc set ICC profile\n");
printf(" exif file.exif set EXIF metadata\n");
printf(" xmp file.xmp set XMP metadata\n");
printf(" Set color profile/metadata/parameters:\n");
printf(" loop LOOP_COUNT set the loop count\n");
printf(" bgcolor BACKGROUND_COLOR set the animation background color\n");
printf(" icc file.icc set ICC profile\n");
printf(" exif file.exif set EXIF metadata\n");
printf(" xmp file.xmp set XMP metadata\n");
printf(" where: 'file.icc' contains the ICC profile to be set,\n");
printf(" 'file.exif' contains the EXIF metadata to be set\n");
printf(" 'file.xmp' contains the XMP metadata to be set\n");
@ -323,7 +329,7 @@ static void PrintHelp(void) {
printf("\n");
printf("DURATION_OPTIONS:\n");
printf(" Set duration of selected frames:\n");
printf(" duration set duration for each frames\n");
printf(" duration set duration for all frames\n");
printf(" duration,frame set duration of a particular frame\n");
printf(" duration,start,end set duration of frames in the\n");
printf(" interval [start,end])\n");
@ -342,7 +348,7 @@ static void PrintHelp(void) {
printf("\n");
printf("FRAME_OPTIONS(i):\n");
printf(" Create animation:\n");
printf(" file_i +di+[xi+yi[+mi[bi]]]\n");
printf(" file_i +di[+xi+yi[+mi[bi]]]\n");
printf(" where: 'file_i' is the i'th animation frame (WebP format),\n");
printf(" 'di' is the pause duration before next frame,\n");
printf(" 'xi','yi' specify the image offset for this frame,\n");
@ -369,6 +375,10 @@ static void PrintHelp(void) {
printf("\nNote: The nature of EXIF, XMP and ICC data is not checked");
printf(" and is assumed to be\nvalid.\n");
printf("\nNote: if a single file name is passed as the argument, the "
"arguments will be\n");
printf("tokenized from this file. The file name must not start with "
"the character '-'.\n");
}
static void WarnAboutOddOffset(const WebPMuxFrameInfo* const info) {
@ -379,40 +389,32 @@ static void WarnAboutOddOffset(const WebPMuxFrameInfo* const info) {
}
}
static int ReadFileToWebPData(const char* const filename,
WebPData* const webp_data) {
const uint8_t* data;
size_t size;
if (!ImgIoUtilReadFile(filename, &data, &size)) return 0;
webp_data->bytes = data;
webp_data->size = size;
return 1;
}
static int CreateMux(const char* const filename, WebPMux** mux) {
WebPData bitstream;
assert(mux != NULL);
if (!ReadFileToWebPData(filename, &bitstream)) return 0;
if (!ExUtilReadFileToWebPData(filename, &bitstream)) return 0;
*mux = WebPMuxCreate(&bitstream, 1);
free((void*)bitstream.bytes);
WebPDataClear(&bitstream);
if (*mux != NULL) return 1;
fprintf(stderr, "Failed to create mux object from file %s.\n", filename);
WFPRINTF(stderr, "Failed to create mux object from file %s.\n",
(const W_CHAR*)filename);
return 0;
}
static int WriteData(const char* filename, const WebPData* const webpdata) {
int ok = 0;
FILE* fout = strcmp(filename, "-") ? fopen(filename, "wb")
: ImgIoUtilSetBinaryMode(stdout);
FILE* fout = WSTRCMP(filename, "-") ? WFOPEN(filename, "wb")
: ImgIoUtilSetBinaryMode(stdout);
if (fout == NULL) {
fprintf(stderr, "Error opening output WebP file %s!\n", filename);
WFPRINTF(stderr, "Error opening output WebP file %s!\n",
(const W_CHAR*)filename);
return 0;
}
if (fwrite(webpdata->bytes, webpdata->size, 1, fout) != 1) {
fprintf(stderr, "Error writing file %s!\n", filename);
WFPRINTF(stderr, "Error writing file %s!\n", (const W_CHAR*)filename);
} else {
fprintf(stderr, "Saved file %s (%d bytes)\n",
filename, (int)webpdata->size);
WFPRINTF(stderr, "Saved file %s (%d bytes)\n",
(const W_CHAR*)filename, (int)webpdata->size);
ok = 1;
}
if (fout != stdout) fclose(fout);
@ -458,7 +460,8 @@ static WebPMux* DuplicateMuxHeader(const WebPMux* const mux) {
if (err == WEBP_MUX_OK && metadata.size > 0) {
err = WebPMuxSetChunk(new_mux, kFourccList[i], &metadata, 1);
if (err != WEBP_MUX_OK) {
ERROR_GOTO1("Error transferring metadata in DuplicateMux().", End);
ERROR_GOTO1("Error transferring metadata in DuplicateMuxHeader().",
End);
}
}
}
@ -472,11 +475,11 @@ static WebPMux* DuplicateMuxHeader(const WebPMux* const mux) {
}
static int ParseFrameArgs(const char* args, WebPMuxFrameInfo* const info) {
int dispose_method, dummy;
int dispose_method, unused;
char plus_minus, blend_method;
const int num_args = sscanf(args, "+%d+%d+%d+%d%c%c+%d", &info->duration,
&info->x_offset, &info->y_offset, &dispose_method,
&plus_minus, &blend_method, &dummy);
&plus_minus, &blend_method, &unused);
switch (num_args) {
case 1:
info->x_offset = info->y_offset = 0; // fall through
@ -495,7 +498,7 @@ static int ParseFrameArgs(const char* args, WebPMuxFrameInfo* const info) {
WarnAboutOddOffset(info);
// Note: The sanity of the following conversion is checked by
// Note: The validity of the following conversion is checked by
// WebPMuxPushFrame().
info->dispose_method = (WebPMuxAnimDispose)dispose_method;
@ -517,9 +520,10 @@ static int ParseBgcolorArgs(const char* args, uint32_t* const bgcolor) {
//------------------------------------------------------------------------------
// Clean-up.
static void DeleteConfig(WebPMuxConfig* config) {
static void DeleteConfig(Config* const config) {
if (config != NULL) {
free(config->feature_.args_);
free(config->args_);
ExUtilDeleteCommandLineArguments(&config->cmd_args_);
memset(config, 0, sizeof(*config));
}
}
@ -531,7 +535,7 @@ static void DeleteConfig(WebPMuxConfig* config) {
// Returns 1 on valid, 0 otherwise.
// Also fills up num_feature_args to be number of feature arguments given.
// (e.g. if there are 4 '-frame's and 1 '-loop', then num_feature_args = 5).
static int ValidateCommandLine(int argc, const char* argv[],
static int ValidateCommandLine(const CommandLineArguments* const cmd_args,
int* num_feature_args) {
int num_frame_args;
int num_loop_args;
@ -543,27 +547,27 @@ static int ValidateCommandLine(int argc, const char* argv[],
*num_feature_args = 0;
// Simple checks.
if (CountOccurrences(argv, argc, "-get") > 1) {
if (CountOccurrences(cmd_args, "-get") > 1) {
ERROR_GOTO1("ERROR: Multiple '-get' arguments specified.\n", ErrValidate);
}
if (CountOccurrences(argv, argc, "-set") > 1) {
if (CountOccurrences(cmd_args, "-set") > 1) {
ERROR_GOTO1("ERROR: Multiple '-set' arguments specified.\n", ErrValidate);
}
if (CountOccurrences(argv, argc, "-strip") > 1) {
if (CountOccurrences(cmd_args, "-strip") > 1) {
ERROR_GOTO1("ERROR: Multiple '-strip' arguments specified.\n", ErrValidate);
}
if (CountOccurrences(argv, argc, "-info") > 1) {
if (CountOccurrences(cmd_args, "-info") > 1) {
ERROR_GOTO1("ERROR: Multiple '-info' arguments specified.\n", ErrValidate);
}
if (CountOccurrences(argv, argc, "-o") > 1) {
if (CountOccurrences(cmd_args, "-o") > 1) {
ERROR_GOTO1("ERROR: Multiple output files specified.\n", ErrValidate);
}
// Compound checks.
num_frame_args = CountOccurrences(argv, argc, "-frame");
num_loop_args = CountOccurrences(argv, argc, "-loop");
num_bgcolor_args = CountOccurrences(argv, argc, "-bgcolor");
num_durations_args = CountOccurrences(argv, argc, "-duration");
num_frame_args = CountOccurrences(cmd_args, "-frame");
num_loop_args = CountOccurrences(cmd_args, "-loop");
num_bgcolor_args = CountOccurrences(cmd_args, "-bgcolor");
num_durations_args = CountOccurrences(cmd_args, "-duration");
if (num_loop_args > 1) {
ERROR_GOTO1("ERROR: Multiple loop counts specified.\n", ErrValidate);
@ -598,31 +602,38 @@ static int ValidateCommandLine(int argc, const char* argv[],
#define ACTION_IS_NIL (config->action_type_ == NIL_ACTION)
#define FEATURETYPE_IS_NIL (feature->type_ == NIL_FEATURE)
#define FEATURETYPE_IS_NIL (config->type_ == NIL_FEATURE)
#define CHECK_NUM_ARGS_LESS(NUM, LABEL) \
#define CHECK_NUM_ARGS_AT_LEAST(NUM, LABEL) \
if (argc < i + (NUM)) { \
fprintf(stderr, "ERROR: Too few arguments for '%s'.\n", argv[i]); \
goto LABEL; \
}
#define CHECK_NUM_ARGS_NOT_EQUAL(NUM, LABEL) \
if (argc != i + (NUM)) { \
#define CHECK_NUM_ARGS_AT_MOST(NUM, LABEL) \
if (argc > i + (NUM)) { \
fprintf(stderr, "ERROR: Too many arguments for '%s'.\n", argv[i]); \
goto LABEL; \
}
#define CHECK_NUM_ARGS_EXACTLY(NUM, LABEL) \
CHECK_NUM_ARGS_AT_LEAST(NUM, LABEL); \
CHECK_NUM_ARGS_AT_MOST(NUM, LABEL);
// Parses command-line arguments to fill up config object. Also performs some
// semantic checks.
static int ParseCommandLine(int argc, const char* argv[],
WebPMuxConfig* config) {
// semantic checks. unicode_argv contains wchar_t arguments or is null.
static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
int i = 0;
int feature_arg_index = 0;
int ok = 1;
int argc = config->cmd_args_.argc_;
const char* const* argv = config->cmd_args_.argv_;
// Unicode file paths will be used if available.
const char* const* wargv =
(unicode_argv != NULL) ? (const char**)(unicode_argv + 1) : argv;
while (i < argc) {
Feature* const feature = &config->feature_;
FeatureArg* const arg = &feature->args_[feature_arg_index];
FeatureArg* const arg = &config->args_[feature_arg_index];
if (argv[i][0] == '-') { // One of the action types or output.
if (!strcmp(argv[i], "-set")) {
if (ACTION_IS_NIL) {
@ -632,14 +643,14 @@ static int ParseCommandLine(int argc, const char* argv[],
}
++i;
} else if (!strcmp(argv[i], "-duration")) {
CHECK_NUM_ARGS_LESS(2, ErrParse);
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
if (ACTION_IS_NIL || config->action_type_ == ACTION_DURATION) {
config->action_type_ = ACTION_DURATION;
} else {
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
}
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_DURATION) {
feature->type_ = FEATURE_DURATION;
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_DURATION) {
config->type_ = FEATURE_DURATION;
} else {
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
}
@ -656,37 +667,37 @@ static int ParseCommandLine(int argc, const char* argv[],
} else if (!strcmp(argv[i], "-strip")) {
if (ACTION_IS_NIL) {
config->action_type_ = ACTION_STRIP;
feature->arg_count_ = 0;
config->arg_count_ = 0;
} else {
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
}
++i;
} else if (!strcmp(argv[i], "-frame")) {
CHECK_NUM_ARGS_LESS(3, ErrParse);
CHECK_NUM_ARGS_AT_LEAST(3, ErrParse);
if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) {
config->action_type_ = ACTION_SET;
} else {
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
}
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_ANMF) {
feature->type_ = FEATURE_ANMF;
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_ANMF) {
config->type_ = FEATURE_ANMF;
} else {
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
}
arg->subtype_ = SUBTYPE_ANMF;
arg->filename_ = argv[i + 1];
arg->filename_ = wargv[i + 1];
arg->params_ = argv[i + 2];
++feature_arg_index;
i += 3;
} else if (!strcmp(argv[i], "-loop") || !strcmp(argv[i], "-bgcolor")) {
CHECK_NUM_ARGS_LESS(2, ErrParse);
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) {
config->action_type_ = ACTION_SET;
} else {
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
}
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_ANMF) {
feature->type_ = FEATURE_ANMF;
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_ANMF) {
config->type_ = FEATURE_ANMF;
} else {
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
}
@ -696,34 +707,36 @@ static int ParseCommandLine(int argc, const char* argv[],
++feature_arg_index;
i += 2;
} else if (!strcmp(argv[i], "-o")) {
CHECK_NUM_ARGS_LESS(2, ErrParse);
config->output_ = argv[i + 1];
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
config->output_ = wargv[i + 1];
i += 2;
} else if (!strcmp(argv[i], "-info")) {
CHECK_NUM_ARGS_NOT_EQUAL(2, ErrParse);
CHECK_NUM_ARGS_EXACTLY(2, ErrParse);
if (config->action_type_ != NIL_ACTION) {
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
} else {
config->action_type_ = ACTION_INFO;
feature->arg_count_ = 0;
config->input_ = argv[i + 1];
config->arg_count_ = 0;
config->input_ = wargv[i + 1];
}
i += 2;
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help")) {
PrintHelp();
DeleteConfig(config);
LOCAL_FREE((W_CHAR** const)unicode_argv);
exit(0);
} else if (!strcmp(argv[i], "-version")) {
const int version = WebPGetMuxVersion();
printf("%d.%d.%d\n",
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
DeleteConfig(config);
LOCAL_FREE((W_CHAR** const)unicode_argv);
exit(0);
} else if (!strcmp(argv[i], "--")) {
if (i < argc - 1) {
++i;
if (config->input_ == NULL) {
config->input_ = argv[i];
config->input_ = wargv[i];
} else {
ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n",
argv[i], ErrParse);
@ -741,14 +754,14 @@ static int ParseCommandLine(int argc, const char* argv[],
if (!strcmp(argv[i], "icc") || !strcmp(argv[i], "exif") ||
!strcmp(argv[i], "xmp")) {
if (FEATURETYPE_IS_NIL) {
feature->type_ = (!strcmp(argv[i], "icc")) ? FEATURE_ICCP :
config->type_ = (!strcmp(argv[i], "icc")) ? FEATURE_ICCP :
(!strcmp(argv[i], "exif")) ? FEATURE_EXIF : FEATURE_XMP;
} else {
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
}
if (config->action_type_ == ACTION_SET) {
CHECK_NUM_ARGS_LESS(2, ErrParse);
arg->filename_ = argv[i + 1];
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
arg->filename_ = wargv[i + 1];
++feature_arg_index;
i += 2;
} else {
@ -756,14 +769,28 @@ static int ParseCommandLine(int argc, const char* argv[],
}
} else if (!strcmp(argv[i], "frame") &&
(config->action_type_ == ACTION_GET)) {
CHECK_NUM_ARGS_LESS(2, ErrParse);
feature->type_ = FEATURE_ANMF;
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
config->type_ = FEATURE_ANMF;
arg->params_ = argv[i + 1];
++feature_arg_index;
i += 2;
} else if (!strcmp(argv[i], "loop") &&
(config->action_type_ == ACTION_SET)) {
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
config->type_ = FEATURE_LOOP;
arg->params_ = argv[i + 1];
++feature_arg_index;
i += 2;
} else if (!strcmp(argv[i], "bgcolor") &&
(config->action_type_ == ACTION_SET)) {
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
config->type_ = FEATURE_BGCOLOR;
arg->params_ = argv[i + 1];
++feature_arg_index;
i += 2;
} else { // Assume input file.
if (config->input_ == NULL) {
config->input_ = argv[i];
config->input_ = wargv[i];
} else {
ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n",
argv[i], ErrParse);
@ -777,9 +804,8 @@ static int ParseCommandLine(int argc, const char* argv[],
}
// Additional checks after config is filled.
static int ValidateConfig(WebPMuxConfig* config) {
static int ValidateConfig(Config* const config) {
int ok = 1;
Feature* const feature = &config->feature_;
// Action.
if (ACTION_IS_NIL) {
@ -795,7 +821,7 @@ static int ValidateConfig(WebPMuxConfig* config) {
if (config->input_ == NULL) {
if (config->action_type_ != ACTION_SET) {
ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2);
} else if (feature->type_ != FEATURE_ANMF) {
} else if (config->type_ != FEATURE_ANMF) {
ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2);
}
}
@ -810,28 +836,29 @@ static int ValidateConfig(WebPMuxConfig* config) {
}
// Create config object from command-line arguments.
static int InitializeConfig(int argc, const char* argv[],
WebPMuxConfig* config) {
static int InitializeConfig(int argc, const char* argv[], Config* const config,
const W_CHAR** const unicode_argv) {
int num_feature_args = 0;
int ok = 1;
int ok;
assert(config != NULL);
memset(config, 0, sizeof(*config));
ok = ExUtilInitCommandLineArguments(argc, argv, &config->cmd_args_);
if (!ok) return 0;
// Validate command-line arguments.
if (!ValidateCommandLine(argc, argv, &num_feature_args)) {
if (!ValidateCommandLine(&config->cmd_args_, &num_feature_args)) {
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
}
config->feature_.arg_count_ = num_feature_args;
config->feature_.args_ =
(FeatureArg*)calloc(num_feature_args, sizeof(*config->feature_.args_));
if (config->feature_.args_ == NULL) {
config->arg_count_ = num_feature_args;
config->args_ = (FeatureArg*)calloc(num_feature_args, sizeof(*config->args_));
if (config->args_ == NULL) {
ERROR_GOTO1("ERROR: Memory allocation error.\n", Err1);
}
// Parse command-line.
if (!ParseCommandLine(argc, argv, config) || !ValidateConfig(config)) {
if (!ParseCommandLine(config, unicode_argv) || !ValidateConfig(config)) {
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
}
@ -841,13 +868,14 @@ static int InitializeConfig(int argc, const char* argv[],
#undef ACTION_IS_NIL
#undef FEATURETYPE_IS_NIL
#undef CHECK_NUM_ARGS_LESS
#undef CHECK_NUM_ARGS_MORE
#undef CHECK_NUM_ARGS_AT_LEAST
#undef CHECK_NUM_ARGS_AT_MOST
#undef CHECK_NUM_ARGS_EXACTLY
//------------------------------------------------------------------------------
// Processing.
static int GetFrame(const WebPMux* mux, const WebPMuxConfig* config) {
static int GetFrame(const WebPMux* mux, const Config* config) {
WebPMuxError err = WEBP_MUX_OK;
WebPMux* mux_single = NULL;
int num = 0;
@ -857,7 +885,7 @@ static int GetFrame(const WebPMux* mux, const WebPMuxConfig* config) {
WebPMuxFrameInfo info;
WebPDataInit(&info.bitstream);
num = ExUtilGetInt(config->feature_.args_[0].params_, 10, &parse_error);
num = ExUtilGetInt(config->args_[0].params_, 10, &parse_error);
if (num < 0) {
ERROR_GOTO1("ERROR: Frame/Fragment index must be non-negative.\n", ErrGet);
}
@ -891,18 +919,17 @@ static int GetFrame(const WebPMux* mux, const WebPMuxConfig* config) {
}
// Read and process config.
static int Process(const WebPMuxConfig* config) {
static int Process(const Config* config) {
WebPMux* mux = NULL;
WebPData chunk;
WebPMuxError err = WEBP_MUX_OK;
int ok = 1;
const Feature* const feature = &config->feature_;
switch (config->action_type_) {
case ACTION_GET: {
ok = CreateMux(config->input_, &mux);
if (!ok) goto Err2;
switch (feature->type_) {
switch (config->type_) {
case FEATURE_ANMF:
ok = GetFrame(mux, config);
break;
@ -910,10 +937,10 @@ static int Process(const WebPMuxConfig* config) {
case FEATURE_ICCP:
case FEATURE_EXIF:
case FEATURE_XMP:
err = WebPMuxGetChunk(mux, kFourccList[feature->type_], &chunk);
err = WebPMuxGetChunk(mux, kFourccList[config->type_], &chunk);
if (err != WEBP_MUX_OK) {
ERROR_GOTO3("ERROR (%s): Could not get the %s.\n",
ErrorString(err), kDescriptions[feature->type_], Err2);
ErrorString(err), kDescriptions[config->type_], Err2);
}
ok = WriteData(config->output_, &chunk);
break;
@ -925,7 +952,7 @@ static int Process(const WebPMuxConfig* config) {
break;
}
case ACTION_SET: {
switch (feature->type_) {
switch (config->type_) {
case FEATURE_ANMF: {
int i;
WebPMuxAnimParams params = { 0xFFFFFFFF, 0 };
@ -934,11 +961,11 @@ static int Process(const WebPMuxConfig* config) {
ERROR_GOTO2("ERROR (%s): Could not allocate a mux object.\n",
ErrorString(WEBP_MUX_MEMORY_ERROR), Err2);
}
for (i = 0; i < feature->arg_count_; ++i) {
switch (feature->args_[i].subtype_) {
for (i = 0; i < config->arg_count_; ++i) {
switch (config->args_[i].subtype_) {
case SUBTYPE_BGCOLOR: {
uint32_t bgcolor;
ok = ParseBgcolorArgs(feature->args_[i].params_, &bgcolor);
ok = ParseBgcolorArgs(config->args_[i].params_, &bgcolor);
if (!ok) {
ERROR_GOTO1("ERROR: Could not parse the background color \n",
Err2);
@ -949,7 +976,7 @@ static int Process(const WebPMuxConfig* config) {
case SUBTYPE_LOOP: {
int parse_error = 0;
const int loop_count =
ExUtilGetInt(feature->args_[i].params_, 10, &parse_error);
ExUtilGetInt(config->args_[i].params_, 10, &parse_error);
if (loop_count < 0 || loop_count > 65535) {
// Note: This is only a 'necessary' condition for loop_count
// to be valid. The 'sufficient' conditioned in checked in
@ -965,10 +992,10 @@ static int Process(const WebPMuxConfig* config) {
case SUBTYPE_ANMF: {
WebPMuxFrameInfo frame;
frame.id = WEBP_CHUNK_ANMF;
ok = ReadFileToWebPData(feature->args_[i].filename_,
&frame.bitstream);
ok = ExUtilReadFileToWebPData(config->args_[i].filename_,
&frame.bitstream);
if (!ok) goto Err2;
ok = ParseFrameArgs(feature->args_[i].params_, &frame);
ok = ParseFrameArgs(config->args_[i].params_, &frame);
if (!ok) {
WebPDataClear(&frame.bitstream);
ERROR_GOTO1("ERROR: Could not parse frame properties.\n",
@ -1001,13 +1028,62 @@ static int Process(const WebPMuxConfig* config) {
case FEATURE_XMP: {
ok = CreateMux(config->input_, &mux);
if (!ok) goto Err2;
ok = ReadFileToWebPData(feature->args_[0].filename_, &chunk);
ok = ExUtilReadFileToWebPData(config->args_[0].filename_, &chunk);
if (!ok) goto Err2;
err = WebPMuxSetChunk(mux, kFourccList[feature->type_], &chunk, 1);
free((void*)chunk.bytes);
err = WebPMuxSetChunk(mux, kFourccList[config->type_], &chunk, 1);
WebPDataClear(&chunk);
if (err != WEBP_MUX_OK) {
ERROR_GOTO3("ERROR (%s): Could not set the %s.\n",
ErrorString(err), kDescriptions[feature->type_], Err2);
ErrorString(err), kDescriptions[config->type_], Err2);
}
break;
}
case FEATURE_LOOP: {
WebPMuxAnimParams params = { 0xFFFFFFFF, 0 };
int parse_error = 0;
const int loop_count =
ExUtilGetInt(config->args_[0].params_, 10, &parse_error);
if (loop_count < 0 || loop_count > 65535 || parse_error) {
ERROR_GOTO1("ERROR: Loop count must be in the range 0 to 65535.\n",
Err2);
}
ok = CreateMux(config->input_, &mux);
if (!ok) goto Err2;
ok = (WebPMuxGetAnimationParams(mux, &params) == WEBP_MUX_OK);
if (!ok) {
ERROR_GOTO1("ERROR: input file does not seem to be an animation.\n",
Err2);
}
params.loop_count = loop_count;
err = WebPMuxSetAnimationParams(mux, &params);
ok = (err == WEBP_MUX_OK);
if (!ok) {
ERROR_GOTO2("ERROR (%s): Could not set animation parameters.\n",
ErrorString(err), Err2);
}
break;
}
case FEATURE_BGCOLOR: {
WebPMuxAnimParams params = { 0xFFFFFFFF, 0 };
uint32_t bgcolor;
ok = ParseBgcolorArgs(config->args_[0].params_, &bgcolor);
if (!ok) {
ERROR_GOTO1("ERROR: Could not parse the background color.\n",
Err2);
}
ok = CreateMux(config->input_, &mux);
if (!ok) goto Err2;
ok = (WebPMuxGetAnimationParams(mux, &params) == WEBP_MUX_OK);
if (!ok) {
ERROR_GOTO1("ERROR: input file does not seem to be an animation.\n",
Err2);
}
params.bgcolor = bgcolor;
err = WebPMuxSetAnimationParams(mux, &params);
ok = (err == WEBP_MUX_OK);
if (!ok) {
ERROR_GOTO2("ERROR (%s): Could not set animation parameters.\n",
ErrorString(err), Err2);
}
break;
}
@ -1038,16 +1114,16 @@ static int Process(const WebPMuxConfig* config) {
int* durations = NULL;
WebPMux* new_mux = DuplicateMuxHeader(mux);
if (new_mux == NULL) goto Err2;
durations = (int*)malloc((size_t)num_frames * sizeof(*durations));
durations = (int*)WebPMalloc((size_t)num_frames * sizeof(*durations));
if (durations == NULL) goto Err2;
for (i = 0; i < num_frames; ++i) durations[i] = -1;
// Parse intervals to process.
for (i = 0; i < feature->arg_count_; ++i) {
for (i = 0; i < config->arg_count_; ++i) {
int k;
int args[3];
int duration, start, end;
const int nb_args = ExUtilGetInts(feature->args_[i].params_,
const int nb_args = ExUtilGetInts(config->args_[i].params_,
10, 3, args);
ok = (nb_args >= 1);
if (!ok) goto Err3;
@ -1096,7 +1172,7 @@ static int Process(const WebPMuxConfig* config) {
new_mux = NULL;
Err3:
free(durations);
WebPFree(durations);
WebPMuxDelete(new_mux);
if (!ok) goto Err2;
}
@ -1105,12 +1181,12 @@ static int Process(const WebPMuxConfig* config) {
case ACTION_STRIP: {
ok = CreateMux(config->input_, &mux);
if (!ok) goto Err2;
if (feature->type_ == FEATURE_ICCP || feature->type_ == FEATURE_EXIF ||
feature->type_ == FEATURE_XMP) {
err = WebPMuxDeleteChunk(mux, kFourccList[feature->type_]);
if (config->type_ == FEATURE_ICCP || config->type_ == FEATURE_EXIF ||
config->type_ == FEATURE_XMP) {
err = WebPMuxDeleteChunk(mux, kFourccList[config->type_]);
if (err != WEBP_MUX_OK) {
ERROR_GOTO3("ERROR (%s): Could not strip the %s.\n",
ErrorString(err), kDescriptions[feature->type_], Err2);
ErrorString(err), kDescriptions[config->type_], Err2);
}
} else {
ERROR_GOTO1("ERROR: Invalid feature for action 'strip'.\n", Err2);
@ -1140,15 +1216,19 @@ static int Process(const WebPMuxConfig* config) {
// Main.
int main(int argc, const char* argv[]) {
WebPMuxConfig config;
int ok = InitializeConfig(argc - 1, argv + 1, &config);
Config config;
int ok;
INIT_WARGV(argc, argv);
ok = InitializeConfig(argc - 1, argv + 1, &config, GET_WARGV_OR_NULL());
if (ok) {
ok = Process(&config);
} else {
PrintHelp();
}
DeleteConfig(&config);
return !ok;
FREE_WARGV_AND_RETURN(!ok);
}
//------------------------------------------------------------------------------

View File

@ -1,3 +1,4 @@
AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
noinst_LTLIBRARIES = libwebpextras.la
@ -11,16 +12,33 @@ libwebpextras_la_CPPFLAGS = $(AM_CPPFLAGS)
libwebpextras_la_LDFLAGS = -lm
libwebpextras_la_LIBADD = ../src/libwebp.la
noinst_PROGRAMS = get_disto webp_quality
noinst_PROGRAMS =
noinst_PROGRAMS += webp_quality
if BUILD_DEMUX
noinst_PROGRAMS += get_disto
endif
if BUILD_VWEBP_SDL
noinst_PROGRAMS += vwebp_sdl
endif
get_disto_SOURCES = get_disto.c
get_disto_CPPFLAGS = $(AM_CPPFLAGS)
get_disto_LDADD = ../imageio/libimageio_util.la ../imageio/libimagedec.la
get_disto_SOURCES = get_disto.c
get_disto_CPPFLAGS = $(AM_CPPFLAGS)
get_disto_LDADD =
get_disto_LDADD += ../imageio/libimageio_util.la
get_disto_LDADD += ../imageio/libimagedec.la
get_disto_LDADD += ../src/libwebp.la
get_disto_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS)
webp_quality_SOURCES = webp_quality.c
webp_quality_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
webp_quality_LDADD = ../imageio/libimageio_util.la
webp_quality_CPPFLAGS = $(AM_CPPFLAGS)
webp_quality_LDADD =
webp_quality_LDADD += ../imageio/libimageio_util.la
webp_quality_LDADD += libwebpextras.la
webp_quality_LDADD += ../src/libwebp.la
vwebp_sdl_SOURCES = vwebp_sdl.c webp_to_sdl.c webp_to_sdl.h
vwebp_sdl_CPPFLAGS = $(AM_CPPFLAGS) $(SDL_INCLUDES)
vwebp_sdl_LDADD =
vwebp_sdl_LDADD += ../imageio/libimageio_util.la
vwebp_sdl_LDADD += ../src/libwebp.la
vwebp_sdl_LDADD += $(SDL_LIBS)

View File

@ -10,15 +10,16 @@
// Additional WebP utilities.
//
#include "./extras.h"
#include "extras/extras.h"
#include "webp/format_constants.h"
#include "src/dsp/dsp.h"
#include <assert.h>
#include <string.h>
#define XTRA_MAJ_VERSION 0
#define XTRA_MIN_VERSION 1
#define XTRA_REV_VERSION 0
#define XTRA_MAJ_VERSION 1
#define XTRA_MIN_VERSION 2
#define XTRA_REV_VERSION 4
//------------------------------------------------------------------------------
@ -48,15 +49,16 @@ int WebPImportGray(const uint8_t* gray_data, WebPPicture* pic) {
int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
int x, y;
uint32_t* dst;
if (pic == NULL || rgb565 == NULL) return 0;
pic->colorspace = WEBP_YUV420;
pic->use_argb = 1;
if (!WebPPictureAlloc(pic)) return 0;
dst = pic->argb;
for (y = 0; y < pic->height; ++y) {
const int width = pic->width;
uint32_t* dst = pic->argb + y * pic->argb_stride;
for (x = 0; x < width; ++x) {
#ifdef WEBP_SWAP_16BIT_CSP
#if defined(WEBP_SWAP_16BIT_CSP) && (WEBP_SWAP_16BIT_CSP == 1)
const uint32_t rg = rgb565[2 * x + 1];
const uint32_t gb = rgb565[2 * x + 0];
#else
@ -70,24 +72,26 @@ int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
r = r | (r >> 5);
g = g | (g >> 6);
b = b | (b >> 5);
dst[x] = (r << 16) | (g << 8) | b;
dst[x] = (0xffu << 24) | (r << 16) | (g << 8) | b;
}
rgb565 += 2 * width;
dst += pic->argb_stride;
}
return 1;
}
int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
int x, y;
uint32_t* dst;
if (pic == NULL || rgb4444 == NULL) return 0;
pic->colorspace = WEBP_YUV420;
pic->use_argb = 1;
if (!WebPPictureAlloc(pic)) return 0;
dst = pic->argb;
for (y = 0; y < pic->height; ++y) {
const int width = pic->width;
uint32_t* dst = pic->argb + y * pic->argb_stride;
for (x = 0; x < width; ++x) {
#ifdef WEBP_SWAP_16BIT_CSP
#if defined(WEBP_SWAP_16BIT_CSP) && (WEBP_SWAP_16BIT_CSP == 1)
const uint32_t rg = rgb4444[2 * x + 1];
const uint32_t ba = rgb4444[2 * x + 0];
#else
@ -106,6 +110,7 @@ int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
dst[x] = (a << 24) | (r << 16) | (g << 8) | b;
}
rgb4444 += 2 * width;
dst += pic->argb_stride;
}
return 1;
}
@ -140,3 +145,18 @@ int WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride,
}
//------------------------------------------------------------------------------
int WebPUnmultiplyARGB(WebPPicture* pic) {
int y;
uint32_t* dst;
if (pic == NULL || pic->use_argb != 1 || pic->argb == NULL) return 0;
WebPInitAlphaProcessing();
dst = pic->argb;
for (y = 0; y < pic->height; ++y) {
WebPMultARGBRow(dst, pic->width, /*inverse=*/1);
dst += pic->argb_stride;
}
return 1;
}
//------------------------------------------------------------------------------

View File

@ -19,38 +19,45 @@ extern "C" {
#include "webp/encode.h"
#define WEBP_EXTRAS_ABI_VERSION 0x0001 // MAJOR(8b) + MINOR(8b)
#define WEBP_EXTRAS_ABI_VERSION 0x0002 // MAJOR(8b) + MINOR(8b)
//------------------------------------------------------------------------------
// Returns the version number of the extras library, packed in hexadecimal using
// 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.
WEBP_EXTERN(int) WebPGetExtrasVersion(void);
WEBP_EXTERN int WebPGetExtrasVersion(void);
//------------------------------------------------------------------------------
// Ad-hoc colorspace importers.
// Import luma sample (gray scale image) into 'picture'. The 'picture'
// width and height must be set prior to calling this function.
WEBP_EXTERN(int) WebPImportGray(const uint8_t* gray, WebPPicture* picture);
WEBP_EXTERN int WebPImportGray(const uint8_t* gray, WebPPicture* picture);
// Import rgb sample in RGB565 packed format into 'picture'. The 'picture'
// width and height must be set prior to calling this function.
WEBP_EXTERN(int) WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic);
WEBP_EXTERN int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic);
// Import rgb sample in RGB4444 packed format into 'picture'. The 'picture'
// width and height must be set prior to calling this function.
WEBP_EXTERN(int) WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic);
WEBP_EXTERN int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic);
// Import a color mapped image. The number of colors is less or equal to
// MAX_PALETTE_SIZE. 'pic' must have been initialized. Its content, if any,
// will be discarded. Returns 'false' in case of error, or if indexed[] contains
// invalid indices.
WEBP_EXTERN(int)
WEBP_EXTERN int
WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride,
const uint32_t palette[], int palette_size,
WebPPicture* pic);
// Convert the ARGB content of 'pic' from associated to unassociated.
// 'pic' can be for instance the result of calling of some WebPPictureImportXXX
// functions, with pic->use_argb set to 'true'. It is assumed (and not checked)
// that the pre-multiplied r/g/b values as less or equal than the alpha value.
// Return false in case of error (invalid parameter, ...).
WEBP_EXTERN int WebPUnmultiplyARGB(WebPPicture* pic);
//------------------------------------------------------------------------------
// Parse a bitstream, search for VP8 (lossy) header and report a
@ -59,7 +66,7 @@ WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride,
// Otherwise (lossy bitstream), the returned value is in the range [0..100].
// Any error (invalid bitstream, animated WebP, incomplete header, etc.)
// will return a value of -1.
WEBP_EXTERN(int) VP8EstimateQuality(const uint8_t* const data, size_t size);
WEBP_EXTERN int VP8EstimateQuality(const uint8_t* const data, size_t size);
//------------------------------------------------------------------------------
@ -67,4 +74,4 @@ WEBP_EXTERN(int) VP8EstimateQuality(const uint8_t* const data, size_t size);
} // extern "C"
#endif
#endif /* WEBP_EXTRAS_EXTRAS_H_ */
#endif // WEBP_EXTRAS_EXTRAS_H_

View File

@ -24,8 +24,9 @@
#include <string.h>
#include "webp/encode.h"
#include "../imageio/image_dec.h"
#include "../imageio/imageio_util.h"
#include "imageio/image_dec.h"
#include "imageio/imageio_util.h"
#include "../examples/unicode.h"
static size_t ReadPicture(const char* const filename, WebPPicture* const pic,
int keep_alpha) {
@ -48,7 +49,8 @@ static size_t ReadPicture(const char* const filename, WebPPicture* const pic,
End:
if (!ok) {
fprintf(stderr, "Error! Could not process file %s\n", filename);
WFPRINTF(stderr, "Error! Could not process file %s\n",
(const W_CHAR*)filename);
}
free((void*)data);
return ok ? data_size : 0;
@ -221,10 +223,11 @@ static void Help(void) {
" -o <file> . save the diff map as a WebP lossless file\n"
" -scale .... scale the difference map to fit [0..255] range\n"
" -gray ..... use grayscale for difference map (-scale)\n"
" Also handles PNG, JPG and TIFF files, in addition to WebP.\n");
"\nSupported input formats:\n %s\n",
WebPGetEnabledInputFileFormats());
}
int main(int argc, const char *argv[]) {
int main(int argc, const char* argv[]) {
WebPPicture pic1, pic2;
size_t size1 = 0, size2 = 0;
int ret = 1;
@ -239,9 +242,11 @@ int main(int argc, const char *argv[]) {
const char* name2 = NULL;
const char* output = NULL;
INIT_WARGV(argc, argv);
if (!WebPPictureInit(&pic1) || !WebPPictureInit(&pic2)) {
fprintf(stderr, "Can't init pictures\n");
return 1;
FREE_WARGV_AND_RETURN(1);
}
for (c = 1; c < argc; ++c) {
@ -263,11 +268,11 @@ int main(int argc, const char *argv[]) {
fprintf(stderr, "missing file name after %s option.\n", argv[c - 1]);
goto End;
}
output = argv[c];
output = (const char*)GET_WARGV(argv, c);
} else if (name1 == NULL) {
name1 = argv[c];
name1 = (const char*)GET_WARGV(argv, c);
} else {
name2 = argv[c];
name2 = (const char*)GET_WARGV(argv, c);
}
}
if (help || name1 == NULL || name2 == NULL) {
@ -278,7 +283,7 @@ int main(int argc, const char *argv[]) {
goto End;
}
size1 = ReadPicture(name1, &pic1, 1);
size2 = ReadPicture(name1, &pic2, 1);
size2 = ReadPicture(name2, &pic2, 1);
if (size1 == 0 || size2 == 0) goto End;
if (!keep_alpha) {
@ -290,9 +295,10 @@ int main(int argc, const char *argv[]) {
fprintf(stderr, "Error while computing the distortion.\n");
goto End;
}
printf("%u %.2f %.2f %.2f %.2f %.2f\n",
printf("%u %.2f %.2f %.2f %.2f %.2f [ %.2f bpp ]\n",
(unsigned int)size1,
disto[4], disto[0], disto[1], disto[2], disto[3]);
disto[4], disto[0], disto[1], disto[2], disto[3],
8.f * size1 / pic1.width / pic1.height);
if (output != NULL) {
uint8_t* data = NULL;
@ -322,6 +328,7 @@ int main(int argc, const char *argv[]) {
fprintf(stderr, "Can only compute the difference map in ARGB format.\n");
goto End;
}
#if !defined(WEBP_REDUCE_CSP)
data_size = WebPEncodeLosslessBGRA((const uint8_t*)pic1.argb,
pic1.width, pic1.height,
pic1.argb_stride * 4,
@ -333,11 +340,17 @@ int main(int argc, const char *argv[]) {
ret = ImgIoUtilWriteFile(output, data, data_size) ? 0 : 1;
WebPFree(data);
if (ret) goto End;
#else
(void)data;
(void)data_size;
fprintf(stderr, "Cannot save the difference map. Please recompile "
"without the WEBP_REDUCE_CSP flag.\n");
#endif // WEBP_REDUCE_CSP
}
ret = 0;
End:
WebPPictureFree(&pic1);
WebPPictureFree(&pic2);
return ret;
FREE_WARGV_AND_RETURN(ret);
}

View File

@ -11,7 +11,7 @@
//
// Author: Skal (pascal.massimino@gmail.com)
#include "./extras.h"
#include "extras/extras.h"
#include "webp/decode.h"
#include <math.h>
@ -73,7 +73,7 @@ int VP8EstimateQuality(const uint8_t* const data, size_t size) {
pos += 4;
bit_pos = pos * 8;
GET_BIT(2); // color_space + clamp type
GET_BIT(2); // colorspace + clamp type
// Segment header
if (GET_BIT(1)) { // use_segment_

101
extras/vwebp_sdl.c Normal file
View File

@ -0,0 +1,101 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Simple SDL-based WebP file viewer.
// Does not support animation, just static images.
//
// Press 'q' to exit.
//
// Author: James Zern (jzern@google.com)
#include <stdio.h>
#ifdef HAVE_CONFIG_H
#include "webp/config.h"
#endif
#if defined(WEBP_HAVE_SDL)
#include "webp_to_sdl.h"
#include "webp/decode.h"
#include "imageio/imageio_util.h"
#include "../examples/unicode.h"
#if defined(WEBP_HAVE_JUST_SDL_H)
#include <SDL.h>
#else
#include <SDL/SDL.h>
#endif
static void ProcessEvents(void) {
int done = 0;
SDL_Event event;
while (!done && SDL_WaitEvent(&event)) {
switch (event.type) {
case SDL_KEYUP:
switch (event.key.keysym.sym) {
case SDLK_q: done = 1; break;
default: break;
}
break;
default: break;
}
}
}
int main(int argc, char* argv[]) {
int c;
int ok = 0;
INIT_WARGV(argc, argv);
for (c = 1; c < argc; ++c) {
const char* file = NULL;
const uint8_t* webp = NULL;
size_t webp_size = 0;
if (!strcmp(argv[c], "-h")) {
printf("Usage: %s [-h] image.webp [more_files.webp...]\n", argv[0]);
FREE_WARGV_AND_RETURN(0);
} else {
file = (const char*)GET_WARGV(argv, c);
}
if (file == NULL) continue;
if (!ImgIoUtilReadFile(file, &webp, &webp_size)) {
WFPRINTF(stderr, "Error opening file: %s\n", (const W_CHAR*)file);
goto Error;
}
if (webp_size != (size_t)(int)webp_size) {
free((void*)webp);
fprintf(stderr, "File too large.\n");
goto Error;
}
ok = WebpToSDL((const char*)webp, (int)webp_size);
free((void*)webp);
if (!ok) {
WFPRINTF(stderr, "Error decoding file %s\n", (const W_CHAR*)file);
goto Error;
}
ProcessEvents();
}
ok = 1;
Error:
SDL_Quit();
FREE_WARGV_AND_RETURN(ok ? 0 : 1);
}
#else // !WEBP_HAVE_SDL
int main(int argc, const char* argv[]) {
fprintf(stderr, "SDL support not enabled in %s.\n", argv[0]);
(void)argc;
return 0;
}
#endif

View File

@ -11,28 +11,32 @@
#include <stdlib.h>
#include <string.h>
#include "./extras.h"
#include "../imageio/imageio_util.h"
#include "extras/extras.h"
#include "imageio/imageio_util.h"
#include "../examples/unicode.h"
int main(int argc, const char *argv[]) {
int main(int argc, const char* argv[]) {
int c;
int quiet = 0;
int ok = 1;
INIT_WARGV(argc, argv);
for (c = 1; ok && c < argc; ++c) {
if (!strcmp(argv[c], "-quiet")) {
quiet = 1;
} else if (!strcmp(argv[c], "-help") || !strcmp(argv[c], "-h")) {
printf("webp_quality [-h][-quiet] webp_files...\n");
return 0;
FREE_WARGV_AND_RETURN(0);
} else {
const char* const filename = argv[c];
const char* const filename = (const char*)GET_WARGV(argv, c);
const uint8_t* data = NULL;
size_t data_size = 0;
int q;
ok = ImgIoUtilReadFile(filename, &data, &data_size);
if (!ok) break;
q = VP8EstimateQuality(data, data_size);
if (!quiet) printf("[%s] ", filename);
if (!quiet) WPRINTF("[%s] ", (const W_CHAR*)filename);
if (q < 0) {
fprintf(stderr, "Not a WebP file, or not a lossy WebP file.\n");
ok = 0;
@ -46,5 +50,5 @@ int main(int argc, const char *argv[]) {
free((void*)data);
}
}
return ok ? 0 : 1;
FREE_WARGV_AND_RETURN(ok ? 0 : 1);
}

110
extras/webp_to_sdl.c Normal file
View File

@ -0,0 +1,110 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Simple WebP-to-SDL wrapper. Useful for emscripten.
//
// Author: James Zern (jzern@google.com)
#ifdef HAVE_CONFIG_H
#include "src/webp/config.h"
#endif
#if defined(WEBP_HAVE_SDL)
#include "webp_to_sdl.h"
#include <stdio.h>
#include "src/webp/decode.h"
#if defined(WEBP_HAVE_JUST_SDL_H)
#include <SDL.h>
#else
#include <SDL/SDL.h>
#endif
static int init_ok = 0;
int WebpToSDL(const char* data, unsigned int data_size) {
int ok = 0;
VP8StatusCode status;
WebPDecoderConfig config;
WebPBitstreamFeatures* const input = &config.input;
WebPDecBuffer* const output = &config.output;
SDL_Surface* screen = NULL;
SDL_Surface* surface = NULL;
if (!WebPInitDecoderConfig(&config)) {
fprintf(stderr, "Library version mismatch!\n");
return 0;
}
if (!init_ok) {
SDL_Init(SDL_INIT_VIDEO);
init_ok = 1;
}
status = WebPGetFeatures((uint8_t*)data, (size_t)data_size, &config.input);
if (status != VP8_STATUS_OK) goto Error;
screen = SDL_SetVideoMode(input->width, input->height, 32, SDL_SWSURFACE);
if (screen == NULL) {
fprintf(stderr, "Unable to set video mode (32bpp %dx%d)!\n",
input->width, input->height);
goto Error;
}
surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
input->width, input->height, 32,
0x000000ffu, // R mask
0x0000ff00u, // G mask
0x00ff0000u, // B mask
0xff000000u); // A mask
if (surface == NULL) {
fprintf(stderr, "Unable to create %dx%d RGBA surface!\n",
input->width, input->height);
goto Error;
}
if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface);
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
output->colorspace = MODE_BGRA;
#else
output->colorspace = MODE_RGBA;
#endif
output->width = surface->w;
output->height = surface->h;
output->u.RGBA.rgba = surface->pixels;
output->u.RGBA.stride = surface->pitch;
output->u.RGBA.size = surface->pitch * surface->h;
output->is_external_memory = 1;
status = WebPDecode((const uint8_t*)data, (size_t)data_size, &config);
if (status != VP8_STATUS_OK) {
fprintf(stderr, "Error decoding image (%d)\n", status);
goto Error;
}
if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface);
if (SDL_BlitSurface(surface, NULL, screen, NULL) ||
SDL_Flip(screen)) {
goto Error;
}
ok = 1;
Error:
SDL_FreeSurface(surface);
SDL_FreeSurface(screen);
WebPFreeDecBuffer(output);
return ok;
}
//------------------------------------------------------------------------------
#endif // WEBP_HAVE_SDL

22
extras/webp_to_sdl.h Normal file
View File

@ -0,0 +1,22 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Simple WebP-to-SDL wrapper. Useful for emscripten.
//
// Author: James Zern (jzern@google.com)
#ifndef WEBP_EXTRAS_WEBP_TO_SDL_H_
#define WEBP_EXTRAS_WEBP_TO_SDL_H_
// Exports the method WebpToSDL(const char* data, int data_size) which decodes
// a WebP bitstream into an RGBA SDL surface.
// Return false on failure.
extern int WebpToSDL(const char* data, unsigned int data_size);
#endif // WEBP_EXTRAS_WEBP_TO_SDL_H_

Binary file not shown.

View File

@ -1,6 +1,5 @@
#Thu May 12 17:06:25 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip

65
gradlew vendored
View File

@ -1,4 +1,20 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
@ -28,16 +44,16 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
warn () {
echo "$*"
}
die ( ) {
die () {
echo
echo "$*"
echo
@ -109,8 +125,8 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
@ -138,27 +154,30 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=`save "$@"`
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

190
gradlew.bat vendored
View File

@ -1,90 +1,100 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -25,6 +25,7 @@ LOCAL_SRC_FILES := \
jpegdec.c \
metadata.c \
pngdec.c \
pnmdec.c \
tiffdec.c \
webpdec.c \

View File

@ -1,22 +1,32 @@
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
noinst_LTLIBRARIES = libimageio_util.la libimagedec.la libimageenc.la
noinst_LTLIBRARIES =
noinst_LTLIBRARIES += libimageio_util.la
if BUILD_DEMUX
noinst_LTLIBRARIES += libimagedec.la
endif
noinst_LTLIBRARIES += libimageenc.la
noinst_HEADERS =
noinst_HEADERS += ../src/webp/decode.h
noinst_HEADERS += ../src/webp/types.h
libimageio_util_la_SOURCES = imageio_util.c imageio_util.h
libimageio_util_la_SOURCES =
libimageio_util_la_SOURCES += imageio_util.c imageio_util.h
libimagedec_la_SOURCES = image_dec.c image_dec.h
libimagedec_la_SOURCES =
libimagedec_la_SOURCES += image_dec.c image_dec.h
libimagedec_la_SOURCES += jpegdec.c jpegdec.h
libimagedec_la_SOURCES += metadata.c metadata.h
libimagedec_la_SOURCES += pngdec.c pngdec.h
libimagedec_la_SOURCES += pnmdec.c pnmdec.h
libimagedec_la_SOURCES += tiffdec.c tiffdec.h
libimagedec_la_SOURCES += webpdec.c webpdec.h
libimagedec_la_SOURCES += wicdec.c wicdec.h
libimagedec_la_CPPFLAGS = $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES)
libimagedec_la_CPPFLAGS += $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
libimagedec_la_CPPFLAGS += $(AM_CPPFLAGS)
libimagedec_la_LIBADD = ../src/demux/libwebpdemux.la
libimageenc_la_SOURCES = image_enc.c image_enc.h
libimageenc_la_SOURCES =
libimageenc_la_SOURCES += image_enc.c image_enc.h
libimageenc_la_CPPFLAGS = $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES)
libimageenc_la_CPPFLAGS += $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
libimageenc_la_CPPFLAGS += $(AM_CPPFLAGS)

View File

@ -11,6 +11,24 @@
#include "./image_dec.h"
const char* WebPGetEnabledInputFileFormats(void) {
return "WebP"
#ifdef WEBP_HAVE_JPEG
", JPEG"
#endif
#ifdef WEBP_HAVE_PNG
", PNG"
#endif
", PNM (PGM, PPM, PAM)"
#ifdef WEBP_HAVE_TIFF
", TIFF"
#endif
#ifdef HAVE_WINCODEC_H
", Windows Imaging Component (WIC)"
#endif
"";
}
static WEBP_INLINE uint32_t GetBE32(const uint8_t buf[]) {
return ((uint32_t)buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
}
@ -29,6 +47,10 @@ WebPInputFileFormat WebPGuessImageType(const uint8_t* const data,
format = WEBP_TIFF_FORMAT;
} else if (magic1 == 0x52494646 && magic2 == 0x57454250) {
format = WEBP_WEBP_FORMAT;
} else if (((magic1 >> 24) & 0xff) == 'P') {
const int type = (magic1 >> 16) & 0xff;
// we only support 'P5 -> P7' for now.
if (type >= '5' && type <= '7') format = WEBP_PNM_FORMAT;
}
}
return format;
@ -51,6 +73,7 @@ WebPImageReader WebPGetImageReader(WebPInputFileFormat format) {
case WEBP_JPEG_FORMAT: return ReadJPEG;
case WEBP_TIFF_FORMAT: return ReadTIFF;
case WEBP_WEBP_FORMAT: return ReadWebP;
case WEBP_PNM_FORMAT: return ReadPNM;
default: return FailReader;
}
}

View File

@ -23,6 +23,7 @@
#include "./metadata.h"
#include "./jpegdec.h"
#include "./pngdec.h"
#include "./pnmdec.h"
#include "./tiffdec.h"
#include "./webpdec.h"
#include "./wicdec.h"
@ -36,9 +37,13 @@ typedef enum {
WEBP_JPEG_FORMAT,
WEBP_TIFF_FORMAT,
WEBP_WEBP_FORMAT,
WEBP_PNM_FORMAT,
WEBP_UNSUPPORTED_FORMAT
} WebPInputFileFormat;
// Returns a comma separated list of enabled input formats.
const char* WebPGetEnabledInputFileFormats(void);
// Try to infer the image format. 'data_size' should be larger than 12.
// Returns WEBP_UNSUPPORTED_FORMAT if format can't be guess safely.
WebPInputFileFormat WebPGuessImageType(const uint8_t* const data,

View File

@ -29,11 +29,13 @@
// code with COBJMACROS.
#include <ole2.h> // CreateStreamOnHGlobal()
#include <shlwapi.h>
#include <tchar.h>
#include <windows.h>
#include <wincodec.h>
#endif
#include "./imageio_util.h"
#include "../examples/unicode.h"
//------------------------------------------------------------------------------
// PNG
@ -61,11 +63,12 @@ static HRESULT CreateOutputStream(const char* out_file_name,
// Output to a memory buffer. This is freed when 'stream' is released.
IFS(CreateStreamOnHGlobal(NULL, TRUE, stream));
} else {
IFS(SHCreateStreamOnFileA(out_file_name, STGM_WRITE | STGM_CREATE, stream));
IFS(SHCreateStreamOnFile((const LPTSTR)out_file_name,
STGM_WRITE | STGM_CREATE, stream));
}
if (FAILED(hr)) {
fprintf(stderr, "Error opening output file %s (%08lx)\n",
out_file_name, hr);
_ftprintf(stderr, _T("Error opening output file %s (%08lx)\n"),
(const LPTSTR)out_file_name, hr);
}
return hr;
}
@ -152,20 +155,14 @@ int WebPWritePNG(const char* out_file_name, int use_stdout,
}
#elif defined(WEBP_HAVE_PNG) // !HAVE_WINCODEC_H
static void PNGAPI PNGErrorFunction(png_structp png, png_const_charp dummy) {
(void)dummy; // remove variable-unused warning
static void PNGAPI PNGErrorFunction(png_structp png, png_const_charp unused) {
(void)unused; // remove variable-unused warning
longjmp(png_jmpbuf(png), 1);
}
int WebPWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
const uint32_t width = buffer->width;
const uint32_t height = buffer->height;
png_bytep row = buffer->u.RGBA.rgba;
const int stride = buffer->u.RGBA.stride;
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
volatile png_structp png;
volatile png_infop info;
png_uint_32 y;
if (out_file == NULL || buffer == NULL) return 0;
@ -184,14 +181,23 @@ int WebPWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
return 0;
}
png_init_io(png, out_file);
png_set_IHDR(png, info, width, height, 8,
has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
png_write_info(png, info);
for (y = 0; y < height; ++y) {
png_write_rows(png, &row, 1);
row += stride;
{
const uint32_t width = buffer->width;
const uint32_t height = buffer->height;
png_bytep row = buffer->u.RGBA.rgba;
const int stride = buffer->u.RGBA.stride;
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
uint32_t y;
png_set_IHDR(png, info, width, height, 8,
has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
png_write_info(png, info);
for (y = 0; y < height; ++y) {
png_write_rows(png, &row, 1);
row += stride;
}
}
png_write_end(png, info);
png_destroy_write_struct((png_structpp)&png, (png_infopp)&info);
@ -274,7 +280,7 @@ int WebPWrite16bAsPGM(FILE* fout, const WebPDecBuffer* const buffer) {
}
//------------------------------------------------------------------------------
// BMP
// BMP (see https://en.wikipedia.org/wiki/BMP_file_format#Pixel_storage)
static void PutLE16(uint8_t* const dst, uint32_t value) {
dst[0] = (value >> 0) & 0xff;
@ -287,8 +293,11 @@ static void PutLE32(uint8_t* const dst, uint32_t value) {
}
#define BMP_HEADER_SIZE 54
#define BMP_HEADER_ALPHA_EXTRA_SIZE 16 // for alpha info
int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
const int header_size =
BMP_HEADER_SIZE + (has_alpha ? BMP_HEADER_ALPHA_EXTRA_SIZE : 0);
const uint32_t width = buffer->width;
const uint32_t height = buffer->height;
const uint8_t* rgba = buffer->u.RGBA.rgba;
@ -297,8 +306,9 @@ int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
uint32_t y;
const uint32_t line_size = bytes_per_px * width;
const uint32_t bmp_stride = (line_size + 3) & ~3; // pad to 4
const uint32_t total_size = bmp_stride * height + BMP_HEADER_SIZE;
uint8_t bmp_header[BMP_HEADER_SIZE] = { 0 };
const uint32_t image_size = bmp_stride * height;
const uint32_t total_size = image_size + header_size;
uint8_t bmp_header[BMP_HEADER_SIZE + BMP_HEADER_ALPHA_EXTRA_SIZE] = { 0 };
if (fout == NULL || buffer == NULL || rgba == NULL) return 0;
@ -306,30 +316,37 @@ int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
PutLE16(bmp_header + 0, 0x4d42); // signature 'BM'
PutLE32(bmp_header + 2, total_size); // size including header
PutLE32(bmp_header + 6, 0); // reserved
PutLE32(bmp_header + 10, BMP_HEADER_SIZE); // offset to pixel array
PutLE32(bmp_header + 10, header_size); // offset to pixel array
// bitmap info header
PutLE32(bmp_header + 14, 40); // DIB header size
PutLE32(bmp_header + 14, header_size - 14); // DIB header size
PutLE32(bmp_header + 18, width); // dimensions
PutLE32(bmp_header + 22, -(int)height); // vertical flip!
PutLE32(bmp_header + 22, height); // no vertical flip
PutLE16(bmp_header + 26, 1); // number of planes
PutLE16(bmp_header + 28, bytes_per_px * 8); // bits per pixel
PutLE32(bmp_header + 30, 0); // no compression (BI_RGB)
PutLE32(bmp_header + 34, 0); // image size (dummy)
PutLE32(bmp_header + 30, has_alpha ? 3 : 0); // BI_BITFIELDS or BI_RGB
PutLE32(bmp_header + 34, image_size);
PutLE32(bmp_header + 38, 2400); // x pixels/meter
PutLE32(bmp_header + 42, 2400); // y pixels/meter
PutLE32(bmp_header + 46, 0); // number of palette colors
PutLE32(bmp_header + 50, 0); // important color count
if (has_alpha) { // BITMAPV3INFOHEADER complement
PutLE32(bmp_header + 54, 0x00ff0000); // red mask
PutLE32(bmp_header + 58, 0x0000ff00); // green mask
PutLE32(bmp_header + 62, 0x000000ff); // blue mask
PutLE32(bmp_header + 66, 0xff000000); // alpha mask
}
// TODO(skal): color profile
// write header
if (fwrite(bmp_header, sizeof(bmp_header), 1, fout) != 1) {
if (fwrite(bmp_header, header_size, 1, fout) != 1) {
return 0;
}
// write pixel array
// write pixel array, bottom to top
for (y = 0; y < height; ++y) {
if (fwrite(rgba, line_size, 1, fout) != 1) {
const uint8_t* const src = &rgba[(uint64_t)(height - 1 - y) * stride];
if (fwrite(src, line_size, 1, fout) != 1) {
return 0;
}
// write padding zeroes
@ -339,11 +356,11 @@ int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
return 0;
}
}
rgba += stride;
}
return 1;
}
#undef BMP_HEADER_SIZE
#undef BMP_HEADER_ALPHA_EXTRA_SIZE
//------------------------------------------------------------------------------
// TIFF
@ -361,6 +378,8 @@ int WebPWriteTIFF(FILE* fout, const WebPDecBuffer* const buffer) {
const uint8_t* rgba = buffer->u.RGBA.rgba;
const int stride = buffer->u.RGBA.stride;
const uint8_t bytes_per_px = has_alpha ? 4 : 3;
const uint8_t assoc_alpha =
WebPIsPremultipliedMode(buffer->colorspace) ? 1 : 2;
// For non-alpha case, we omit tag 0x152 (ExtraSamples).
const uint8_t num_ifd_entries = has_alpha ? NUM_IFD_ENTRIES
: NUM_IFD_ENTRIES - 1;
@ -388,7 +407,8 @@ int WebPWriteTIFF(FILE* fout, const WebPDecBuffer* const buffer) {
EXTRA_DATA_OFFSET + 8, 0, 0, 0,
0x1c, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 154: PlanarConfiguration
0x28, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, // 166: ResolutionUnit (inch)
0x52, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 178: ExtraSamples: rgbA
0x52, 0x01, 3, 0, 1, 0, 0, 0,
assoc_alpha, 0, 0, 0, // 178: ExtraSamples: rgbA/RGBA
0, 0, 0, 0, // 190: IFD terminator
// EXTRA_DATA_OFFSET:
8, 0, 8, 0, 8, 0, 8, 0, // BitsPerSample
@ -539,22 +559,26 @@ int WebPWriteYUV(FILE* fout, const WebPDecBuffer* const buffer) {
// Generic top-level call
int WebPSaveImage(const WebPDecBuffer* const buffer,
WebPOutputFileFormat format, const char* const out_file) {
WebPOutputFileFormat format,
const char* const out_file_name) {
FILE* fout = NULL;
int needs_open_file = 1;
const int use_stdout = (out_file != NULL) && !strcmp(out_file, "-");
const int use_stdout =
(out_file_name != NULL) && !WSTRCMP(out_file_name, "-");
int ok = 1;
if (buffer == NULL || out_file == NULL) return 0;
if (buffer == NULL || out_file_name == NULL) return 0;
#ifdef HAVE_WINCODEC_H
needs_open_file = (format != PNG);
#endif
if (needs_open_file) {
fout = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : fopen(out_file, "wb");
fout = use_stdout ? ImgIoUtilSetBinaryMode(stdout)
: WFOPEN(out_file_name, "wb");
if (fout == NULL) {
fprintf(stderr, "Error opening output file %s\n", out_file);
WFPRINTF(stderr, "Error opening output file %s\n",
(const W_CHAR*)out_file_name);
return 0;
}
}
@ -563,7 +587,7 @@ int WebPSaveImage(const WebPDecBuffer* const buffer,
format == RGBA || format == BGRA || format == ARGB ||
format == rgbA || format == bgrA || format == Argb) {
#ifdef HAVE_WINCODEC_H
ok &= WebPWritePNG(out_file, use_stdout, buffer);
ok &= WebPWritePNG(out_file_name, use_stdout, buffer);
#else
ok &= WebPWritePNG(fout, buffer);
#endif

View File

@ -79,7 +79,7 @@ int WebPWriteTIFF(FILE* fout, const struct WebPDecBuffer* const buffer);
int WebPWriteAlphaPlane(FILE* fout, const struct WebPDecBuffer* const buffer);
// Save as YUV samples as PGM format (using IMC4 layout).
// See: http://www.fourcc.org/yuv.php#IMC4.
// See: https://www.fourcc.org/yuv.php#IMC4.
// (very convenient format for viewing the samples, esp. for odd dimensions).
int WebPWritePGM(FILE* fout, const struct WebPDecBuffer* const buffer);

View File

@ -18,6 +18,7 @@
#endif
#include <stdlib.h>
#include <string.h>
#include "../examples/unicode.h"
// -----------------------------------------------------------------------------
// File I/O
@ -47,7 +48,8 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
while (!feof(stdin)) {
// We double the buffer size each time and read as much as possible.
const size_t extra_size = (max_size == 0) ? kBlockSize : max_size;
void* const new_data = realloc(input, max_size + extra_size);
// we allocate one extra byte for the \0 terminator
void* const new_data = realloc(input, max_size + extra_size + 1);
if (new_data == NULL) goto Error;
input = (uint8_t*)new_data;
max_size += extra_size;
@ -55,6 +57,7 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
if (size < max_size) break;
}
if (ferror(stdin)) goto Error;
if (input != NULL) input[size] = '\0'; // convenient 0-terminator
*data = input;
*data_size = size;
return 1;
@ -68,10 +71,10 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
int ImgIoUtilReadFile(const char* const file_name,
const uint8_t** data, size_t* data_size) {
int ok;
void* file_data;
uint8_t* file_data;
size_t file_size;
FILE* in;
const int from_stdin = (file_name == NULL) || !strcmp(file_name, "-");
const int from_stdin = (file_name == NULL) || !WSTRCMP(file_name, "-");
if (from_stdin) return ImgIoUtilReadFromStdin(data, data_size);
@ -79,42 +82,52 @@ int ImgIoUtilReadFile(const char* const file_name,
*data = NULL;
*data_size = 0;
in = fopen(file_name, "rb");
in = WFOPEN(file_name, "rb");
if (in == NULL) {
fprintf(stderr, "cannot open input file '%s'\n", file_name);
WFPRINTF(stderr, "cannot open input file '%s'\n", (const W_CHAR*)file_name);
return 0;
}
fseek(in, 0, SEEK_END);
file_size = ftell(in);
fseek(in, 0, SEEK_SET);
file_data = malloc(file_size);
if (file_data == NULL) return 0;
// we allocate one extra byte for the \0 terminator
file_data = (uint8_t*)WebPMalloc(file_size + 1);
if (file_data == NULL) {
fclose(in);
WFPRINTF(stderr, "memory allocation failure when reading file %s\n",
(const W_CHAR*)file_name);
return 0;
}
ok = (fread(file_data, file_size, 1, in) == 1);
fclose(in);
if (!ok) {
fprintf(stderr, "Could not read %d bytes of data from file %s\n",
(int)file_size, file_name);
free(file_data);
WFPRINTF(stderr, "Could not read %d bytes of data from file %s\n",
(int)file_size, (const W_CHAR*)file_name);
WebPFree(file_data);
return 0;
}
*data = (uint8_t*)file_data;
file_data[file_size] = '\0'; // convenient 0-terminator
*data = file_data;
*data_size = file_size;
return 1;
}
// -----------------------------------------------------------------------------
int ImgIoUtilWriteFile(const char* const file_name,
const uint8_t* data, size_t data_size) {
int ok;
FILE* out;
const int to_stdout = (file_name == NULL) || !strcmp(file_name, "-");
const int to_stdout = (file_name == NULL) || !WSTRCMP(file_name, "-");
if (data == NULL) {
return 0;
}
out = to_stdout ? stdout : fopen(file_name, "wb");
out = to_stdout ? ImgIoUtilSetBinaryMode(stdout) : WFOPEN(file_name, "wb");
if (out == NULL) {
fprintf(stderr, "Error! Cannot open output file '%s'\n", file_name);
WFPRINTF(stderr, "Error! Cannot open output file '%s'\n",
(const W_CHAR*)file_name);
return 0;
}
ok = (fwrite(data, data_size, 1, out) == 1);
@ -135,9 +148,15 @@ void ImgIoUtilCopyPlane(const uint8_t* src, int src_stride,
// -----------------------------------------------------------------------------
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) {
const uint64_t total_size = nmemb * size;
return (total_size == (size_t)total_size);
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t stride, size_t height) {
const uint64_t total_size = stride * height;
int ok = (total_size == (size_t)total_size);
// check that 'stride' is representable as int:
ok = ok && ((uint64_t)(int)stride == stride);
#if defined(WEBP_MAX_IMAGE_SIZE)
ok = ok && (total_size <= (uint64_t)WEBP_MAX_IMAGE_SIZE);
#endif
return ok;
}
// -----------------------------------------------------------------------------

View File

@ -29,7 +29,10 @@ FILE* ImgIoUtilSetBinaryMode(FILE* file);
// Allocates storage for entire file 'file_name' and returns contents and size
// in 'data' and 'data_size'. Returns 1 on success, 0 otherwise. '*data' should
// be deleted using free().
// be deleted using WebPFree().
// Note: for convenience, the data will be null-terminated with an extra byte
// (not accounted for in *data_size), in case the file is text and intended
// to be used as a C-string.
// If 'file_name' is NULL or equal to "-", input is read from stdin by calling
// the function ImgIoUtilReadFromStdin().
int ImgIoUtilReadFile(const char* const file_name,
@ -51,8 +54,8 @@ void ImgIoUtilCopyPlane(const uint8_t* src, int src_stride,
//------------------------------------------------------------------------------
// Returns 0 in case of overflow of nmemb * size.
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t nmemb, size_t size);
// Returns 0 in case of overflow, memory over-allocation or excessive dimension.
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t stride, size_t height);
#ifdef __cplusplus
} // extern "C"

View File

@ -206,6 +206,7 @@ struct my_error_mgr {
static void my_error_exit(j_common_ptr dinfo) {
struct my_error_mgr* myerr = (struct my_error_mgr*)dinfo->err;
fprintf(stderr, "libjpeg error: ");
dinfo->err->output_message(dinfo);
longjmp(myerr->setjmp_buffer, 1);
}
@ -273,7 +274,7 @@ int ReadJPEG(const uint8_t* const data, size_t data_size,
ctx.data = data;
ctx.data_size = data_size;
memset((j_decompress_ptr)&dinfo, 0, sizeof(dinfo)); // for setjmp sanity
memset((j_decompress_ptr)&dinfo, 0, sizeof(dinfo)); // for setjmp safety
dinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
@ -304,18 +305,18 @@ int ReadJPEG(const uint8_t* const data, size_t data_size,
if (stride != (int)stride ||
!ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) {
goto End;
goto Error;
}
rgb = (uint8_t*)malloc((size_t)stride * height);
if (rgb == NULL) {
goto End;
goto Error;
}
buffer[0] = (JSAMPLE*)rgb;
while (dinfo.output_scanline < dinfo.output_height) {
if (jpeg_read_scanlines((j_decompress_ptr)&dinfo, buffer, 1) != 1) {
goto End;
goto Error;
}
buffer[0] += stride;
}
@ -335,7 +336,11 @@ int ReadJPEG(const uint8_t* const data, size_t data_size,
pic->width = width;
pic->height = height;
ok = WebPPictureImportRGB(pic, rgb, (int)stride);
if (!ok) goto Error;
if (!ok) {
pic->width = 0; // WebPPictureImportRGB() barely touches 'pic' on failure.
pic->height = 0; // Just reset dimensions but keep any 'custom_ptr' etc.
MetadataFree(metadata); // In case the caller forgets to free it on error.
}
End:
free(rgb);

View File

@ -18,6 +18,9 @@
#include <stdio.h>
#ifdef WEBP_HAVE_PNG
#ifndef PNG_USER_MEM_SUPPORTED
#define PNG_USER_MEM_SUPPORTED // for png_create_read_struct_2
#endif
#include <png.h>
#include <setjmp.h> // note: this must be included *after* png.h
#include <stdlib.h>
@ -27,11 +30,33 @@
#include "./imageio_util.h"
#include "./metadata.h"
#define LOCAL_PNG_VERSION ((PNG_LIBPNG_VER_MAJOR << 8) | PNG_LIBPNG_VER_MINOR)
#define LOCAL_PNG_PREREQ(maj, min) \
(LOCAL_PNG_VERSION >= (((maj) << 8) | (min)))
static void PNGAPI error_function(png_structp png, png_const_charp error) {
if (error != NULL) fprintf(stderr, "libpng error: %s\n", error);
longjmp(png_jmpbuf(png), 1);
}
#if LOCAL_PNG_PREREQ(1,4)
typedef png_alloc_size_t LocalPngAllocSize;
#else
typedef png_size_t LocalPngAllocSize;
#endif
static png_voidp MallocFunc(png_structp png_ptr, LocalPngAllocSize size) {
(void)png_ptr;
if (size != (size_t)size) return NULL;
if (!ImgIoUtilCheckSizeArgumentsOverflow(size, 1)) return NULL;
return (png_voidp)malloc((size_t)size);
}
static void FreeFunc(png_structp png_ptr, png_voidp ptr) {
(void)png_ptr;
free(ptr);
}
// Converts the NULL terminated 'hexstring' which contains 2-byte character
// representations of hex values to raw data.
// 'hexstring' may contain values consisting of [A-F][a-f][0-9] in pairs,
@ -108,7 +133,7 @@ static const struct {
MetadataPayload* const payload);
size_t storage_offset;
} kPNGMetadataMap[] = {
// http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PNG.html#TextualData
// https://exiftool.org/TagNames/PNG.html#TextualData
// See also: ExifTool on CPAN.
{ "Raw profile type exif", ProcessRawProfile, METADATA_OFFSET(exif) },
{ "Raw profile type xmp", ProcessRawProfile, METADATA_OFFSET(xmp) },
@ -171,11 +196,10 @@ static int ExtractMetadataFromPNG(png_structp png,
{
png_charp name;
int comp_type;
#if ((PNG_LIBPNG_VER_MAJOR << 8) | PNG_LIBPNG_VER_MINOR << 0) < \
((1 << 8) | (5 << 0))
png_charp profile;
#else // >= libpng 1.5.0
#if LOCAL_PNG_PREREQ(1,5)
png_bytep profile;
#else
png_charp profile;
#endif
png_uint_32 len;
@ -185,7 +209,6 @@ static int ExtractMetadataFromPNG(png_structp png,
}
}
}
return 1;
}
@ -225,7 +248,8 @@ int ReadPNG(const uint8_t* const data, size_t data_size,
context.data = data;
context.data_size = data_size;
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
png = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL,
NULL, MallocFunc, FreeFunc);
if (png == NULL) goto End;
png_set_error_fn(png, 0, error_function, NULL);
@ -235,6 +259,15 @@ int ReadPNG(const uint8_t* const data, size_t data_size,
goto End;
}
#if LOCAL_PNG_PREREQ(1,5) || \
(LOCAL_PNG_PREREQ(1,4) && PNG_LIBPNG_VER_RELEASE >= 1)
// If it looks like the bitstream is going to need more memory than libpng's
// internal limit (default: 8M), try to (reasonably) raise it.
if (data_size > png_get_chunk_malloc_max(png) && data_size < (1u << 24)) {
png_set_chunk_malloc_max(png, data_size);
}
#endif
info = png_create_info_struct(png);
if (info == NULL) goto Error;
end_info = png_create_info_struct(png);
@ -265,6 +298,16 @@ int ReadPNG(const uint8_t* const data, size_t data_size,
has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA);
}
// Apply gamma correction if needed.
{
double image_gamma = 1 / 2.2, screen_gamma = 2.2;
int srgb_intent;
if (png_get_sRGB(png, info, &srgb_intent) ||
png_get_gAMA(png, info, &image_gamma)) {
png_set_gamma(png, screen_gamma, image_gamma);
}
}
if (!keep_alpha) {
png_set_strip_alpha(png);
has_alpha = 0;

296
imageio/pnmdec.c Normal file
View File

@ -0,0 +1,296 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// (limited) PNM decoder
#include "./pnmdec.h"
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "webp/encode.h"
#include "./imageio_util.h"
typedef enum {
WIDTH_FLAG = 1 << 0,
HEIGHT_FLAG = 1 << 1,
DEPTH_FLAG = 1 << 2,
MAXVAL_FLAG = 1 << 3,
TUPLE_FLAG = 1 << 4,
ALL_NEEDED_FLAGS = WIDTH_FLAG | HEIGHT_FLAG | DEPTH_FLAG | MAXVAL_FLAG
} PNMFlags;
typedef struct {
const uint8_t* data;
size_t data_size;
int width, height;
int bytes_per_px;
int depth; // 1 (grayscale), 2 (grayscale + alpha), 3 (rgb), 4 (rgba)
int max_value;
int type; // 5, 6 or 7
int seen_flags;
} PNMInfo;
// -----------------------------------------------------------------------------
// PNM decoding
#define MAX_LINE_SIZE 1024
static const size_t kMinPNMHeaderSize = 3;
static size_t ReadLine(const uint8_t* const data, size_t off, size_t data_size,
char out[MAX_LINE_SIZE + 1], size_t* const out_size) {
size_t i = 0;
*out_size = 0;
redo:
for (i = 0; i < MAX_LINE_SIZE && off < data_size; ++i) {
out[i] = data[off++];
if (out[i] == '\n') break;
}
if (off < data_size) {
if (i == 0) goto redo; // empty line
if (out[0] == '#') goto redo; // skip comment
}
out[i] = 0; // safety sentinel
*out_size = i;
return off;
}
static size_t FlagError(const char flag[]) {
fprintf(stderr, "PAM header error: flags '%s' already seen.\n", flag);
return 0;
}
// inspired from http://netpbm.sourceforge.net/doc/pam.html
static size_t ReadPAMFields(PNMInfo* const info, size_t off) {
char out[MAX_LINE_SIZE + 1];
size_t out_size;
int tmp;
int expected_depth = -1;
assert(info != NULL);
while (1) {
off = ReadLine(info->data, off, info->data_size, out, &out_size);
if (off == 0) return 0;
if (sscanf(out, "WIDTH %d", &tmp) == 1) {
if (info->seen_flags & WIDTH_FLAG) return FlagError("WIDTH");
info->seen_flags |= WIDTH_FLAG;
info->width = tmp;
} else if (sscanf(out, "HEIGHT %d", &tmp) == 1) {
if (info->seen_flags & HEIGHT_FLAG) return FlagError("HEIGHT");
info->seen_flags |= HEIGHT_FLAG;
info->height = tmp;
} else if (sscanf(out, "DEPTH %d", &tmp) == 1) {
if (info->seen_flags & DEPTH_FLAG) return FlagError("DEPTH");
info->seen_flags |= DEPTH_FLAG;
info->depth = tmp;
} else if (sscanf(out, "MAXVAL %d", &tmp) == 1) {
if (info->seen_flags & MAXVAL_FLAG) return FlagError("MAXVAL");
info->seen_flags |= MAXVAL_FLAG;
info->max_value = tmp;
} else if (!strcmp(out, "TUPLTYPE RGB_ALPHA")) {
expected_depth = 4;
info->seen_flags |= TUPLE_FLAG;
} else if (!strcmp(out, "TUPLTYPE RGB")) {
expected_depth = 3;
info->seen_flags |= TUPLE_FLAG;
} else if (!strcmp(out, "TUPLTYPE GRAYSCALE_ALPHA")) {
expected_depth = 2;
info->seen_flags |= TUPLE_FLAG;
} else if (!strcmp(out, "TUPLTYPE GRAYSCALE")) {
expected_depth = 1;
info->seen_flags |= TUPLE_FLAG;
} else if (!strcmp(out, "ENDHDR")) {
break;
} else {
static const char kEllipsis[] = " ...";
int i;
if (out_size > 20) sprintf(out + 20 - strlen(kEllipsis), kEllipsis);
for (i = 0; i < (int)strlen(out); ++i) {
// isprint() might trigger a "char-subscripts" warning if given a char.
if (!isprint((int)out[i])) out[i] = ' ';
}
fprintf(stderr, "PAM header error: unrecognized entry [%s]\n", out);
return 0;
}
}
if (!(info->seen_flags & ALL_NEEDED_FLAGS)) {
fprintf(stderr, "PAM header error: missing tags%s%s%s%s\n",
(info->seen_flags & WIDTH_FLAG) ? "" : " WIDTH",
(info->seen_flags & HEIGHT_FLAG) ? "" : " HEIGHT",
(info->seen_flags & DEPTH_FLAG) ? "" : " DEPTH",
(info->seen_flags & MAXVAL_FLAG) ? "" : " MAXVAL");
return 0;
}
if (expected_depth != -1 && info->depth != expected_depth) {
fprintf(stderr, "PAM header error: expected DEPTH %d but got DEPTH %d\n",
expected_depth, info->depth);
return 0;
}
return off;
}
static size_t ReadHeader(PNMInfo* const info) {
size_t off = 0;
char out[MAX_LINE_SIZE + 1];
size_t out_size;
if (info == NULL) return 0;
if (info->data == NULL || info->data_size < kMinPNMHeaderSize) return 0;
info->width = info->height = 0;
info->type = -1;
info->seen_flags = 0;
info->bytes_per_px = 0;
info->depth = 0;
info->max_value = 0;
off = ReadLine(info->data, off, info->data_size, out, &out_size);
if (off == 0 || sscanf(out, "P%d", &info->type) != 1) return 0;
if (info->type == 7) {
off = ReadPAMFields(info, off);
} else {
off = ReadLine(info->data, off, info->data_size, out, &out_size);
if (off == 0 || sscanf(out, "%d %d", &info->width, &info->height) != 2) {
return 0;
}
off = ReadLine(info->data, off, info->data_size, out, &out_size);
if (off == 0 || sscanf(out, "%d", &info->max_value) != 1) return 0;
// finish initializing missing fields
info->depth = (info->type == 5) ? 1 : 3;
}
// perform some basic numerical validation
if (info->width <= 0 || info->height <= 0 ||
info->type <= 0 || info->type >= 9 ||
info->depth <= 0 || info->depth > 4 ||
info->max_value <= 0 || info->max_value >= 65536) {
return 0;
}
info->bytes_per_px = info->depth * (info->max_value > 255 ? 2 : 1);
return off;
}
int ReadPNM(const uint8_t* const data, size_t data_size,
WebPPicture* const pic, int keep_alpha,
struct Metadata* const metadata) {
int ok = 0;
int i, j;
uint64_t stride, pixel_bytes, sample_size, depth;
uint8_t* rgb = NULL, *tmp_rgb;
size_t offset;
PNMInfo info;
info.data = data;
info.data_size = data_size;
offset = ReadHeader(&info);
if (offset == 0) {
fprintf(stderr, "Error parsing PNM header.\n");
goto End;
}
if (info.type < 5 || info.type > 7) {
fprintf(stderr, "Unsupported P%d PNM format.\n", info.type);
goto End;
}
// Some basic validations.
if (pic == NULL) goto End;
if (info.width > WEBP_MAX_DIMENSION || info.height > WEBP_MAX_DIMENSION) {
fprintf(stderr, "Invalid %dx%d dimension for PNM\n",
info.width, info.height);
goto End;
}
pixel_bytes = (uint64_t)info.width * info.height * info.bytes_per_px;
if (data_size < offset + pixel_bytes) {
fprintf(stderr, "Truncated PNM file (P%d).\n", info.type);
goto End;
}
sample_size = (info.max_value > 255) ? 2 : 1;
// final depth
depth = (info.depth == 1 || info.depth == 3 || !keep_alpha) ? 3 : 4;
stride = depth * info.width;
if (stride != (size_t)stride ||
!ImgIoUtilCheckSizeArgumentsOverflow(stride, info.height)) {
goto End;
}
rgb = (uint8_t*)malloc((size_t)stride * info.height);
if (rgb == NULL) goto End;
// Convert input.
// We only optimize for the sample_size=1, max_value=255, depth=1 case.
tmp_rgb = rgb;
for (j = 0; j < info.height; ++j) {
const uint8_t* in = data + offset;
offset += info.bytes_per_px * info.width;
assert(offset <= data_size);
if (info.max_value == 255 && info.depth >= 3) {
// RGB or RGBA
if (info.depth == 3 || keep_alpha) {
memcpy(tmp_rgb, in, info.depth * info.width * sizeof(*in));
} else {
assert(info.depth == 4 && !keep_alpha);
for (i = 0; i < info.width; ++i) {
tmp_rgb[3 * i + 0] = in[4 * i + 0];
tmp_rgb[3 * i + 1] = in[4 * i + 1];
tmp_rgb[3 * i + 2] = in[4 * i + 2];
}
}
} else {
// Unoptimized case, we need to handle non-trivial operations:
// * convert 16b to 8b (if max_value > 255)
// * rescale to [0..255] range (if max_value != 255)
// * drop the alpha channel (if keep_alpha is false)
const uint32_t round = info.max_value / 2;
int k = 0;
for (i = 0; i < info.width * info.depth; ++i) {
uint32_t v = (sample_size == 2) ? 256u * in[2 * i + 0] + in[2 * i + 1]
: in[i];
if (info.max_value != 255) v = (v * 255u + round) / info.max_value;
if (v > 255u) v = 255u;
if (info.depth > 2) {
if (!keep_alpha && info.depth == 4 && (i % 4) == 3) {
// skip alpha
} else {
tmp_rgb[k] = v;
k += 1;
}
} else if (info.depth == 1 || (i % 2) == 0) {
tmp_rgb[k + 0] = tmp_rgb[k + 1] = tmp_rgb[k + 2] = v;
k += 3;
} else if (keep_alpha && info.depth == 2) {
tmp_rgb[k] = v;
k += 1;
} else {
// skip alpha
}
}
}
tmp_rgb += stride;
}
// WebP conversion.
pic->width = info.width;
pic->height = info.height;
ok = (depth == 4) ? WebPPictureImportRGBA(pic, rgb, (int)stride)
: WebPPictureImportRGB(pic, rgb, (int)stride);
if (!ok) goto End;
ok = 1;
End:
free((void*)rgb);
(void)metadata;
(void)keep_alpha;
return ok;
}
// -----------------------------------------------------------------------------

37
imageio/pnmdec.h Normal file
View File

@ -0,0 +1,37 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// partial PNM format decoder (ppm/pgm)
#ifndef WEBP_IMAGEIO_PNMDEC_H_
#define WEBP_IMAGEIO_PNMDEC_H_
#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct Metadata;
struct WebPPicture;
// Reads a PNM file from 'data', returning the decoded output in 'pic'.
// The output is RGB or YUV depending on pic->use_argb value.
// Returns true on success.
// 'metadata' has no effect, but is kept for coherence with other signatures
// for image readers.
int ReadPNM(const uint8_t* const data, size_t data_size,
struct WebPPicture* const pic, int keep_alpha,
struct Metadata* const metadata);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // WEBP_IMAGEIO_PNMDEC_H_

View File

@ -15,6 +15,7 @@
#include "webp/config.h"
#endif
#include <limits.h>
#include <stdio.h>
#include <string.h>
@ -45,7 +46,7 @@ static int ExtractMetadataFromTIFF(TIFF* const tif, Metadata* const metadata) {
(MetadataPayload*)((uint8_t*)metadata +
kTIFFMetadataMap[i].storage_offset);
void* tag_data;
uint32 tag_data_len;
uint32_t tag_data_len;
if (TIFFGetField(tif, kTIFFMetadataMap[i].tag, &tag_data_len, &tag_data) &&
!MetadataCopy((const char*)tag_data, tag_data_len, payload)) {
@ -107,7 +108,7 @@ static void MyUnmapFile(thandle_t opaque, void* base, toff_t size) {
static tsize_t MyRead(thandle_t opaque, void* dst, tsize_t size) {
MyData* const my_data = (MyData*)opaque;
if (my_data->pos + size > my_data->size) {
size = my_data->size - my_data->pos;
size = (tsize_t)(my_data->size - my_data->pos);
}
if (size > 0) {
memcpy(dst, my_data->data + my_data->pos, size);
@ -116,18 +117,58 @@ static tsize_t MyRead(thandle_t opaque, void* dst, tsize_t size) {
return size;
}
// Unmultiply Argb data. Taken from dsp/alpha_processing
// (we don't want to force a dependency to a libdspdec library).
#define MFIX 24 // 24bit fixed-point arithmetic
#define HALF ((1u << MFIX) >> 1)
static uint32_t Unmult(uint8_t x, uint32_t mult) {
const uint32_t v = (x * mult + HALF) >> MFIX;
return (v > 255u) ? 255u : v;
}
static WEBP_INLINE uint32_t GetScale(uint32_t a) {
return (255u << MFIX) / a;
}
#undef MFIX
#undef HALF
static void MultARGBRow(uint8_t* ptr, int width) {
int x;
for (x = 0; x < width; ++x, ptr += 4) {
const uint32_t alpha = ptr[3];
if (alpha < 255) {
if (alpha == 0) { // alpha == 0
ptr[0] = ptr[1] = ptr[2] = 0;
} else {
const uint32_t scale = GetScale(alpha);
ptr[0] = Unmult(ptr[0], scale);
ptr[1] = Unmult(ptr[1], scale);
ptr[2] = Unmult(ptr[2], scale);
}
}
}
}
int ReadTIFF(const uint8_t* const data, size_t data_size,
WebPPicture* const pic, int keep_alpha,
Metadata* const metadata) {
MyData my_data = { data, (toff_t)data_size, 0 };
TIFF* tif;
uint32 width, height;
uint32* raster;
uint32_t image_width, image_height, tile_width, tile_height;
uint64_t stride;
uint16_t samples_per_px = 0;
uint16_t extra_samples = 0;
uint16_t* extra_samples_ptr = NULL;
uint32_t* raster;
int64_t alloc_size;
int ok = 0;
tdir_t dircount;
if (data == NULL || data_size == 0 || pic == NULL) return 0;
if (data == NULL || data_size == 0 || data_size > INT_MAX || pic == NULL) {
return 0;
}
tif = TIFFClientOpen("Memory", "r", &my_data,
MyRead, MyRead, MySeek, MyClose,
@ -143,35 +184,77 @@ int ReadTIFF(const uint8_t* const data, size_t data_size,
"Only the first will be used, %d will be ignored.\n",
dircount - 1);
}
if (!TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_px)) {
fprintf(stderr, "Error! Cannot retrieve TIFF samples-per-pixel info.\n");
goto End;
}
if (!(samples_per_px == 1 || samples_per_px == 3 || samples_per_px == 4)) {
goto End; // not supported
}
if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) &&
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))) {
if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &image_width) &&
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &image_height))) {
fprintf(stderr, "Error! Cannot retrieve TIFF image dimensions.\n");
goto End;
}
if (!ImgIoUtilCheckSizeArgumentsOverflow((uint64_t)width * height,
sizeof(*raster))) {
stride = (uint64_t)image_width * sizeof(*raster);
if (!ImgIoUtilCheckSizeArgumentsOverflow(stride, image_height)) {
fprintf(stderr, "Error! TIFF image dimension (%d x %d) is too large.\n",
image_width, image_height);
goto End;
}
// According to spec, a tile can be bigger than the image. However it should
// be a multiple of 16 and not way too large, so check that it's not more
// than twice the image size, for dimensions above some arbitrary minimum
// 32. We also check that they respect WebP's dimension and memory limit.
// Note that a tile can be 6byte/px in some cases. Here we assume
// 4byte/px with sizeof(*raster), to be conservative.
if (TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width) &&
TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height)) {
if ((tile_width > 32 && tile_width / 2 > image_width) ||
(tile_height > 32 && tile_height / 2 > image_height) ||
!ImgIoUtilCheckSizeArgumentsOverflow(
(uint64_t)tile_width * sizeof(*raster), tile_height)) {
fprintf(stderr, "Error! TIFF tile dimension (%d x %d) is too large.\n",
tile_width, tile_height);
goto End;
}
}
if (samples_per_px > 3 && !TIFFGetField(tif, TIFFTAG_EXTRASAMPLES,
&extra_samples, &extra_samples_ptr)) {
fprintf(stderr, "Error! Cannot retrieve TIFF ExtraSamples info.\n");
goto End;
}
// _Tiffmalloc uses a signed type for size.
alloc_size = (int64_t)((uint64_t)width * height * sizeof(*raster));
alloc_size = (int64_t)(stride * image_height);
if (alloc_size < 0 || alloc_size != (tsize_t)alloc_size) goto End;
raster = (uint32*)_TIFFmalloc((tsize_t)alloc_size);
raster = (uint32_t*)_TIFFmalloc((tsize_t)alloc_size);
if (raster != NULL) {
if (TIFFReadRGBAImageOriented(tif, width, height, raster,
if (TIFFReadRGBAImageOriented(tif, image_width, image_height, raster,
ORIENTATION_TOPLEFT, 1)) {
const int stride = width * sizeof(*raster);
pic->width = width;
pic->height = height;
pic->width = image_width;
pic->height = image_height;
// TIFF data is ABGR
#ifdef WORDS_BIGENDIAN
TIFFSwabArrayOfLong(raster, width * height);
TIFFSwabArrayOfLong(raster, image_width * image_height);
#endif
// if we have an alpha channel, we must un-multiply from rgbA to RGBA
if (extra_samples == 1 && extra_samples_ptr != NULL &&
extra_samples_ptr[0] == EXTRASAMPLE_ASSOCALPHA) {
uint32_t y;
uint8_t* tmp = (uint8_t*)raster;
for (y = 0; y < image_height; ++y) {
MultARGBRow(tmp, image_width);
tmp += stride;
}
}
ok = keep_alpha
? WebPPictureImportRGBA(pic, (const uint8_t*)raster, stride)
: WebPPictureImportRGBX(pic, (const uint8_t*)raster, stride);
? WebPPictureImportRGBA(pic, (const uint8_t*)raster, (int)stride)
: WebPPictureImportRGBX(pic, (const uint8_t*)raster, (int)stride);
}
_TIFFfree(raster);
} else {

View File

@ -9,13 +9,20 @@
//
// WebP decode.
#ifdef HAVE_CONFIG_H
#include "webp/config.h"
#endif
#include "./webpdec.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "webp/decode.h"
#include "webp/demux.h"
#include "webp/encode.h"
#include "../examples/unicode.h"
#include "./imageio_util.h"
#include "./metadata.h"
@ -37,7 +44,7 @@ static void PrintAnimationWarning(const WebPDecoderConfig* const config) {
}
void PrintWebPError(const char* const in_file, int status) {
fprintf(stderr, "Decoding of %s failed.\n", in_file);
WFPRINTF(stderr, "Decoding of %s failed.\n", (const W_CHAR*)in_file);
fprintf(stderr, "Status: %d", status);
if (status >= VP8_STATUS_OK && status <= VP8_STATUS_NOT_ENOUGH_DATA) {
fprintf(stderr, "(%s)", kStatusMessages[status]);
@ -58,7 +65,7 @@ int LoadWebP(const char* const in_file,
status = WebPGetFeatures(*data, *data_size, bitstream);
if (status != VP8_STATUS_OK) {
free((void*)*data);
WebPFree((void*)*data);
*data = NULL;
*data_size = 0;
PrintWebPError(in_file, status);
@ -88,28 +95,50 @@ VP8StatusCode DecodeWebPIncremental(
{
WebPIDecoder* const idec = WebPIDecode(data, data_size, config);
if (idec == NULL) {
fprintf(stderr, "Failed during WebPINewDecoder().\n");
fprintf(stderr, "Failed during WebPIDecode().\n");
return VP8_STATUS_OUT_OF_MEMORY;
} else {
#ifdef WEBP_EXPERIMENTAL_FEATURES
size_t size = 0;
const size_t incr = 2 + (data_size / 20);
while (size < data_size) {
size_t next_size = size + (rand() % incr);
if (next_size > data_size) next_size = data_size;
status = WebPIUpdate(idec, data, next_size);
if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) break;
size = next_size;
}
#else
status = WebPIUpdate(idec, data, data_size);
#endif
WebPIDelete(idec);
}
}
return status;
}
// -----------------------------------------------------------------------------
// Metadata
static int ExtractMetadata(const uint8_t* const data, size_t data_size,
Metadata* const metadata) {
WebPData webp_data = { data, data_size };
WebPDemuxer* const demux = WebPDemux(&webp_data);
WebPChunkIterator chunk_iter;
uint32_t flags;
if (demux == NULL) return 0;
assert(metadata != NULL);
flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
if ((flags & ICCP_FLAG) && WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter)) {
MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
&metadata->iccp);
WebPDemuxReleaseChunkIterator(&chunk_iter);
}
if ((flags & EXIF_FLAG) && WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) {
MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
&metadata->exif);
WebPDemuxReleaseChunkIterator(&chunk_iter);
}
if ((flags & XMP_FLAG) && WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter)) {
MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
&metadata->xmp);
WebPDemuxReleaseChunkIterator(&chunk_iter);
}
WebPDemuxDelete(demux);
return 1;
}
// -----------------------------------------------------------------------------
int ReadWebP(const uint8_t* const data, size_t data_size,
@ -123,11 +152,6 @@ int ReadWebP(const uint8_t* const data, size_t data_size,
if (data == NULL || data_size == 0 || pic == NULL) return 0;
// TODO(jzern): add Exif/XMP/ICC extraction.
if (metadata != NULL) {
fprintf(stderr, "Warning: metadata extraction from WebP is unsupported.\n");
}
if (!WebPInitDecoderConfig(&config)) {
fprintf(stderr, "Library version mismatch!\n");
return 0;
@ -138,52 +162,82 @@ int ReadWebP(const uint8_t* const data, size_t data_size,
PrintWebPError("input data", status);
return 0;
}
{
do {
const int has_alpha = keep_alpha && bitstream->has_alpha;
uint64_t stride;
pic->width = bitstream->width;
pic->height = bitstream->height;
if (pic->use_argb) {
output_buffer->colorspace = has_alpha ? MODE_RGBA : MODE_RGB;
stride = (uint64_t)bitstream->width * 4;
} else {
output_buffer->colorspace = has_alpha ? MODE_YUVA : MODE_YUV;
stride = (uint64_t)bitstream->width * (has_alpha ? 5 : 3) / 2;
pic->colorspace = has_alpha ? WEBP_YUV420A : WEBP_YUV420;
}
if (!ImgIoUtilCheckSizeArgumentsOverflow(stride, bitstream->height)) {
status = VP8_STATUS_OUT_OF_MEMORY;
break;
}
ok = WebPPictureAlloc(pic);
if (!ok) {
status = VP8_STATUS_OUT_OF_MEMORY;
break;
}
if (pic->use_argb) {
#ifdef WORDS_BIGENDIAN
output_buffer->colorspace = MODE_ARGB;
#else
output_buffer->colorspace = MODE_BGRA;
#endif
output_buffer->u.RGBA.rgba = (uint8_t*)pic->argb;
output_buffer->u.RGBA.stride = pic->argb_stride * sizeof(uint32_t);
output_buffer->u.RGBA.size = output_buffer->u.RGBA.stride * pic->height;
} else {
output_buffer->colorspace = has_alpha ? MODE_YUVA : MODE_YUV;
output_buffer->u.YUVA.y = pic->y;
output_buffer->u.YUVA.u = pic->u;
output_buffer->u.YUVA.v = pic->v;
output_buffer->u.YUVA.a = has_alpha ? pic->a : NULL;
output_buffer->u.YUVA.y_stride = pic->y_stride;
output_buffer->u.YUVA.u_stride = pic->uv_stride;
output_buffer->u.YUVA.v_stride = pic->uv_stride;
output_buffer->u.YUVA.a_stride = has_alpha ? pic->a_stride : 0;
output_buffer->u.YUVA.y_size = pic->height * pic->y_stride;
output_buffer->u.YUVA.u_size = (pic->height + 1) / 2 * pic->uv_stride;
output_buffer->u.YUVA.v_size = (pic->height + 1) / 2 * pic->uv_stride;
output_buffer->u.YUVA.a_size = pic->height * pic->a_stride;
}
output_buffer->is_external_memory = 1;
status = DecodeWebP(data, data_size, &config);
if (status == VP8_STATUS_OK) {
pic->width = output_buffer->width;
pic->height = output_buffer->height;
if (pic->use_argb) {
const uint8_t* const rgba = output_buffer->u.RGBA.rgba;
const int stride = output_buffer->u.RGBA.stride;
ok = has_alpha ? WebPPictureImportRGBA(pic, rgba, stride)
: WebPPictureImportRGB(pic, rgba, stride);
} else {
pic->colorspace = has_alpha ? WEBP_YUV420A : WEBP_YUV420;
ok = WebPPictureAlloc(pic);
if (!ok) {
status = VP8_STATUS_OUT_OF_MEMORY;
} else {
const WebPYUVABuffer* const yuva = &output_buffer->u.YUVA;
const int uv_width = (pic->width + 1) >> 1;
const int uv_height = (pic->height + 1) >> 1;
ImgIoUtilCopyPlane(yuva->y, yuva->y_stride,
pic->y, pic->y_stride, pic->width, pic->height);
ImgIoUtilCopyPlane(yuva->u, yuva->u_stride,
pic->u, pic->uv_stride, uv_width, uv_height);
ImgIoUtilCopyPlane(yuva->v, yuva->v_stride,
pic->v, pic->uv_stride, uv_width, uv_height);
if (has_alpha) {
ImgIoUtilCopyPlane(yuva->a, yuva->a_stride,
pic->a, pic->a_stride, pic->width, pic->height);
}
}
ok = (status == VP8_STATUS_OK);
if (ok && !keep_alpha && pic->use_argb) {
// Need to wipe out the alpha value, as requested.
int x, y;
uint32_t* argb = pic->argb;
for (y = 0; y < pic->height; ++y) {
for (x = 0; x < pic->width; ++x) argb[x] |= 0xff000000u;
argb += pic->argb_stride;
}
}
}
} while (0); // <- so we can 'break' out of the loop
if (status != VP8_STATUS_OK) {
PrintWebPError("input data", status);
ok = 0;
}
WebPFreeDecBuffer(output_buffer);
if (ok && metadata != NULL) {
ok = ExtractMetadata(data, data_size, metadata);
if (!ok) {
PrintWebPError("metadata", VP8_STATUS_BITSTREAM_ERROR);
}
}
if (!ok) WebPPictureFree(pic);
return ok;
}

View File

@ -51,7 +51,7 @@ VP8StatusCode DecodeWebPIncremental(
//------------------------------------------------------------------------------
// Reads a WebP from 'in_file', returning the decoded output in 'pic'.
// Decodes a WebP contained in 'data', returning the decoded output in 'pic'.
// Output is RGBA or YUVA, depending on pic->use_argb value.
// If 'keep_alpha' is true and the WebP has an alpha channel, the output is RGBA
// or YUVA. Otherwise, alpha channel is dropped and output is RGB or YUV.

View File

@ -29,12 +29,14 @@
// code with COBJMACROS.
#include <ole2.h> // CreateStreamOnHGlobal()
#include <shlwapi.h>
#include <tchar.h>
#include <windows.h>
#include <wincodec.h>
#include "webp/encode.h"
#include "../examples/unicode.h"
#include "./imageio_util.h"
#include "./metadata.h"
#include "webp/encode.h"
#define IFS(fn) \
do { \
@ -85,7 +87,7 @@ WEBP_DEFINE_GUID(GUID_WICPixelFormat64bppRGBA_,
static HRESULT OpenInputStream(const char* filename, IStream** stream) {
HRESULT hr = S_OK;
if (!strcmp(filename, "-")) {
if (!WSTRCMP(filename, "-")) {
const uint8_t* data = NULL;
size_t data_size = 0;
const int ok = ImgIoUtilReadFile(filename, &data, &data_size);
@ -108,11 +110,12 @@ static HRESULT OpenInputStream(const char* filename, IStream** stream) {
hr = E_FAIL;
}
} else {
IFS(SHCreateStreamOnFileA(filename, STGM_READ, stream));
IFS(SHCreateStreamOnFile((const LPTSTR)filename, STGM_READ, stream));
}
if (FAILED(hr)) {
fprintf(stderr, "Error opening input file %s (%08lx)\n", filename, hr);
_ftprintf(stderr, _T("Error opening input file %s (%08lx)\n"),
(const LPTSTR)filename, hr);
}
return hr;
}
@ -131,7 +134,10 @@ static HRESULT ExtractICCP(IWICImagingFactory* const factory,
IWICColorContext** color_contexts;
IFS(IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count));
if (FAILED(hr) || count == 0) return hr;
if (FAILED(hr) || count == 0) {
// Treat unsupported operation as a non-fatal error. See crbug.com/webp/506.
return (hr == WINCODEC_ERR_UNSUPPORTEDOPERATION) ? S_OK : hr;
}
color_contexts = (IWICColorContext**)calloc(count, sizeof(*color_contexts));
if (color_contexts == NULL) return E_OUTOFMEMORY;
@ -267,10 +273,15 @@ int ReadPictureWithWIC(const char* const filename,
WICPixelFormatGUID src_pixel_format = GUID_WICPixelFormatUndefined;
const WICFormatImporter* importer = NULL;
GUID src_container_format = GUID_NULL_;
// From Windows Kits\10\Include\10.0.19041.0\um\wincodec.h
WEBP_DEFINE_GUID(GUID_ContainerFormatWebp_,
0xe094b0e2, 0x67f2, 0x45b3,
0xb0, 0xea, 0x11, 0x53, 0x37, 0xca, 0x7c, 0xf3);
static const GUID* kAlphaContainers[] = {
&GUID_ContainerFormatBmp,
&GUID_ContainerFormatPng,
&GUID_ContainerFormatTiff,
&GUID_ContainerFormatWebp_,
NULL
};
int has_alpha = 0;
@ -295,9 +306,15 @@ int ReadPictureWithWIC(const char* const filename,
factory, stream, NULL,
WICDecodeMetadataCacheOnDemand, &decoder));
IFS(IWICBitmapDecoder_GetFrameCount(decoder, &frame_count));
if (SUCCEEDED(hr) && frame_count == 0) {
fprintf(stderr, "No frame found in input file.\n");
hr = E_FAIL;
if (SUCCEEDED(hr)) {
if (frame_count == 0) {
fprintf(stderr, "No frame found in input file.\n");
hr = E_FAIL;
} else if (frame_count > 1) {
// WIC will be tried before native WebP decoding so avoid duplicating the
// error message.
hr = E_FAIL;
}
}
IFS(IWICBitmapDecoder_GetFrame(decoder, 0, &frame));
IFS(IWICBitmapFrameDecode_GetPixelFormat(frame, &src_pixel_format));

106
infra/common.sh Normal file
View File

@ -0,0 +1,106 @@
# Copyright (c) 2021, Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# * Neither the name of Google nor the names of its contributors may
# be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
log_err() {
echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2
}
#######################################
# Create build directory. Build directory will be deleted if it exists.
# Arguments:
# None.
# Returns:
# mkdir result.
#######################################
make_build_dir() {
if [[ "$#" -ne 1 ]]; then
return 1
fi
local build_dir
build_dir="$1"
rm -rf "${build_dir}"
mkdir -p "${build_dir}"
}
#######################################
# Cleanup files from the build directory.
# Globals:
# LIBWEBP_ROOT repository's root path.
# Arguments:
# $1 build directory.
#######################################
cleanup() {
# $1 is not completely removed to allow for binary artifacts to be
# extracted.
find "${1:?"Build directory not defined"}" \
\( -name "*.[ao]" -o -name "*.l[ao]" \) -exec rm -f {} +
}
#######################################
# Setup ccache for toolchain.
# Globals:
# PATH
# Arguments:
# None.
#######################################
setup_ccache() {
if [[ -x "$(command -v ccache)" ]]; then
export CCACHE_CPP2=yes
export PATH="/usr/lib/ccache:${PATH}"
fi
}
#######################################
# Detects whether test block should be run in the current test shard.
# Globals:
# TEST_TOTAL_SHARDS: Valid range: [1, N]. Defaults to 1.
# TEST_SHARD_INDEX: Valid range: [0, TEST_TOTAL_SHARDS). Defaults to 0.
# libwebp_test_id: current test number; incremented with each call.
# Arguments:
# None
# Returns:
# true if the shard is active
# false if the shard is inactive
#######################################
shard_should_run() {
TEST_TOTAL_SHARDS=${TEST_TOTAL_SHARDS:=1}
TEST_SHARD_INDEX=${TEST_SHARD_INDEX:=0}
libwebp_test_id=${libwebp_test_id:=-1}
: $((libwebp_test_id += 1))
if [[ "${TEST_SHARD_INDEX}" -lt 0 ||
"${TEST_SHARD_INDEX}" -ge "${TEST_TOTAL_SHARDS}" ]]; then
log_err "Invalid TEST_SHARD_INDEX (${TEST_SHARD_INDEX})!" \
"Expected [0, ${TEST_TOTAL_SHARDS})."
fi
[[ "$((libwebp_test_id % TEST_TOTAL_SHARDS))" -eq "${TEST_SHARD_INDEX}" ]]
}

401
infra/compile.sh Executable file
View File

@ -0,0 +1,401 @@
#!/bin/bash
# Copyright (c) 2021, Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# * Neither the name of Google nor the names of its contributors may
# be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -xe
LIBWEBP_ROOT="$(realpath "$(dirname "$0")/..")"
WORKSPACE=${WORKSPACE:-"$(mktemp -d -t webp.XXX)"}
# shellcheck source=infra/common.sh
source "${LIBWEBP_ROOT}/infra/common.sh"
usage() {
cat << EOF
Usage: compile.sh BUILD_TYPE TARGET
Options:
BUILD_TYPE supported build type: (shared, static, static-debug)
TARGET supported target platforms:
aarch64-linux-clang
aarch64-linux-gnu
arm-linux-gnueabi
arm-neon-linux-gnueabi
cmake
cmake-aarch64
cmake-arm
cmake-clang
disable-near-lossless
disable-sse4.1
disable-stats
force-aligned-32
force-aligned-64
gradle
i686-linux-asan
i686-linux-clang
i686-linux-gnu
i686-w64-mingw32
mips2el-linux-gnu
mips32dspr2el-linux-gnu
mips32eb-linux-gnu
mips32el-linux-gnu
mips32r2el-linux-gnu
mips32r5el-linux-gnu
mips64r2el-linux-gnu
mips64r6el-linux-gnu
native
reduce-csp
reduce-size
reduce-size-disable-stats
visibility-default-gnu
visibility-hidden-clang
visibility-hidden-gnu
wasm
x86_64-linux-clang
x86_64-linux-gnu
x86_64-linux-msan
x86_64-w64-mingw32
Environment variables:
WORKSPACE directory where the build is done
EOF
}
################################################################################
echo "Building libwebp in ${WORKSPACE}"
if [[ ! -d "${WORKSPACE}" ]]; then
log_err "${WORKSPACE} directory does not exist"
exit 1
fi
BUILD_TYPE=${1:?"Build type not defined.$(
echo
usage
)"}
TARGET=${2:?"Target not defined.$(
echo
usage
)"}
readonly BUILD_DIR="${WORKSPACE}/build-${BUILD_TYPE}"
trap 'cleanup ${BUILD_DIR}' EXIT
make_build_dir "${BUILD_DIR}"
config_flags=()
case "${BUILD_TYPE}" in
shared*) ;; # Valid BUILD_TYPE but no setup required
static*) config_flags+=("--disable-shared") ;;
experimental) config_flags+=("--enable-experimental") ;;
*)
log_err "Invalid BUILD_TYPE"
usage
exit 1
;;
esac
if grep -m 1 -q "enable-asserts" "${LIBWEBP_ROOT}/configure.ac"; then
config_flags+=("--enable-asserts")
fi
case "${TARGET}" in
aarch64-linux-clang)
TARGET="aarch64-linux-gnu"
CC="clang"
CC="${CC} --target=aarch64-linux-gnu"
export CC
export CFLAGS="-isystem /usr/aarch64-linux-gnu/include"
;;
arm-linux-gnueabi)
export CFLAGS="-O3 -march=armv7-a -mfloat-abi=softfp -ftree-vectorize"
;;
arm-neon-linux-gnueabi)
TARGET="arm-linux-gnueabi"
CFLAGS="-O3 -march=armv7-a -mfpu=neon -mfloat-abi=softfp -ftree-vectorize"
export CFLAGS
;;
mips2el-linux-gnu)
export CFLAGS="-EL -O2 -mips2"
TARGET="mipsel-linux-gnu"
;;
mips32el-linux-gnu)
export CFLAGS="-EL -O2 -mips32"
TARGET="mipsel-linux-gnu"
;;
mips32r2el-linux-gnu)
export CFLAGS="-EL -O2 -mips32r2"
TARGET="mipsel-linux-gnu"
;;
mips32dspr2el-linux-gnu)
export CFLAGS="-EL -O2 -mdspr2"
TARGET="mipsel-linux-gnu"
;;
mips32r5el-linux-gnu)
export CFLAGS="-EL -O2 -mips32r5 -mmsa"
TARGET="mipsel-linux-gnu"
;;
mips32eb-linux-gnu)
export CFLAGS="-EB -O2 -mips32"
TARGET="mips-linux-gnu"
;;
mips64r2el-linux-gnu)
export CFLAGS="-EL -O2 -mips64r2 -mabi=64"
TARGET="mips64el-linux-gnuabi64"
;;
mips64r6el-linux-gnu)
export CFLAGS="-EL -O2 -mips64r6 -mabi=64 -mmsa"
TARGET="mips-img-linux-gnu"
;;
i686-linux-gnu)
export CC="gcc -m32"
;;
i686-linux-clang)
TARGET="i686-linux-gnu"
export CC="clang -m32"
;;
i686-linux-asan)
TARGET="i686-linux-gnu"
export CC="clang -m32 -fsanitize=address"
;;
i686-linux-msan)
TARGET="i686-linux-gnu"
export CC="clang -m32 -fsanitize=memory"
;;
x86_64-linux-clang)
TARGET="x86_64-linux-gnu"
export CC=clang
;;
x86_64-linux-msan)
TARGET="x86_64-linux-gnu"
export CC="clang -fsanitize=memory"
;;
force-aligned-32)
config_flags+=("--enable-aligned")
TARGET="i686-linux-gnu"
export CC="gcc -m32"
;;
force-aligned-64)
config_flags+=("--enable-aligned")
TARGET="x86_64-linux-gnu"
;;
visibility-default-*)
export CFLAGS="-O2 -g -fvisibility=default"
TARGET="x86_64-linux-gnu"
;;
visibility-hidden-*)
export CFLAGS="-O2 -g -fvisibility=hidden"
if [[ "${TARGET}" = "visibility-hidden-clang" ]]; then
export CC=clang
fi
TARGET="x86_64-linux-gnu"
;;
disable-sse4.1)
grep "${TARGET}" "${LIBWEBP_ROOT}/configure.ac" || exit 0
config_flags+=("--${TARGET}")
TARGET="x86_64-linux-gnu"
;;
disable-near-lossless)
grep "${TARGET}" "${LIBWEBP_ROOT}/configure.ac" || exit 0
config_flags+=("--${TARGET}")
TARGET="x86_64-linux-gnu"
;;
disable-stats)
git -C "${LIBWEBP_ROOT}" grep WEBP_DISABLE_STATS || exit 0
export CFLAGS="-O2 -g -DWEBP_DISABLE_STATS"
TARGET="x86_64-linux-gnu"
;;
reduce-size)
git -C "${LIBWEBP_ROOT}" grep WEBP_REDUCE_SIZE || exit 0
export CFLAGS="-O2 -g -DWEBP_REDUCE_SIZE"
TARGET="x86_64-linux-gnu"
;;
reduce-size-disable-stats)
git -C "${LIBWEBP_ROOT}" grep -e WEBP_DISABLE_STATS -e WEBP_REDUCE_SIZE \
|| exit 0
export CFLAGS="-O2 -g -DWEBP_DISABLE_STATS -DWEBP_REDUCE_SIZE"
TARGET="x86_64-linux-gnu"
;;
reduce-csp)
git -C "${LIBWEBP_ROOT}" grep WEBP_REDUCE_CSP || exit 0
export CFLAGS="-O2 -g -DWEBP_REDUCE_CSP"
TARGET="x86_64-linux-gnu"
;;
x86_64-linux-gnu | *mingw32 | aarch64*) ;; # Default target configuration
# non-configure based builds
native)
setup_ccache
# exercise makefile.unix then quit
make -C "${LIBWEBP_ROOT}" -f makefile.unix -j all
for tgt in extras examples/anim_diff; do
grep -q -m 1 "${tgt}" "${LIBWEBP_ROOT}/makefile.unix" \
&& make -C "${LIBWEBP_ROOT}" -f makefile.unix -j "${tgt}"
done
[[ -d "${LIBWEBP_ROOT}/tests/fuzzer" ]] \
&& make -j -C "${LIBWEBP_ROOT}/tests/fuzzer" -f makefile.unix
exit 0
;;
cmake*)
setup_ccache
# exercise cmake then quit
opts=()
case "${TARGET}" in
cmake-clang)
opts+=("-DCMAKE_C_COMPILER=clang")
;;
cmake-arm)
opts+=("-DCMAKE_C_COMPILER=arm-linux-gnueabi-gcc")
case "${GERRIT_BRANCH:-}" in
portable-intrinsics | 0.6.1) exit 0 ;;
*) ;; # Skip configuration
esac
;;
cmake-aarch64)
opts+=("-DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc")
case "${GERRIT_BRANCH:-}" in
portable-intrinsics | 0.6.1) exit 0 ;;
*) ;; # Skip configuration
esac
;;
*) ;; # Skip configuration
esac
case "${BUILD_TYPE}" in
static*)
opts+=("-DBUILD_SHARED_LIBS=OFF")
;;
experimental)
opts+=("-DWEBP_EXPERIMENTAL_FEATURES=ON" "-DBUILD_SHARED_LIBS=ON")
;;
*)
opts+=("-DBUILD_SHARED_LIBS=ON")
;;
esac
case "${BUILD_TYPE}" in
*debug) opts+=("-DCMAKE_BUILD_TYPE=Debug") ;;
*) opts+=("-DCMAKE_BUILD_TYPE=RelWithDebInfo") ;;
esac
cd "${BUILD_DIR}"
opts+=("-DWEBP_BUILD_CWEBP=ON" "-DWEBP_BUILD_DWEBP=ON")
grep -m 1 -q WEBP_BUILD_GIF2WEBP "${LIBWEBP_ROOT}/CMakeLists.txt" \
&& opts+=("-DWEBP_BUILD_GIF2WEBP=ON")
grep -m 1 -q WEBP_BUILD_IMG2WEBP "${LIBWEBP_ROOT}/CMakeLists.txt" \
&& opts+=("-DWEBP_BUILD_IMG2WEBP=ON")
cmake "${opts[@]}" "${LIBWEBP_ROOT}"
make VERBOSE=1 -j
case "${BUILD_TYPE}" in
static)
mkdir -p examples
cp [cd]webp examples
;;
*) ;; # Skip configuration.
esac
grep "install" "${LIBWEBP_ROOT}/CMakeLists.txt" || exit 0
make DESTDIR="${BUILD_DIR}/webp-install" install/strip
mkdir tmp
cd tmp
cat > CMakeLists.txt << EOF
cmake_minimum_required(VERSION 2.8.7)
project(libwebp C)
find_package(WebP)
if (NOT WebP_FOUND)
message(FATAL_ERROR "WebP package not found")
endif ()
message("WebP_FOUND: \${WebP_FOUND}")
message("WebP_INCLUDE_DIRS: \${WebP_INCLUDE_DIRS}")
message("WebP_LIBRARIES: \${WebP_LIBRARIES}")
message("WEBP_INCLUDE_DIRS: \${WEBP_INCLUDE_DIRS}")
message("WEBP_LIBRARIES: \${WEBP_LIBRARIES}")
EOF
cmake . "${opts[@]}" \
"-DCMAKE_PREFIX_PATH=${BUILD_DIR}/webp-install/usr/local"
exit 0
;;
gradle)
setup_ccache
# exercise gradle then quit
[[ -f "${LIBWEBP_ROOT}/gradlew" ]] || exit 0
cd "${BUILD_DIR}"
# TODO -g / --gradle-user-home could be used if there's a race between jobs
"${LIBWEBP_ROOT}/gradlew" -p "${LIBWEBP_ROOT}" buildAllExecutables
exit 0
;;
wasm)
grep -m 1 -q WEBP_ENABLE_WASM "${LIBWEBP_ROOT}/CMakeLists.txt" || exit 0
opts+=("-DCMAKE_C_COMPILER=clang" "-DWEBP_ENABLE_WASM=ON")
opts+=("-DWEBP_BUILD_CWEBP=ON" "-DWEBP_BUILD_DWEBP=ON")
case "${BUILD_TYPE}" in
*debug) opts+=("-DCMAKE_BUILD_TYPE=Debug") ;;
*) opts+=("-DCMAKE_BUILD_TYPE=RelWithDebInfo") ;;
esac
cd "${BUILD_DIR}"
cmake "${opts[@]}" "${LIBWEBP_ROOT}"
make VERBOSE=1 -j
mkdir examples
case "${BUILD_TYPE}" in
static)
mkdir -p examples
cp [cd]webp examples
;;
*) ;; # Skip configuration
esac
exit 0
;;
*)
log_err "Invalid TARGET"
usage
exit 1
;;
esac
case "${TARGET}" in
*mingw32) ;; # Skip configuration
*)
case "${TARGET}-${CC}" in
static-debug-gcc* | static-debug-)
CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage -O0 -g"
CXXFLAGS="${CXXFLAGS} -fprofile-arcs -ftest-coverage -O0 -g"
export CFLAGS CXXFLAGS
;;
*) ;; # This case should not be reached.
esac
;;
esac
setup_ccache
cd "${LIBWEBP_ROOT}"
./autogen.sh
cd "${BUILD_DIR}"
"${LIBWEBP_ROOT}/configure" \
--host "${TARGET}" --build "$("${LIBWEBP_ROOT}/config.guess")" \
--enable-everything "${config_flags[@]}"
make -j V=1

224
infra/compile_android.sh Executable file
View File

@ -0,0 +1,224 @@
#!/bin/bash
# Copyright (c) 2021, Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# * Neither the name of Google nor the names of its contributors may
# be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -xe
LIBWEBP_ROOT="$(realpath "$(dirname "$0")/..")"
readonly LIBWEBP_ROOT
readonly WORKSPACE=${WORKSPACE:-"$(mktemp -d -t webp.android.XXX)"}
# shellcheck source=infra/common.sh
source "${LIBWEBP_ROOT}/infra/common.sh"
usage() {
cat << EOF
Usage: $(basename "$0") BUILD_TYPE APP_ABI
Options:
BUILD_TYPE supported build types:
static
static-debug
shared
shared-debug
APP_ABI supported application binary interfaces:
armeabi-v7a
arm64-v8a
x86
x86_64
Environment variables:
WORKSPACE directory where the build is done.
ANDROID_NDK_DIR directory where the android ndk tools are.
EOF
}
################################################################################
echo "Building libwebp for Android in ${WORKSPACE}"
if [[ ! -d "${WORKSPACE}" ]]; then
log_err "${WORKSPACE} directory does not exist."
exit 1
fi
readonly BUILD_TYPE=${1:?"BUILD_TYPE is not defined.$(
echo
usage
)"}
readonly APP_ABI=${2:?"APP_ABI not defined.$(
echo
usage
)"}
readonly ANDROID_NDK_DIR=${ANDROID_NDK_DIR:?"ANDROID_NDK_DIR is not defined.$(
echo
usage
)"}
readonly BUILD_DIR="${WORKSPACE}/build-${BUILD_TYPE}"
readonly STANDALONE_ANDROID_DIR="${WORKSPACE}/android"
if [[ ! -x "${ANDROID_NDK_DIR}/ndk-build" ]]; then
log_err "unable to find ndk-build in ANDROID_NDK_DIR: ${ANDROID_NDK_DIR}."
exit 1
fi
CFLAGS=
LDFLAGS=
opts=()
case "${BUILD_TYPE}" in
*debug)
readonly APP_OPTIM="debug"
CFLAGS="-O0 -g"
opts+=("--enable-asserts")
;;
static* | shared*)
readonly APP_OPTIM="release"
CFLAGS="-O2 -g"
;;
*)
usage
exit 1
;;
esac
case "${BUILD_TYPE}" in
shared*) readonly SHARED="1" ;;
*)
readonly SHARED="0"
CFLAGS="${CFLAGS} -fPIE"
LDFLAGS="${LDFLAGS} -Wl,-pie"
opts+=("--disable-shared")
;;
esac
# Create a fresh build directory
make_build_dir "${BUILD_DIR}"
cd "${BUILD_DIR}"
ln -s "${LIBWEBP_ROOT}" jni
"${ANDROID_NDK_DIR}/ndk-build" -j2 \
APP_ABI="${APP_ABI}" \
APP_OPTIM="${APP_OPTIM}" \
ENABLE_SHARED="${SHARED}"
cd "${LIBWEBP_ROOT}"
./autogen.sh
case "${APP_ABI}" in
armeabi*) arch="arm" ;;
arm64*) arch="arm64" ;;
*) arch="${APP_ABI}" ;;
esac
# TODO(b/185520507): remove this and use the binaries from
# toolchains/llvm/prebuilt/ directly.
rm -rf "${STANDALONE_ANDROID_DIR}"
"${ANDROID_NDK_DIR}/build/tools/make_standalone_toolchain.py" \
--api 24 --arch "${arch}" --stl gnustl --install-dir \
"${STANDALONE_ANDROID_DIR}"
export PATH="${STANDALONE_ANDROID_DIR}/bin:${PATH}"
rm -rf "${BUILD_DIR}"
make_build_dir "${BUILD_DIR}"
cd "${BUILD_DIR}"
case "${arch}" in
arm)
host="arm-linux-androideabi"
case "${APP_ABI}" in
armeabi) ;;
armeabi-v7a)
CFLAGS="${CFLAGS} -march=armv7-a -mfpu=neon -mfloat-abi=softfp"
;;
*) ;; # No configuration needed
esac
;;
arm64)
host="aarch64-linux-android"
;;
x86)
host="i686-linux-android"
;;
x86_64)
host="x86_64-linux-android"
;;
*) ;; # Skip configuration
esac
setup_ccache
CC="clang"
"${LIBWEBP_ROOT}/configure" --host "${host}" --build \
"$("${LIBWEBP_ROOT}/config.guess")" CC="${CC}" CFLAGS="${CFLAGS}" \
LDFLAGS="${LDFLAGS}" "${opts[@]}"
make -j
if [[ "${GERRIT_REFSPEC:-}" = "refs/heads/portable-intrinsics" ]] \
|| [[ "${GERRIT_BRANCH:-}" = "portable-intrinsics" ]]; then
cd "${WORKSPACE}"
rm -rf build && mkdir build
cd build
standalone="${WORKSPACE}/android"
cmake ../libwebp \
-DWEBP_BUILD_DWEBP=1 \
-DCMAKE_C_COMPILER="${standalone}/bin/clang" \
-DCMAKE_PREFIX_PATH="${standalone}/sysroot/usr/lib" \
-DCMAKE_C_FLAGS=-fPIE \
-DCMAKE_EXE_LINKER_FLAGS=-Wl,-pie \
-DCMAKE_BUILD_TYPE=Release \
-DWEBP_ENABLE_WASM=1
make -j2
cd "${WORKSPACE}"
make_build_dir "${BUILD_DIR}"
cd "${BUILD_DIR}"
case "${APP_ABI}" in
armeabi-v7a | arm64*)
cmake "${LIBWEBP_ROOT}" \
-DWEBP_BUILD_DWEBP=1 \
-DCMAKE_C_COMPILER="${standalone}/bin/clang" \
-DCMAKE_PREFIX_PATH="${standalone}/sysroot/usr/lib" \
-DCMAKE_C_FLAGS='-fPIE -DENABLE_NEON_BUILTIN_MULHI_INT16X8' \
-DCMAKE_EXE_LINKER_FLAGS=-Wl,-pie \
-DCMAKE_BUILD_TYPE=Release \
-DWEBP_ENABLE_WASM=1
make -j2
;;
x86*)
cmake "${LIBWEBP_ROOT}" \
-DWEBP_BUILD_DWEBP=1 \
-DCMAKE_C_COMPILER="${standalone}/bin/clang" \
-DCMAKE_PREFIX_PATH="${standalone}/sysroot/usr/lib" \
-DCMAKE_C_FLAGS='-fPIE -DENABLE_X86_BUILTIN_MULHI_INT16X8' \
-DCMAKE_EXE_LINKER_FLAGS=-Wl,-pie \
-DCMAKE_BUILD_TYPE=Release \
-DWEBP_ENABLE_WASM=1
make -j2
;;
*)
log_err "APP_ABI not supported."
exit 1
;;
esac
fi

75
infra/compile_js.sh Executable file
View File

@ -0,0 +1,75 @@
#!/bin/bash
# Copyright (c) 2021, Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# * Neither the name of Google nor the names of its contributors may
# be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -ex
readonly WORKSPACE="${WORKSPACE:-"$(mktemp -d -t webp.js.XXX)"}"
readonly BUILD_DIR="${WORKSPACE}/webp_js/"
readonly LIBWEBP_ROOT="$(realpath "$(dirname "$0")/..")"
# shellcheck source=infra/common.sh
source "${LIBWEBP_ROOT}/infra/common.sh"
usage() {
cat << EOF
Usage: $(basename "$0")
Environment variables:
WORKSPACE directory where the build is done
EMSDK_DIR directory where emsdk is installed
EOF
}
[[ -d "${EMSDK_DIR:?Not defined}" ]] \
|| (log_err "${EMSDK_DIR} is not a valid directory." && exit 1)
# shellcheck source=/opt/emsdk/emsdk_env.sh
source "${EMSDK_DIR}/emsdk_env.sh"
readonly EMSCRIPTEN=${EMSCRIPTEN:-"${EMSDK}/upstream/emscripten"}
readonly \
EMSCRIPTEN_CMAKE_FILE="${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake"
make_build_dir "${BUILD_DIR}"
pushd "${BUILD_DIR}"
opts=("-GUnix Makefiles" "-DWEBP_BUILD_WEBP_JS=ON")
if [[ -z "$(command -v emcmake)" ]]; then
opts+=("-DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN_CMAKE_FILE}")
cmake \
"${opts[@]}" \
"${LIBWEBP_ROOT}"
make -j
else
emcmake cmake \
"${opts[@]}" \
"${LIBWEBP_ROOT}"
emmake make -j
fi
popd

98
infra/run_static_analysis.sh Executable file
View File

@ -0,0 +1,98 @@
#!/bin/bash
# Copyright (c) 2021, Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# * Neither the name of Google nor the names of its contributors may
# be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -xe
LIBWEBP_ROOT="$(realpath "$(dirname "$0")/..")"
readonly LIBWEBP_ROOT
readonly WORKSPACE=${WORKSPACE:-"$(mktemp -d -t webp.scanbuild.XXX)"}
# shellcheck source=infra/common.sh
source "${LIBWEBP_ROOT}/infra/common.sh"
usage() {
cat << EOF
Usage: $(basename "$0") MODE
Options:
MODE supported scan modes: (shallow|deep)
Environment variables:
WORKSPACE directory where the build is done.
EOF
}
#######################################
# Wrap clang-tools scan-build.
# Globals:
# OUTPUT_DIR target directory where scan-build report is generated.
# MODE scan-build mode
# Arguments:
# $* scan-build additional args.
# Returns:
# scan-build retcode
#######################################
scan_build() {
scan-build -o "${OUTPUT_DIR}" --use-analyzer="$(command -v clang)" \
-analyzer-config mode="${MODE}" "$*"
}
MODE=${1:?"MODE is not specified.$(
echo
usage
)"}
readonly OUTPUT_DIR="${WORKSPACE}/output-${MODE}"
readonly BUILD_DIR="${WORKSPACE}/build"
make_build_dir "${OUTPUT_DIR}"
make_build_dir "${BUILD_DIR}"
cd "${LIBWEBP_ROOT}"
./autogen.sh
cd "${BUILD_DIR}"
grep -m 1 -q 'enable-asserts' "${LIBWEBP_ROOT}/configure.ac" \
&& args='--enable-asserts'
scan_build "${LIBWEBP_ROOT}/configure" --enable-everything "${args}"
scan_build make -j4
index="$(find "${OUTPUT_DIR}" -name index.html)"
if [[ -f "${index}" ]]; then
mv "$(dirname "${index}")/"* "${OUTPUT_DIR}"
else
# make a empty report to wipe out any old bug reports.
cat << EOT > "${OUTPUT_DIR}/index.html"
<html>
<body>
No bugs reported.
</body>
</html>
EOT
fi

View File

@ -1,17 +1,21 @@
#!/bin/bash
#
# This script generates 'WebP.framework' and 'WebPDecoder.framework'. An iOS
# app can decode WebP images by including 'WebPDecoder.framework' and both
# encode and decode WebP images by including 'WebP.framework'.
# This script generates 'WebP.framework' and 'WebPDecoder.framework',
# 'WebPDemux.framework' and 'WebPMux.framework'.
# An iOS app can decode WebP images by including 'WebPDecoder.framework' and
# both encode and decode WebP images by including 'WebP.framework'.
#
# Run ./iosbuild.sh to generate the frameworks under the current directory
# (the previous build will be erased if it exists).
#
# This script is inspired by the build script written by Carson McDonald.
# (http://www.ioncannon.net/programming/1483/using-webp-to-reduce-native-ios-app-size/).
# (https://www.ioncannon.net/programming/1483/using-webp-to-reduce-native-ios-app-size/).
set -e
# Set this variable based on the desired minimum deployment target.
readonly IOS_MIN_VERSION=6.0
# Extract the latest SDK version from the final field of the form: iphoneosX.Y
readonly SDK=$(xcodebuild -showsdks \
| grep iphoneos | sort | tail -n 1 | awk '{print substr($NF, 9)}'
@ -35,35 +39,55 @@ readonly TOPDIR=$(pwd)
readonly BUILDDIR="${TOPDIR}/iosbuild"
readonly TARGETDIR="${TOPDIR}/WebP.framework"
readonly DECTARGETDIR="${TOPDIR}/WebPDecoder.framework"
readonly MUXTARGETDIR="${TOPDIR}/WebPMux.framework"
readonly DEMUXTARGETDIR="${TOPDIR}/WebPDemux.framework"
readonly DEVELOPER=$(xcode-select --print-path)
readonly PLATFORMSROOT="${DEVELOPER}/Platforms"
readonly LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
LIBLIST=''
DECLIBLIST=''
MUXLIBLIST=''
DEMUXLIBLIST=''
if [[ -z "${SDK}" ]]; then
echo "iOS SDK not available"
exit 1
elif [[ ${SDK%%.*} -gt 8 ]]; then
EXTRA_CFLAGS="-fembed-bitcode"
elif [[ ${SDK} < 6.0 ]]; then
elif [[ ${SDK%%.*} -le 6 ]]; then
echo "You need iOS SDK version 6.0 or above"
exit 1
else
echo "iOS SDK Version ${SDK}"
fi
rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR}
mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/Headers/
echo "Xcode Version: ${XCODE}"
echo "iOS SDK Version: ${SDK}"
if [[ -e "${BUILDDIR}" || -e "${TARGETDIR}" || -e "${DECTARGETDIR}" \
|| -e "${MUXTARGETDIR}" || -e "${DEMUXTARGETDIR}" ]]; then
cat << EOF
WARNING: The following directories will be deleted:
WARNING: ${BUILDDIR}
WARNING: ${TARGETDIR}
WARNING: ${DECTARGETDIR}
WARNING: ${MUXTARGETDIR}
WARNING: ${DEMUXTARGETDIR}
WARNING: The build will continue in 5 seconds...
EOF
sleep 5
fi
rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR} \
${MUXTARGETDIR} ${DEMUXTARGETDIR}
mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/Headers/ \
${MUXTARGETDIR}/Headers/ ${DEMUXTARGETDIR}/Headers/
if [[ ! -e ${SRCDIR}/configure ]]; then
if ! (cd ${SRCDIR} && sh autogen.sh); then
cat <<EOT
cat << EOF
Error creating configure script!
This script requires the autoconf/automake and libtool to build. MacPorts can
be used to obtain these:
http://www.macports.org/install.php
EOT
https://www.macports.org/install.php
EOF
exit 1
fi
fi
@ -97,7 +121,7 @@ for PLATFORM in ${PLATFORMS}; do
SDKROOT="${PLATFORMSROOT}/"
SDKROOT+="${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDK}.sdk/"
CFLAGS="-arch ${ARCH2:-${ARCH}} -pipe -isysroot ${SDKROOT} -O3 -DNDEBUG"
CFLAGS+=" -miphoneos-version-min=6.0 ${EXTRA_CFLAGS}"
CFLAGS+=" -miphoneos-version-min=${IOS_MIN_VERSION} ${EXTRA_CFLAGS}"
set -x
export PATH="${DEVROOT}/usr/bin:${OLDPATH}"
@ -105,25 +129,40 @@ for PLATFORM in ${PLATFORMS}; do
--build=$(${SRCDIR}/config.guess) \
--disable-shared --enable-static \
--enable-libwebpdecoder --enable-swap-16bit-csp \
--enable-libwebpmux \
CFLAGS="${CFLAGS}"
set +x
# run make only in the src/ directory to create libwebp.a/libwebpdecoder.a
cd src/
make V=0
make install
# Build only the libraries, skip the examples.
make V=0 -C sharpyuv
make V=0 -C src install
LIBLIST+=" ${ROOTDIR}/lib/libwebp.a"
DECLIBLIST+=" ${ROOTDIR}/lib/libwebpdecoder.a"
MUXLIBLIST+=" ${ROOTDIR}/lib/libwebpmux.a"
DEMUXLIBLIST+=" ${ROOTDIR}/lib/libwebpdemux.a"
make clean
cd ..
export PATH=${OLDPATH}
done
echo "LIBLIST = ${LIBLIST}"
cp -a ${SRCDIR}/src/webp/{decode,encode,types}.h ${TARGETDIR}/Headers/
${LIPO} -create ${LIBLIST} -output ${TARGETDIR}/WebP
echo "DECLIBLIST = ${DECLIBLIST}"
cp -a ${SRCDIR}/src/webp/{decode,types}.h ${DECTARGETDIR}/Headers/
${LIPO} -create ${DECLIBLIST} -output ${DECTARGETDIR}/WebPDecoder
echo "MUXLIBLIST = ${MUXLIBLIST}"
cp -a ${SRCDIR}/src/webp/{types,mux,mux_types}.h \
${MUXTARGETDIR}/Headers/
${LIPO} -create ${MUXLIBLIST} -output ${MUXTARGETDIR}/WebPMux
echo "DEMUXLIBLIST = ${DEMUXLIBLIST}"
cp -a ${SRCDIR}/src/webp/{decode,types,mux_types,demux}.h \
${DEMUXTARGETDIR}/Headers/
${LIPO} -create ${DEMUXLIBLIST} -output ${DEMUXTARGETDIR}/WebPDemux
echo "SUCCESS"

View File

@ -25,16 +25,29 @@ ifeq ($(strip $(shell uname)), Darwin)
# Failure observed with: gcc 4.2.1 and 4.0.1.
EXTRA_FLAGS += -fno-common
EXTRA_FLAGS += -DHAVE_GLUT_GLUT_H
EXTRA_FLAGS += -Wno-deprecated-declarations
EXTRA_FLAGS += -I/opt/local/include
EXTRA_LIBS += -L/opt/local/lib
GL_LIBS = -framework GLUT -framework OpenGL
else
EXTRA_FLAGS += -I/usr/local/include
EXTRA_LIBS += -L/usr/local/lib
GL_LIBS = -lglut -lGL
endif
# SDL flags: use sdl-config if it exists
SDL_CONFIG = $(shell sdl-config --version 2> /dev/null)
ifneq ($(SDL_CONFIG),)
SDL_LIBS = $(shell sdl-config --libs)
SDL_FLAGS = $(shell sdl-config --cflags)
else
# use best-guess
SDL_LIBS = -lSDL
SDL_FLAGS =
endif
# To install libraries on Mac OS X:
# 1. Install MacPorts (http://www.macports.org/install.php)
# 1. Install MacPorts (https://www.macports.org/install.php)
# 2. Run "sudo port install jpeg"
# 3. Run "sudo port install libpng"
# 4. Run "sudo port install tiff"
@ -51,11 +64,8 @@ endif
# 'make -f makefile.unix EXTRA_FLAGS=-m32' to that effect.
# EXTRA_FLAGS += -m32
# Extra flags to enable experimental features and code
# EXTRA_FLAGS += -DWEBP_EXPERIMENTAL_FEATURES
# Extra flags to enable byte swap for 16 bit colorspaces.
# EXTRA_FLAGS += -DWEBP_SWAP_16BIT_CSP
# EXTRA_FLAGS += -DWEBP_SWAP_16BIT_CSP=1
# Extra flags to enable multi-threading
EXTRA_FLAGS += -DWEBP_USE_THREAD
@ -79,12 +89,6 @@ EXTRA_FLAGS += -DWEBP_HAVE_SSE41
src/dsp/%_sse41.o: EXTRA_FLAGS += -msse4.1
endif
# AVX2-specific flags:
ifeq ($(HAVE_AVX2), 1)
EXTRA_FLAGS += -DWEBP_HAVE_AVX2
src/dsp/%_avx2.o: EXTRA_FLAGS += -mavx2
endif
# NEON-specific flags:
# EXTRA_FLAGS += -march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8
# -> seems to make the overall lib slower: -fno-split-wide-types
@ -101,17 +105,34 @@ endif
AR = ar
ARFLAGS = r
CPPFLAGS = -Isrc/ -Wall
CFLAGS = -O3 -DNDEBUG $(EXTRA_FLAGS)
CPPFLAGS = -I. -Isrc/ -Wall
ifeq ($(DEBUG), 1)
CFLAGS = -g
else
CFLAGS = -O3 -DNDEBUG
endif
CFLAGS += $(EXTRA_FLAGS)
CC = gcc
INSTALL = install
GROFF = /usr/bin/groff
COL = /usr/bin/col
LDFLAGS = $(EXTRA_LIBS) $(EXTRA_FLAGS) -lm
ifdef BITTRACE
CFLAGS += -DBITTRACE=$(BITTRACE)
endif
ANIM_UTIL_OBJS = \
examples/anim_util.o \
SHARPYUV_OBJS = \
sharpyuv/sharpyuv.o \
sharpyuv/sharpyuv_csp.o \
sharpyuv/sharpyuv_dsp.o \
sharpyuv/sharpyuv_gamma.o \
sharpyuv/sharpyuv_neon.o \
sharpyuv/sharpyuv_sse2.o \
DEC_OBJS = \
src/dec/alpha_dec.o \
src/dec/buffer_dec.o \
@ -153,6 +174,7 @@ DSP_DEC_OBJS = \
src/dsp/lossless_msa.o \
src/dsp/lossless_neon.o \
src/dsp/lossless_sse2.o \
src/dsp/lossless_sse41.o \
src/dsp/rescaler.o \
src/dsp/rescaler_mips32.o \
src/dsp/rescaler_mips_dsp_r2.o \
@ -164,21 +186,21 @@ DSP_DEC_OBJS = \
src/dsp/upsampling_msa.o \
src/dsp/upsampling_neon.o \
src/dsp/upsampling_sse2.o \
src/dsp/upsampling_sse41.o \
src/dsp/yuv.o \
src/dsp/yuv_mips32.o \
src/dsp/yuv_mips_dsp_r2.o \
src/dsp/yuv_neon.o \
src/dsp/yuv_sse2.o \
src/dsp/yuv_sse41.o \
DSP_ENC_OBJS = \
src/dsp/argb.o \
src/dsp/argb_mips_dsp_r2.o \
src/dsp/argb_sse2.o \
src/dsp/cost.o \
src/dsp/cost_mips32.o \
src/dsp/cost_mips_dsp_r2.o \
src/dsp/cost_neon.o \
src/dsp/cost_sse2.o \
src/dsp/enc.o \
src/dsp/enc_avx2.o \
src/dsp/enc_mips32.o \
src/dsp/enc_mips_dsp_r2.o \
src/dsp/enc_msa.o \
@ -192,14 +214,16 @@ DSP_ENC_OBJS = \
src/dsp/lossless_enc_neon.o \
src/dsp/lossless_enc_sse2.o \
src/dsp/lossless_enc_sse41.o \
src/dsp/ssim.o \
src/dsp/ssim_sse2.o \
ENC_OBJS = \
src/enc/alpha_enc.o \
src/enc/analysis_enc.o \
src/enc/backward_references_cost_enc.o \
src/enc/backward_references_enc.o \
src/enc/config_enc.o \
src/enc/cost_enc.o \
src/enc/delta_palettization_enc.o \
src/enc/filter_enc.o \
src/enc/frame_enc.o \
src/enc/histogram_enc.o \
@ -223,6 +247,7 @@ EX_FORMAT_DEC_OBJS = \
imageio/jpegdec.o \
imageio/metadata.o \
imageio/pngdec.o \
imageio/pnmdec.o \
imageio/tiffdec.o \
imageio/webpdec.o \
@ -265,8 +290,8 @@ EXTRA_OBJS = \
extras/quality_estimate.o \
LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS)
LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) $(DSP_ENC_OBJS) \
$(UTILS_ENC_OBJS)
LIBWEBP_OBJS = $(SHARPYUV_OBJS) $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) \
$(DSP_ENC_OBJS) $(UTILS_ENC_OBJS)
LIBWEBPMUX_OBJS = $(MUX_OBJS)
LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS)
LIBWEBPEXTRA_OBJS = $(EXTRA_OBJS)
@ -287,6 +312,7 @@ HDRS = \
src/dec/vp8li_dec.h \
src/dec/webpi_dec.h \
src/dsp/common_sse2.h \
src/dsp/cpu.h \
src/dsp/dsp.h \
src/dsp/lossless.h \
src/dsp/lossless_common.h \
@ -296,7 +322,6 @@ HDRS = \
src/dsp/yuv.h \
src/enc/backward_references_enc.h \
src/enc/cost_enc.h \
src/enc/delta_palettization_enc.h \
src/enc/histogram_enc.h \
src/enc/vp8i_enc.h \
src/enc/vp8li_enc.h \
@ -328,8 +353,9 @@ OUT_LIBS += src/libwebp.a
EXTRA_LIB = extras/libwebpextras.a
OUT_EXAMPLES = examples/cwebp examples/dwebp
EXTRA_EXAMPLES = examples/gif2webp examples/vwebp examples/webpmux \
examples/anim_diff examples/img2webp
OTHER_EXAMPLES = extras/get_disto extras/webp_quality
examples/anim_diff examples/anim_dump \
examples/img2webp examples/webpinfo
OTHER_EXAMPLES = extras/get_disto extras/webp_quality extras/vwebp_sdl
OUTPUT = $(OUT_LIBS) $(OUT_EXAMPLES)
ifeq ($(MAKECMDGOALS),clean)
@ -356,7 +382,7 @@ src/utils/bit_reader_utils.o: src/utils/endian_inl_utils.h
src/utils/bit_writer_utils.o: src/utils/endian_inl_utils.h
%.o: %.c $(HDRS)
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
examples/libanim_util.a: $(ANIM_UTIL_OBJS)
examples/libexample_util.a: $(EX_UTIL_OBJS)
@ -374,52 +400,76 @@ src/demux/libwebpdemux.a: $(LIBWEBPDEMUX_OBJS)
$(AR) $(ARFLAGS) $@ $^
examples/anim_diff: examples/anim_diff.o $(ANIM_UTIL_OBJS) $(GIFDEC_OBJS)
examples/anim_dump: examples/anim_dump.o $(ANIM_UTIL_OBJS) $(GIFDEC_OBJS)
examples/cwebp: examples/cwebp.o
examples/dwebp: examples/dwebp.o
examples/gif2webp: examples/gif2webp.o $(GIFDEC_OBJS)
examples/vwebp: examples/vwebp.o
examples/webpmux: examples/webpmux.o
examples/img2webp: examples/img2webp.o
examples/webpinfo: examples/webpinfo.o
examples/anim_diff: examples/libanim_util.a examples/libgifdec.a
examples/anim_diff: src/demux/libwebpdemux.a examples/libexample_util.a
examples/anim_diff: imageio/libimageio_util.a src/libwebp.a
examples/anim_diff: EXTRA_LIBS += $(GIF_LIBS)
examples/anim_diff: override EXTRA_LIBS += $(GIF_LIBS)
examples/anim_diff: EXTRA_FLAGS += -DWEBP_HAVE_GIF
examples/anim_dump: examples/libanim_util.a examples/libgifdec.a
examples/anim_dump: src/demux/libwebpdemux.a
examples/anim_dump: examples/libexample_util.a
examples/anim_dump: imageio/libimageio_util.a
examples/anim_dump: imageio/libimageenc.a
examples/anim_dump: src/libwebp.a
examples/anim_dump: override EXTRA_LIBS += $(GIF_LIBS) $(DWEBP_LIBS)
examples/cwebp: examples/libexample_util.a
examples/cwebp: imageio/libimagedec.a
examples/cwebp: src/demux/libwebpdemux.a
examples/cwebp: imageio/libimageio_util.a
examples/cwebp: src/libwebp.a
examples/cwebp: EXTRA_LIBS += $(CWEBP_LIBS)
examples/cwebp: override EXTRA_LIBS += $(CWEBP_LIBS)
examples/dwebp: examples/libexample_util.a
examples/dwebp: imageio/libimagedec.a
examples/dwebp: src/demux/libwebpdemux.a
examples/dwebp: imageio/libimageenc.a
examples/dwebp: imageio/libimageio_util.a
examples/dwebp: src/libwebp.a
examples/dwebp: EXTRA_LIBS += $(DWEBP_LIBS)
examples/dwebp: override EXTRA_LIBS += $(DWEBP_LIBS)
examples/gif2webp: examples/libexample_util.a imageio/libimageio_util.a
examples/gif2webp: examples/libgifdec.a src/mux/libwebpmux.a src/libwebp.a
examples/gif2webp: EXTRA_LIBS += $(GIF_LIBS)
examples/gif2webp: override EXTRA_LIBS += $(GIF_LIBS)
examples/gif2webp: EXTRA_FLAGS += -DWEBP_HAVE_GIF
examples/vwebp: examples/libexample_util.a src/demux/libwebpdemux.a
examples/vwebp: imageio/libimageio_util.a src/libwebp.a
examples/vwebp: EXTRA_LIBS += $(GL_LIBS)
examples/vwebp: override EXTRA_LIBS += $(GL_LIBS)
examples/vwebp: EXTRA_FLAGS += -DWEBP_HAVE_GL
examples/webpmux: examples/libexample_util.a imageio/libimageio_util.a
examples/webpmux: src/mux/libwebpmux.a src/libwebpdecoder.a
examples/img2webp: examples/libexample_util.a imageio/libimageio_util.a
examples/img2webp: imageio/libimagedec.a
examples/img2webp: src/demux/libwebpdemux.a
examples/img2webp: src/mux/libwebpmux.a src/libwebp.a
examples/img2webp: EXTRA_LIBS += $(CWEBP_LIBS)
examples/img2webp: override EXTRA_LIBS += $(CWEBP_LIBS)
examples/webpinfo: examples/libexample_util.a imageio/libimageio_util.a
examples/webpinfo: src/libwebpdecoder.a
extras/get_disto: extras/get_disto.o
extras/get_disto: imageio/libimagedec.a imageio/libimageio_util.a src/libwebp.a
extras/get_disto: EXTRA_LIBS += $(CWEBP_LIBS)
extras/get_disto: imageio/libimagedec.a
extras/get_disto: src/demux/libwebpdemux.a
extras/get_disto: imageio/libimageio_util.a
extras/get_disto: src/libwebp.a
extras/get_disto: override EXTRA_LIBS += $(CWEBP_LIBS)
extras/webp_quality: extras/webp_quality.o
extras/webp_quality: imageio/libimageio_util.a
extras/webp_quality: $(EXTRA_LIB) src/libwebp.a
extras/vwebp_sdl: extras/vwebp_sdl.o
extras/vwebp_sdl: extras/webp_to_sdl.o
extras/vwebp_sdl: imageio/libimageio_util.a
extras/vwebp_sdl: src/libwebp.a
extras/vwebp_sdl: EXTRA_FLAGS += -DWEBP_HAVE_SDL $(SDL_FLAGS)
extras/vwebp_sdl: override EXTRA_LIBS += $(SDL_LIBS)
$(OUT_EXAMPLES) $(EXTRA_EXAMPLES) $(OTHER_EXAMPLES):
$(CC) -o $@ $^ $(LDFLAGS)
@ -435,9 +485,9 @@ dist: all
$(INSTALL) -m644 src/mux/libwebpmux.a $(DESTDIR)/lib
umask 022; \
for m in man/[cdv]webp.1 man/gif2webp.1 man/webpmux.1 \
man/img2webp.1; do \
man/img2webp.1 man/webpinfo.1; do \
basenam=$$(basename $$m .1); \
$(GROFF) -t -e -man -T utf8 $$m \
$(GROFF) -t -e -man -T ascii $$m \
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.txt; \
$(GROFF) -t -e -man -T html $$m \
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.html; \
@ -448,6 +498,7 @@ clean:
examples/*.o examples/*~ \
extras/*.o extras/*~ \
imageio/*.o imageio/*~ \
sharpyuv/*.o sharpyuv/*~ \
src/dec/*.o src/dec/*~ \
src/demux/*.o src/demux/*~ \
src/dsp/*.o src/dsp/*~ \

View File

@ -1,11 +1,17 @@
man_MANS = cwebp.1 dwebp.1
if WANT_MUX
if BUILD_MUX
man_MANS += webpmux.1
endif
if BUILD_GIF2WEBP
man_MANS += gif2webp.1
endif
if BUILD_IMG2WEBP
man_MANS += img2webp.1
endif
if BUILD_VWEBP
man_MANS += vwebp.1
endif
if BUILD_WEBPINFO
man_MANS += webpinfo.1
endif
EXTRA_DIST = $(man_MANS)

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH CWEBP 1 "January 20, 2017"
.TH CWEBP 1 "March 17, 2022"
.SH NAME
cwebp \- compress an image file to a WebP file
.SH SYNOPSIS
@ -13,6 +13,7 @@ command.
.PP
\fBcwebp\fP compresses an image using the WebP format.
Input format can be either PNG, JPEG, TIFF, WebP or raw Y'CbCr samples.
Note: Animated PNG and WebP files are not supported.
.SH OPTIONS
The basic options are:
.TP
@ -41,10 +42,12 @@ the invisible pixel values (R/G/B or Y/U/V) will be preserved only if the
\-exact option is used.
.TP
.BI \-near_lossless " int
Use near\-lossless image preprocessing. This option adjusts pixel values
to help compressibility, but has minimal impact on the visual quality.
It triggers lossless compression mode automatically.
Range is 0 (maximum preprocessing) to 100 (no preprocessing, the default).
Specify the level of near\-lossless image preprocessing. This option adjusts
pixel values to help compressibility, but has minimal impact on the visual
quality. It triggers lossless compression mode automatically. The range is 0
(maximum preprocessing) to 100 (no preprocessing, the default). The typical
value is around 60. Note that lossy with \fB\-q 100\fP can at times yield
better results.
.TP
.BI \-q " float
Specify the compression factor for RGB channels between 0 and 100. The default
@ -87,19 +90,20 @@ additional encoding possibilities and decide on the quality gain.
Lower value can result in faster processing time at the expense of
larger file size and lower compression quality.
.TP
.BI \-resize " width height
Resize the source to a rectangle with size \fBwidth\fP x \fBheight\fP.
If either (but not both) of the \fBwidth\fP or \fBheight\fP parameters is 0,
the value will be calculated preserving the aspect\-ratio.
.TP
.BI \-crop " x_position y_position width height
Crop the source to a rectangle with top\-left corner at coordinates
(\fBx_position\fP, \fBy_position\fP) and size \fBwidth\fP x \fBheight\fP.
This cropping area must be fully contained within the source rectangle.
Note: the cropping is applied \fIbefore\fP any scaling.
.TP
.BI \-resize " width height
Resize the source to a rectangle with size \fBwidth\fP x \fBheight\fP.
If either (but not both) of the \fBwidth\fP or \fBheight\fP parameters is 0,
the value will be calculated preserving the aspect\-ratio. Note: scaling
is applied \fIafter\fP cropping.
.TP
.B \-mt
Use multi\-threading for encoding, if possible. This option is only effective
when using lossy compression on a source with a transparency channel.
Use multi\-threading for encoding, if possible.
.TP
.B \-low_memory
Reduce memory usage of lossy encoding by saving four times the compressed
@ -133,6 +137,13 @@ options \fB\-size\fP or \fB\-psnr\fP. Maximum value is 10, default is 1.
If options \fB\-size\fP or \fB\-psnr\fP were used, but \fB\-pass\fP wasn't
specified, a default value of '6' passes will be used.
.TP
.BI \-qrange " int int
Specifies the permissible interval for the quality factor. This is particularly
useful when using multi-pass (\fB\-size\fP or \fB\-psnr\fP options).
Default is 0 100.
If the quality factor is outside this range, it will be clamped.
If the minimum value must be less or equal to the maximum one.
.TP
.B \-af
Turns auto\-filter on. This algorithm will spend additional time optimizing
the filtering strength to reach a well\-balanced quality.
@ -213,7 +224,7 @@ Compute and report average PSNR (Peak\-Signal\-To\-Noise ratio).
.TP
.B \-print_ssim
Compute and report average SSIM (structural similarity
metric, see http://en.wikipedia.org/wiki/SSIM for additional details).
metric, see https://en.wikipedia.org/wiki/SSIM for additional details).
.TP
.B \-print_lsim
Compute and report local similarity metric (sum of lowest error amongst the
@ -289,7 +300,7 @@ Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
.br
Patches welcome! See this page to get started:
http://www.webmproject.org/code/contribute/submitting\-patches/
https://www.webmproject.org/code/contribute/submitting\-patches/
.SH EXAMPLES
cwebp \-q 50 -lossless picture.png \-o picture_lossless.webp
@ -313,5 +324,5 @@ for the Debian project (and may be used by others).
.BR dwebp (1),
.BR gif2webp (1)
.br
Please refer to http://developers.google.com/speed/webp/ for additional
Please refer to https://developers.google.com/speed/webp/ for additional
information.

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH DWEBP 1 "June 23, 2016"
.TH DWEBP 1 "November 17, 2021"
.SH NAME
dwebp \- decompress a WebP file to an image file
.SH SYNOPSIS
@ -12,6 +12,7 @@ This manual page documents the
command.
.PP
\fBdwebp\fP decompresses WebP files into PNG, PAM, PPM or PGM images.
Note: Animated WebP files are not supported.
.SH OPTIONS
The basic options are:
.TP
@ -112,7 +113,7 @@ Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
.br
Patches welcome! See this page to get started:
http://www.webmproject.org/code/contribute/submitting-patches/
https://www.webmproject.org/code/contribute/submitting\-patches/
.SH EXAMPLES
dwebp picture.webp \-o output.png
@ -137,7 +138,7 @@ for the Debian project (and may be used by others).
.BR gif2webp (1),
.BR webpmux (1)
.br
Please refer to http://developers.google.com/speed/webp/ for additional
Please refer to https://developers.google.com/speed/webp/ for additional
information.
.SS Output file format details
PAM: http://netpbm.sourceforge.net/doc/pam.html

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH GIF2WEBP 1 "January 25, 2017"
.TH GIF2WEBP 1 "November 17, 2021"
.SH NAME
gif2webp \- Convert a GIF image to WebP
.SH SYNOPSIS
@ -20,6 +20,12 @@ Specify the name of the output WebP file. If omitted, \fBgif2webp\fP will
perform conversion but only report statistics.
Using "\-" as output name will direct output to 'stdout'.
.TP
.BI \-\- " string
Explicitly specify the input file. This option is useful if the input
file starts with an '\-' for instance. This option must appear \fBlast\fP.
Any other options afterward will be ignored. If the input file is "\-",
the data will be read from \fIstdin\fP instead of a file.
.TP
.B \-h, \-help
Usage information.
.TP
@ -56,9 +62,9 @@ larger file size and lower compression quality.
.TP
.BI \-min_size
Encode image to achieve smallest size. This disables key frame insertion and
picks the dispose method resulting in smallest output for each frame. It uses
lossless compression by default, but can be combined with \-q, \-m, \-lossy or
\-mixed options.
picks the dispose method resulting in the smallest output for each frame. It
uses lossless compression by default, but can be combined with \-q, \-m,
\-lossy or \-mixed options.
.TP
.BI \-kmin " int
.TP
@ -108,8 +114,11 @@ the value the smoother the picture will appear. Typical values are usually in
the range of 20 to 50.
.TP
.B \-mt
Use multi-threading for encoding, if possible. This option is only effective
when using lossy compression.
Use multi-threading for encoding, if possible.
.TP
.B \-loop_compatibility
If enabled, handle the loop information in a compatible fashion for Chrome
version prior to M62 (inclusive) and Firefox.
.TP
.B \-v
Print extra information.
@ -122,7 +131,7 @@ Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
.br
Patches welcome! See this page to get started:
http://www.webmproject.org/code/contribute/submitting-patches/
https://www.webmproject.org/code/contribute/submitting\-patches/
.SH EXAMPLES
gif2webp picture.gif \-o picture.webp
@ -134,6 +143,8 @@ gif2webp \-lossy \-m 3 picture.gif \-o picture_lossy.webp
gif2webp \-lossy \-f 50 picture.gif \-o picture.webp
.br
gif2webp \-q 70 \-o picture.webp \-\- \-\-\-picture.gif
.br
cat picture.gif | gif2webp \-o \- \-\- \- > output.webp
.SH AUTHORS
\fBgif2webp\fP is a part of libwebp and was written by the WebP team.
@ -149,5 +160,5 @@ Debian project (and may be used by others).
.BR dwebp (1),
.BR webpmux (1)
.br
Please refer to http://developers.google.com/speed/webp/ for additional
Please refer to https://developers.google.com/speed/webp/ for additional
information.

View File

@ -1,10 +1,12 @@
.\" Hey, EMACS: -*- nroff -*-
.TH IMG2WEBP 1 "January 23, 2017"
.TH IMG2WEBP 1 "January 5, 2022"
.SH NAME
img2webp \- create animated WebP file from a sequence of input images.
.SH SYNOPSIS
.B img2webp
[file_level_options] [files] [per_frame_options...]
[file_options] [[frame_options] frame_file]...
.br
.B img2webp argument_file_name
.br
.SH DESCRIPTION
This manual page documents the
@ -13,6 +15,9 @@ command.
.PP
\fBimg2webp\fP compresses a sequence of images using the animated WebP format.
Input images can either be PNG, JPEG, TIFF or WebP.
If a single file name (not starting with the character '\-') is supplied as
the argument, the command line arguments are actually tokenized from this file.
This allows for easy scripting or using a large number of arguments.
.SH FILE-LEVEL OPTIONS
The file-level options are applied at the beginning of the compression process,
before the input frames are read.
@ -22,7 +27,7 @@ Specify the name of the output WebP file.
.TP
.BI \-min_size
Encode images to achieve smallest size. This disables key frame insertion and
picks the parameters resulting in smallest output for each frame. It uses
picks the parameters resulting in the smallest output for each frame. It uses
lossless compression by default, but can be combined with \-q, \-m, \-lossy or
\-mixed options.
.TP
@ -40,14 +45,17 @@ lossy or lossless compression for each frame heuristically. This global
option disables the local option \fB-lossy\fP and \fB-lossless\fP .
.TP
.BI \-loop " int
Specifies the number of times the animation should loop. Using '0' means
'loop indefinitely'.
Specifies the number of times the animation should loop. Using '0'
means 'loop indefinitely'.
.TP
.BI \-v
Be more verbose.
.TP
.B \-h, \-help
A short usage summary.
.TP
.B \-version
Print the version numbers of the relevant libraries used.
.SH PER-FRAME OPTIONS
The per-frame options are applied for the images following as arguments in the
@ -78,7 +86,7 @@ Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
.br
Patches welcome! See this page to get started:
http://www.webmproject.org/code/contribute/submitting\-patches/
https://www.webmproject.org/code/contribute/submitting\-patches/
.SH AUTHORS
\fBimg2webp\fP is a part of libwebp and was written by the WebP team.
@ -93,5 +101,5 @@ for the Debian project (and may be used by others).
.BR webpmux (1),
.BR gif2webp (1)
.br
Please refer to http://developers.google.com/speed/webp/ for additional
Please refer to https://developers.google.com/speed/webp/ for additional
information.

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH VWEBP 1 "November 25, 2016"
.TH VWEBP 1 "November 17, 2021"
.SH NAME
vwebp \- decompress a WebP file and display it in a window
.SH SYNOPSIS
@ -38,6 +38,10 @@ It helps by smoothing gradients and avoiding banding artifacts. Default: 50.
By default, quantized transparency planes are dithered during decompression,
to smooth the gradients. This flag will prevent this dithering.
.TP
.B \-usebgcolor
Fill transparent areas with the bitstream's own background color instead of
checkerboard only. Default is white for non-animated images.
.TP
.B \-mt
Use multi-threading for decoding, if possible.
.TP
@ -56,6 +60,9 @@ the data will be read from \fIstdin\fP instead of a file.
.B 'c'
Toggle use of color profile.
.TP
.B 'b'
Toggle display of background color.
.TP
.B 'i'
Overlay file information.
.TP
@ -70,7 +77,7 @@ Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
.br
Patches welcome! See this page to get started:
http://www.webmproject.org/code/contribute/submitting-patches/
https://www.webmproject.org/code/contribute/submitting\-patches/
.SH EXAMPLES
vwebp picture.webp
@ -90,5 +97,5 @@ This manual page was written for the Debian project (and may be used by others).
.SH SEE ALSO
.BR dwebp (1)
.br
Please refer to http://developers.google.com/speed/webp/ for additional
Please refer to https://developers.google.com/speed/webp/ for additional
information.

80
man/webpinfo.1 Normal file
View File

@ -0,0 +1,80 @@
.\" Hey, EMACS: -*- nroff -*-
.TH WEBPINFO 1 "November 17, 2021"
.SH NAME
webpinfo \- print out the chunk level structure of WebP files
along with basic integrity checks.
.SH SYNOPSIS
.B webpinfo
.I OPTIONS
.I INPUT
.br
.B webpinfo [\-h|\-help|\-H|\-longhelp]
.br
.SH DESCRIPTION
This manual page documents the
.B webpinfo
command.
.PP
\fBwebpinfo\fP can be used to print out the chunk level structure and bitstream
header information of WebP files. It can also check if the files are of valid
WebP format.
.SH OPTIONS
.TP
.B \-version
Print the version number (as major.minor.revision) and exit.
.TP
.B \-quiet
Do not show chunk parsing information.
.TP
.B \-diag
Show parsing error diagnosis.
.TP
.B \-summary
Show chunk stats summary.
.TP
.BI \-bitstream_info
Parse bitstream header.
.TP
.B \-h, \-help
A short usage summary.
.TP
.B \-H, \-longhelp
Detailed usage instructions.
.SH INPUT
Input files in WebP format. Input files must come last, following
options (if any). There can be multiple input files.
.SH BUGS
Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
.br
Patches welcome! See this page to get started:
https://www.webmproject.org/code/contribute/submitting\-patches/
.SH EXAMPLES
.br
webpinfo \-h
.br
webpinfo \-diag \-summary input_file.webp
.br
webpinfo \-bitstream_info input_file_1.webp input_file_2.webp
.br
webpinfo *.webp
.SH AUTHORS
\fBwebpinfo\fP is a part of libwebp and was written by the WebP team.
.br
The latest source tree is available at
https://chromium.googlesource.com/webm/libwebp
.PP
This manual page was written by Hui Su <huisu@google.com>,
for the Debian project (and may be used by others).
.SH SEE ALSO
.BR webpmux (1)
.br
Please refer to https://developers.google.com/speed/webp/ for additional
information.

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH WEBPMUX 1 "November 10, 2016"
.TH WEBPMUX 1 "November 17, 2021"
.SH NAME
webpmux \- create animated WebP files from non\-animated WebP images, extract
frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
@ -48,6 +48,8 @@ frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
.B webpmux [\-h|\-help]
.br
.B webpmux \-version
.br
.B webpmux argument_file_name
.SH DESCRIPTION
This manual page documents the
.B webpmux
@ -55,6 +57,9 @@ command.
.PP
\fBwebpmux\fP can be used to create/extract from animated WebP files, as well as
to add/extract/strip XMP/EXIF metadata and ICC profile.
If a single file name (not starting with the character '\-') is supplied as
the argument, the command line arguments are actually tokenized from this file.
This allows for easy scripting or using a large number of arguments.
.SH OPTIONS
.SS GET_OPTIONS (\-get):
.TP
@ -72,6 +77,17 @@ Get nth frame from an animated image. (n = 0 has a special meaning: last frame).
.SS SET_OPTIONS (\-set)
.TP
.BI loop " loop_count
Set loop count on an animated file.
.P
Where: 'loop_count' must be in range [0, 65535].
.TP
.BI bgcolor " A,R,G,B
Set the background color of the canvas on an animated file.
.P
where: 'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying the
Alpha, Red, Green and Blue component values respectively.
.TP
.BI icc " file.icc
Set ICC profile.
.P
@ -175,7 +191,7 @@ Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
.br
Patches welcome! See this page to get started:
http://www.webmproject.org/code/contribute/submitting\-patches/
https://www.webmproject.org/code/contribute/submitting\-patches/
.SH EXAMPLES
.P
@ -251,5 +267,5 @@ for the Debian project (and may be used by others).
.BR dwebp (1),
.BR gif2webp (1)
.br
Please refer to http://developers.google.com/speed/webp/ for additional
Please refer to https://developers.google.com/speed/webp/ for additional
information.

34
sharpyuv/Makefile.am Normal file
View File

@ -0,0 +1,34 @@
AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
noinst_LTLIBRARIES =
noinst_LTLIBRARIES += libsharpyuv.la
noinst_LTLIBRARIES += libsharpyuv_sse2.la
noinst_LTLIBRARIES += libsharpyuv_neon.la
noinst_HEADERS =
noinst_HEADERS += ../src/webp/types.h
noinst_HEADERS += ../src/dsp/cpu.h
libsharpyuv_sse2_la_SOURCES =
libsharpyuv_sse2_la_SOURCES += sharpyuv_sse2.c
libsharpyuv_sse2_la_CPPFLAGS = $(libsharpyuv_la_CPPFLAGS)
libsharpyuv_sse2_la_CFLAGS = $(AM_CFLAGS) $(SSE2_FLAGS)
libsharpyuv_neon_la_SOURCES =
libsharpyuv_neon_la_SOURCES += sharpyuv_neon.c
libsharpyuv_neon_la_CPPFLAGS = $(libsharpyuv_la_CPPFLAGS)
libsharpyuv_neon_la_CFLAGS = $(AM_CFLAGS) $(NEON_FLAGS)
libsharpyuv_la_SOURCES =
libsharpyuv_la_SOURCES += sharpyuv_csp.c sharpyuv_csp.h
libsharpyuv_la_SOURCES += sharpyuv_dsp.c sharpyuv_dsp.h
libsharpyuv_la_SOURCES += sharpyuv_gamma.c sharpyuv_gamma.h
libsharpyuv_la_SOURCES += sharpyuv.c sharpyuv.h
libsharpyuv_la_CPPFLAGS = $(AM_CPPFLAGS)
libsharpyuv_la_LDFLAGS =
libsharpyuv_la_LIBADD =
libsharpyuv_la_LIBADD += libsharpyuv_sse2.la
libsharpyuv_la_LIBADD += libsharpyuv_neon.la
noinst_PROGRAMS =

498
sharpyuv/sharpyuv.c Normal file
View File

@ -0,0 +1,498 @@
// Copyright 2022 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Sharp RGB to YUV conversion.
//
// Author: Skal (pascal.massimino@gmail.com)
#include "sharpyuv/sharpyuv.h"
#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "src/webp/types.h"
#include "src/dsp/cpu.h"
#include "sharpyuv/sharpyuv_dsp.h"
#include "sharpyuv/sharpyuv_gamma.h"
//------------------------------------------------------------------------------
// Sharp RGB->YUV conversion
static const int kNumIterations = 4;
#define YUV_FIX 16 // fixed-point precision for RGB->YUV
static const int kYuvHalf = 1 << (YUV_FIX - 1);
// Max bit depth so that intermediate calculations fit in 16 bits.
static const int kMaxBitDepth = 14;
// Returns the precision shift to use based on the input rgb_bit_depth.
static int GetPrecisionShift(int rgb_bit_depth) {
// Try to add 2 bits of precision if it fits in kMaxBitDepth. Otherwise remove
// bits if needed.
return ((rgb_bit_depth + 2) <= kMaxBitDepth) ? 2
: (kMaxBitDepth - rgb_bit_depth);
}
typedef int16_t fixed_t; // signed type with extra precision for UV
typedef uint16_t fixed_y_t; // unsigned type with extra precision for W
//------------------------------------------------------------------------------
static uint8_t clip_8b(fixed_t v) {
return (!(v & ~0xff)) ? (uint8_t)v : (v < 0) ? 0u : 255u;
}
static uint16_t clip(fixed_t v, int max) {
return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
}
static fixed_y_t clip_bit_depth(int y, int bit_depth) {
const int max = (1 << bit_depth) - 1;
return (!(y & ~max)) ? (fixed_y_t)y : (y < 0) ? 0 : max;
}
//------------------------------------------------------------------------------
static int RGBToGray(int64_t r, int64_t g, int64_t b) {
const int64_t luma = 13933 * r + 46871 * g + 4732 * b + kYuvHalf;
return (int)(luma >> YUV_FIX);
}
static uint32_t ScaleDown(uint16_t a, uint16_t b, uint16_t c, uint16_t d,
int rgb_bit_depth) {
const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
const uint32_t A = SharpYuvGammaToLinear(a, bit_depth);
const uint32_t B = SharpYuvGammaToLinear(b, bit_depth);
const uint32_t C = SharpYuvGammaToLinear(c, bit_depth);
const uint32_t D = SharpYuvGammaToLinear(d, bit_depth);
return SharpYuvLinearToGamma((A + B + C + D + 2) >> 2, bit_depth);
}
static WEBP_INLINE void UpdateW(const fixed_y_t* src, fixed_y_t* dst, int w,
int rgb_bit_depth) {
const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
int i;
for (i = 0; i < w; ++i) {
const uint32_t R = SharpYuvGammaToLinear(src[0 * w + i], bit_depth);
const uint32_t G = SharpYuvGammaToLinear(src[1 * w + i], bit_depth);
const uint32_t B = SharpYuvGammaToLinear(src[2 * w + i], bit_depth);
const uint32_t Y = RGBToGray(R, G, B);
dst[i] = (fixed_y_t)SharpYuvLinearToGamma(Y, bit_depth);
}
}
static void UpdateChroma(const fixed_y_t* src1, const fixed_y_t* src2,
fixed_t* dst, int uv_w, int rgb_bit_depth) {
int i;
for (i = 0; i < uv_w; ++i) {
const int r =
ScaleDown(src1[0 * uv_w + 0], src1[0 * uv_w + 1], src2[0 * uv_w + 0],
src2[0 * uv_w + 1], rgb_bit_depth);
const int g =
ScaleDown(src1[2 * uv_w + 0], src1[2 * uv_w + 1], src2[2 * uv_w + 0],
src2[2 * uv_w + 1], rgb_bit_depth);
const int b =
ScaleDown(src1[4 * uv_w + 0], src1[4 * uv_w + 1], src2[4 * uv_w + 0],
src2[4 * uv_w + 1], rgb_bit_depth);
const int W = RGBToGray(r, g, b);
dst[0 * uv_w] = (fixed_t)(r - W);
dst[1 * uv_w] = (fixed_t)(g - W);
dst[2 * uv_w] = (fixed_t)(b - W);
dst += 1;
src1 += 2;
src2 += 2;
}
}
static void StoreGray(const fixed_y_t* rgb, fixed_y_t* y, int w) {
int i;
assert(w > 0);
for (i = 0; i < w; ++i) {
y[i] = RGBToGray(rgb[0 * w + i], rgb[1 * w + i], rgb[2 * w + i]);
}
}
//------------------------------------------------------------------------------
static WEBP_INLINE fixed_y_t Filter2(int A, int B, int W0, int bit_depth) {
const int v0 = (A * 3 + B + 2) >> 2;
return clip_bit_depth(v0 + W0, bit_depth);
}
//------------------------------------------------------------------------------
static WEBP_INLINE int Shift(int v, int shift) {
return (shift >= 0) ? (v << shift) : (v >> -shift);
}
static void ImportOneRow(const uint8_t* const r_ptr,
const uint8_t* const g_ptr,
const uint8_t* const b_ptr,
int rgb_step,
int rgb_bit_depth,
int pic_width,
fixed_y_t* const dst) {
// Convert the rgb_step from a number of bytes to a number of uint8_t or
// uint16_t values depending the bit depth.
const int step = (rgb_bit_depth > 8) ? rgb_step / 2 : rgb_step;
int i;
const int w = (pic_width + 1) & ~1;
for (i = 0; i < pic_width; ++i) {
const int off = i * step;
const int shift = GetPrecisionShift(rgb_bit_depth);
if (rgb_bit_depth == 8) {
dst[i + 0 * w] = Shift(r_ptr[off], shift);
dst[i + 1 * w] = Shift(g_ptr[off], shift);
dst[i + 2 * w] = Shift(b_ptr[off], shift);
} else {
dst[i + 0 * w] = Shift(((uint16_t*)r_ptr)[off], shift);
dst[i + 1 * w] = Shift(((uint16_t*)g_ptr)[off], shift);
dst[i + 2 * w] = Shift(((uint16_t*)b_ptr)[off], shift);
}
}
if (pic_width & 1) { // replicate rightmost pixel
dst[pic_width + 0 * w] = dst[pic_width + 0 * w - 1];
dst[pic_width + 1 * w] = dst[pic_width + 1 * w - 1];
dst[pic_width + 2 * w] = dst[pic_width + 2 * w - 1];
}
}
static void InterpolateTwoRows(const fixed_y_t* const best_y,
const fixed_t* prev_uv,
const fixed_t* cur_uv,
const fixed_t* next_uv,
int w,
fixed_y_t* out1,
fixed_y_t* out2,
int rgb_bit_depth) {
const int uv_w = w >> 1;
const int len = (w - 1) >> 1; // length to filter
int k = 3;
const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
while (k-- > 0) { // process each R/G/B segments in turn
// special boundary case for i==0
out1[0] = Filter2(cur_uv[0], prev_uv[0], best_y[0], bit_depth);
out2[0] = Filter2(cur_uv[0], next_uv[0], best_y[w], bit_depth);
SharpYuvFilterRow(cur_uv, prev_uv, len, best_y + 0 + 1, out1 + 1,
bit_depth);
SharpYuvFilterRow(cur_uv, next_uv, len, best_y + w + 1, out2 + 1,
bit_depth);
// special boundary case for i == w - 1 when w is even
if (!(w & 1)) {
out1[w - 1] = Filter2(cur_uv[uv_w - 1], prev_uv[uv_w - 1],
best_y[w - 1 + 0], bit_depth);
out2[w - 1] = Filter2(cur_uv[uv_w - 1], next_uv[uv_w - 1],
best_y[w - 1 + w], bit_depth);
}
out1 += w;
out2 += w;
prev_uv += uv_w;
cur_uv += uv_w;
next_uv += uv_w;
}
}
static WEBP_INLINE int RGBToYUVComponent(int r, int g, int b,
const int coeffs[4], int sfix) {
const int srounder = 1 << (YUV_FIX + sfix - 1);
const int luma = coeffs[0] * r + coeffs[1] * g + coeffs[2] * b +
coeffs[3] + srounder;
return (luma >> (YUV_FIX + sfix));
}
static int ConvertWRGBToYUV(const fixed_y_t* best_y, const fixed_t* best_uv,
uint8_t* y_ptr, int y_stride, uint8_t* u_ptr,
int u_stride, uint8_t* v_ptr, int v_stride,
int rgb_bit_depth,
int yuv_bit_depth, int width, int height,
const SharpYuvConversionMatrix* yuv_matrix) {
int i, j;
const fixed_t* const best_uv_base = best_uv;
const int w = (width + 1) & ~1;
const int h = (height + 1) & ~1;
const int uv_w = w >> 1;
const int uv_h = h >> 1;
const int sfix = GetPrecisionShift(rgb_bit_depth);
const int yuv_max = (1 << yuv_bit_depth) - 1;
for (best_uv = best_uv_base, j = 0; j < height; ++j) {
for (i = 0; i < width; ++i) {
const int off = (i >> 1);
const int W = best_y[i];
const int r = best_uv[off + 0 * uv_w] + W;
const int g = best_uv[off + 1 * uv_w] + W;
const int b = best_uv[off + 2 * uv_w] + W;
const int y = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_y, sfix);
if (yuv_bit_depth <= 8) {
y_ptr[i] = clip_8b(y);
} else {
((uint16_t*)y_ptr)[i] = clip(y, yuv_max);
}
}
best_y += w;
best_uv += (j & 1) * 3 * uv_w;
y_ptr += y_stride;
}
for (best_uv = best_uv_base, j = 0; j < uv_h; ++j) {
for (i = 0; i < uv_w; ++i) {
const int off = i;
// Note r, g and b values here are off by W, but a constant offset on all
// 3 components doesn't change the value of u and v with a YCbCr matrix.
const int r = best_uv[off + 0 * uv_w];
const int g = best_uv[off + 1 * uv_w];
const int b = best_uv[off + 2 * uv_w];
const int u = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_u, sfix);
const int v = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_v, sfix);
if (yuv_bit_depth <= 8) {
u_ptr[i] = clip_8b(u);
v_ptr[i] = clip_8b(v);
} else {
((uint16_t*)u_ptr)[i] = clip(u, yuv_max);
((uint16_t*)v_ptr)[i] = clip(v, yuv_max);
}
}
best_uv += 3 * uv_w;
u_ptr += u_stride;
v_ptr += v_stride;
}
return 1;
}
//------------------------------------------------------------------------------
// Main function
static void* SafeMalloc(uint64_t nmemb, size_t size) {
const uint64_t total_size = nmemb * (uint64_t)size;
if (total_size != (size_t)total_size) return NULL;
return malloc((size_t)total_size);
}
#define SAFE_ALLOC(W, H, T) ((T*)SafeMalloc((W) * (H), sizeof(T)))
static int DoSharpArgbToYuv(const uint8_t* r_ptr, const uint8_t* g_ptr,
const uint8_t* b_ptr, int rgb_step, int rgb_stride,
int rgb_bit_depth, uint8_t* y_ptr, int y_stride,
uint8_t* u_ptr, int u_stride, uint8_t* v_ptr,
int v_stride, int yuv_bit_depth, int width,
int height,
const SharpYuvConversionMatrix* yuv_matrix) {
// we expand the right/bottom border if needed
const int w = (width + 1) & ~1;
const int h = (height + 1) & ~1;
const int uv_w = w >> 1;
const int uv_h = h >> 1;
uint64_t prev_diff_y_sum = ~0;
int j, iter;
// TODO(skal): allocate one big memory chunk. But for now, it's easier
// for valgrind debugging to have several chunks.
fixed_y_t* const tmp_buffer = SAFE_ALLOC(w * 3, 2, fixed_y_t); // scratch
fixed_y_t* const best_y_base = SAFE_ALLOC(w, h, fixed_y_t);
fixed_y_t* const target_y_base = SAFE_ALLOC(w, h, fixed_y_t);
fixed_y_t* const best_rgb_y = SAFE_ALLOC(w, 2, fixed_y_t);
fixed_t* const best_uv_base = SAFE_ALLOC(uv_w * 3, uv_h, fixed_t);
fixed_t* const target_uv_base = SAFE_ALLOC(uv_w * 3, uv_h, fixed_t);
fixed_t* const best_rgb_uv = SAFE_ALLOC(uv_w * 3, 1, fixed_t);
fixed_y_t* best_y = best_y_base;
fixed_y_t* target_y = target_y_base;
fixed_t* best_uv = best_uv_base;
fixed_t* target_uv = target_uv_base;
const uint64_t diff_y_threshold = (uint64_t)(3.0 * w * h);
int ok;
assert(w > 0);
assert(h > 0);
if (best_y_base == NULL || best_uv_base == NULL ||
target_y_base == NULL || target_uv_base == NULL ||
best_rgb_y == NULL || best_rgb_uv == NULL ||
tmp_buffer == NULL) {
ok = 0;
goto End;
}
// Import RGB samples to W/RGB representation.
for (j = 0; j < height; j += 2) {
const int is_last_row = (j == height - 1);
fixed_y_t* const src1 = tmp_buffer + 0 * w;
fixed_y_t* const src2 = tmp_buffer + 3 * w;
// prepare two rows of input
ImportOneRow(r_ptr, g_ptr, b_ptr, rgb_step, rgb_bit_depth, width,
src1);
if (!is_last_row) {
ImportOneRow(r_ptr + rgb_stride, g_ptr + rgb_stride, b_ptr + rgb_stride,
rgb_step, rgb_bit_depth, width, src2);
} else {
memcpy(src2, src1, 3 * w * sizeof(*src2));
}
StoreGray(src1, best_y + 0, w);
StoreGray(src2, best_y + w, w);
UpdateW(src1, target_y, w, rgb_bit_depth);
UpdateW(src2, target_y + w, w, rgb_bit_depth);
UpdateChroma(src1, src2, target_uv, uv_w, rgb_bit_depth);
memcpy(best_uv, target_uv, 3 * uv_w * sizeof(*best_uv));
best_y += 2 * w;
best_uv += 3 * uv_w;
target_y += 2 * w;
target_uv += 3 * uv_w;
r_ptr += 2 * rgb_stride;
g_ptr += 2 * rgb_stride;
b_ptr += 2 * rgb_stride;
}
// Iterate and resolve clipping conflicts.
for (iter = 0; iter < kNumIterations; ++iter) {
const fixed_t* cur_uv = best_uv_base;
const fixed_t* prev_uv = best_uv_base;
uint64_t diff_y_sum = 0;
best_y = best_y_base;
best_uv = best_uv_base;
target_y = target_y_base;
target_uv = target_uv_base;
for (j = 0; j < h; j += 2) {
fixed_y_t* const src1 = tmp_buffer + 0 * w;
fixed_y_t* const src2 = tmp_buffer + 3 * w;
{
const fixed_t* const next_uv = cur_uv + ((j < h - 2) ? 3 * uv_w : 0);
InterpolateTwoRows(best_y, prev_uv, cur_uv, next_uv, w,
src1, src2, rgb_bit_depth);
prev_uv = cur_uv;
cur_uv = next_uv;
}
UpdateW(src1, best_rgb_y + 0 * w, w, rgb_bit_depth);
UpdateW(src2, best_rgb_y + 1 * w, w, rgb_bit_depth);
UpdateChroma(src1, src2, best_rgb_uv, uv_w, rgb_bit_depth);
// update two rows of Y and one row of RGB
diff_y_sum +=
SharpYuvUpdateY(target_y, best_rgb_y, best_y, 2 * w,
rgb_bit_depth + GetPrecisionShift(rgb_bit_depth));
SharpYuvUpdateRGB(target_uv, best_rgb_uv, best_uv, 3 * uv_w);
best_y += 2 * w;
best_uv += 3 * uv_w;
target_y += 2 * w;
target_uv += 3 * uv_w;
}
// test exit condition
if (iter > 0) {
if (diff_y_sum < diff_y_threshold) break;
if (diff_y_sum > prev_diff_y_sum) break;
}
prev_diff_y_sum = diff_y_sum;
}
// final reconstruction
ok = ConvertWRGBToYUV(best_y_base, best_uv_base, y_ptr, y_stride, u_ptr,
u_stride, v_ptr, v_stride, rgb_bit_depth, yuv_bit_depth,
width, height, yuv_matrix);
End:
free(best_y_base);
free(best_uv_base);
free(target_y_base);
free(target_uv_base);
free(best_rgb_y);
free(best_rgb_uv);
free(tmp_buffer);
return ok;
}
#undef SAFE_ALLOC
// Hidden exported init function.
// By default SharpYuvConvert calls it with NULL. If needed, users can declare
// it as extern and call it with a VP8CPUInfo function.
extern void SharpYuvInit(VP8CPUInfo cpu_info_func);
void SharpYuvInit(VP8CPUInfo cpu_info_func) {
static volatile VP8CPUInfo sharpyuv_last_cpuinfo_used =
(VP8CPUInfo)&sharpyuv_last_cpuinfo_used;
const int initialized =
(sharpyuv_last_cpuinfo_used != (VP8CPUInfo)&sharpyuv_last_cpuinfo_used);
if (cpu_info_func == NULL && initialized) return;
if (sharpyuv_last_cpuinfo_used == cpu_info_func) return;
SharpYuvInitDsp(cpu_info_func);
if (!initialized) {
SharpYuvInitGammaTables();
}
sharpyuv_last_cpuinfo_used = cpu_info_func;
}
int SharpYuvConvert(const void* r_ptr, const void* g_ptr,
const void* b_ptr, int rgb_step, int rgb_stride,
int rgb_bit_depth, void* y_ptr, int y_stride,
void* u_ptr, int u_stride, void* v_ptr,
int v_stride, int yuv_bit_depth, int width,
int height, const SharpYuvConversionMatrix* yuv_matrix) {
SharpYuvConversionMatrix scaled_matrix;
const int rgb_max = (1 << rgb_bit_depth) - 1;
const int rgb_round = 1 << (rgb_bit_depth - 1);
const int yuv_max = (1 << yuv_bit_depth) - 1;
const int sfix = GetPrecisionShift(rgb_bit_depth);
if (width < 1 || height < 1 || width == INT_MAX || height == INT_MAX ||
r_ptr == NULL || g_ptr == NULL || b_ptr == NULL || y_ptr == NULL ||
u_ptr == NULL || v_ptr == NULL) {
return 0;
}
if (rgb_bit_depth != 8 && rgb_bit_depth != 10 && rgb_bit_depth != 12 &&
rgb_bit_depth != 16) {
return 0;
}
if (yuv_bit_depth != 8 && yuv_bit_depth != 10 && yuv_bit_depth != 12) {
return 0;
}
if (rgb_bit_depth > 8 && (rgb_step % 2 != 0 || rgb_stride %2 != 0)) {
// Step/stride should be even for uint16_t buffers.
return 0;
}
if (yuv_bit_depth > 8 &&
(y_stride % 2 != 0 || u_stride % 2 != 0 || v_stride % 2 != 0)) {
// Stride should be even for uint16_t buffers.
return 0;
}
SharpYuvInit(NULL);
// Add scaling factor to go from rgb_bit_depth to yuv_bit_depth, to the
// rgb->yuv conversion matrix.
if (rgb_bit_depth == yuv_bit_depth) {
memcpy(&scaled_matrix, yuv_matrix, sizeof(scaled_matrix));
} else {
int i;
for (i = 0; i < 3; ++i) {
scaled_matrix.rgb_to_y[i] =
(yuv_matrix->rgb_to_y[i] * yuv_max + rgb_round) / rgb_max;
scaled_matrix.rgb_to_u[i] =
(yuv_matrix->rgb_to_u[i] * yuv_max + rgb_round) / rgb_max;
scaled_matrix.rgb_to_v[i] =
(yuv_matrix->rgb_to_v[i] * yuv_max + rgb_round) / rgb_max;
}
}
// Also incorporate precision change scaling.
scaled_matrix.rgb_to_y[3] = Shift(yuv_matrix->rgb_to_y[3], sfix);
scaled_matrix.rgb_to_u[3] = Shift(yuv_matrix->rgb_to_u[3], sfix);
scaled_matrix.rgb_to_v[3] = Shift(yuv_matrix->rgb_to_v[3], sfix);
return DoSharpArgbToYuv(r_ptr, g_ptr, b_ptr, rgb_step, rgb_stride,
rgb_bit_depth, y_ptr, y_stride, u_ptr, u_stride,
v_ptr, v_stride, yuv_bit_depth, width, height,
&scaled_matrix);
}
//------------------------------------------------------------------------------

81
sharpyuv/sharpyuv.h Normal file
View File

@ -0,0 +1,81 @@
// Copyright 2022 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Sharp RGB to YUV conversion.
#ifndef WEBP_SHARPYUV_SHARPYUV_H_
#define WEBP_SHARPYUV_SHARPYUV_H_
#include <inttypes.h>
#ifdef __cplusplus
extern "C" {
#endif
// SharpYUV API version following the convention from semver.org
#define SHARPYUV_VERSION_MAJOR 0
#define SHARPYUV_VERSION_MINOR 1
#define SHARPYUV_VERSION_PATCH 0
// Version as a uint32_t. The major number is the high 8 bits.
// The minor number is the middle 8 bits. The patch number is the low 16 bits.
#define SHARPYUV_MAKE_VERSION(MAJOR, MINOR, PATCH) \
(((MAJOR) << 24) | ((MINOR) << 16) | (PATCH))
#define SHARPYUV_VERSION \
SHARPYUV_MAKE_VERSION(SHARPYUV_VERSION_MAJOR, SHARPYUV_VERSION_MINOR, \
SHARPYUV_VERSION_PATCH)
// RGB to YUV conversion matrix, in 16 bit fixed point.
// y = rgb_to_y[0] * r + rgb_to_y[1] * g + rgb_to_y[2] * b + rgb_to_y[3]
// u = rgb_to_u[0] * r + rgb_to_u[1] * g + rgb_to_u[2] * b + rgb_to_u[3]
// v = rgb_to_v[0] * r + rgb_to_v[1] * g + rgb_to_v[2] * b + rgb_to_v[3]
// Then y, u and v values are divided by 1<<16 and rounded.
typedef struct {
int rgb_to_y[4];
int rgb_to_u[4];
int rgb_to_v[4];
} SharpYuvConversionMatrix;
// Converts RGB to YUV420 using a downsampling algorithm that minimizes
// artefacts caused by chroma subsampling.
// This is slower than standard downsampling (averaging of 4 UV values).
// Assumes that the image will be upsampled using a bilinear filter. If nearest
// neighbor is used instead, the upsampled image might look worse than with
// standard downsampling.
// r_ptr, g_ptr, b_ptr: pointers to the source r, g and b channels. Should point
// to uint8_t buffers if rgb_bit_depth is 8, or uint16_t buffers otherwise.
// rgb_step: distance in bytes between two horizontally adjacent pixels on the
// r, g and b channels. If rgb_bit_depth is > 8, it should be a
// multiple of 2.
// rgb_stride: distance in bytes between two vertically adjacent pixels on the
// r, g, and b channels. If rgb_bit_depth is > 8, it should be a
// multiple of 2.
// rgb_bit_depth: number of bits for each r/g/b value. One of: 8, 10, 12, 16.
// Note: 16 bit input is truncated to 14 bits before conversion to yuv.
// yuv_bit_depth: number of bits for each y/u/v value. One of: 8, 10, 12.
// y_ptr, u_ptr, v_ptr: pointers to the destination y, u and v channels. Should
// point to uint8_t buffers if yuv_bit_depth is 8, or uint16_t buffers
// otherwise.
// y_stride, u_stride, v_stride: distance in bytes between two vertically
// adjacent pixels on the y, u and v channels. If yuv_bit_depth > 8, they
// should be multiples of 2.
// width, height: width and height of the image in pixels
int SharpYuvConvert(const void* r_ptr, const void* g_ptr, const void* b_ptr,
int rgb_step, int rgb_stride, int rgb_bit_depth,
void* y_ptr, int y_stride, void* u_ptr, int u_stride,
void* v_ptr, int v_stride, int yuv_bit_depth, int width,
int height, const SharpYuvConversionMatrix* yuv_matrix);
// TODO(b/194336375): Add YUV444 to YUV420 conversion. Maybe also add 422
// support (it's rarely used in practice, especially for images).
#ifdef __cplusplus
} // extern "C"
#endif
#endif // WEBP_SHARPYUV_SHARPYUV_H_

110
sharpyuv/sharpyuv_csp.c Normal file
View File

@ -0,0 +1,110 @@
// Copyright 2022 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Colorspace utilities.
#include "sharpyuv/sharpyuv_csp.h"
#include <assert.h>
#include <math.h>
#include <string.h>
static int ToFixed16(float f) { return (int)floor(f * (1 << 16) + 0.5f); }
void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space,
SharpYuvConversionMatrix* matrix) {
const float kr = yuv_color_space->kr;
const float kb = yuv_color_space->kb;
const float kg = 1.0f - kr - kb;
const float cr = 0.5f / (1.0f - kb);
const float cb = 0.5f / (1.0f - kr);
const int shift = yuv_color_space->bit_depth - 8;
const float denom = (float)((1 << yuv_color_space->bit_depth) - 1);
float scale_y = 1.0f;
float add_y = 0.0f;
float scale_u = cr;
float scale_v = cb;
float add_uv = (float)(128 << shift);
assert(yuv_color_space->bit_depth >= 8);
if (yuv_color_space->range == kSharpYuvRangeLimited) {
scale_y *= (219 << shift) / denom;
scale_u *= (224 << shift) / denom;
scale_v *= (224 << shift) / denom;
add_y = (float)(16 << shift);
}
matrix->rgb_to_y[0] = ToFixed16(kr * scale_y);
matrix->rgb_to_y[1] = ToFixed16(kg * scale_y);
matrix->rgb_to_y[2] = ToFixed16(kb * scale_y);
matrix->rgb_to_y[3] = ToFixed16(add_y);
matrix->rgb_to_u[0] = ToFixed16(-kr * scale_u);
matrix->rgb_to_u[1] = ToFixed16(-kg * scale_u);
matrix->rgb_to_u[2] = ToFixed16((1 - kb) * scale_u);
matrix->rgb_to_u[3] = ToFixed16(add_uv);
matrix->rgb_to_v[0] = ToFixed16((1 - kr) * scale_v);
matrix->rgb_to_v[1] = ToFixed16(-kg * scale_v);
matrix->rgb_to_v[2] = ToFixed16(-kb * scale_v);
matrix->rgb_to_v[3] = ToFixed16(add_uv);
}
// Matrices are in YUV_FIX fixed point precision.
// WebP's matrix, similar but not identical to kRec601LimitedMatrix.
static const SharpYuvConversionMatrix kWebpMatrix = {
{16839, 33059, 6420, 16 << 16},
{-9719, -19081, 28800, 128 << 16},
{28800, -24116, -4684, 128 << 16},
};
// Kr=0.2990f Kb=0.1140f bits=8 range=kSharpYuvRangeLimited
static const SharpYuvConversionMatrix kRec601LimitedMatrix = {
{16829, 33039, 6416, 16 << 16},
{-9714, -19071, 28784, 128 << 16},
{28784, -24103, -4681, 128 << 16},
};
// Kr=0.2990f Kb=0.1140f bits=8 range=kSharpYuvRangeFull
static const SharpYuvConversionMatrix kRec601FullMatrix = {
{19595, 38470, 7471, 0},
{-11058, -21710, 32768, 128 << 16},
{32768, -27439, -5329, 128 << 16},
};
// Kr=0.2126f Kb=0.0722f bits=8 range=kSharpYuvRangeLimited
static const SharpYuvConversionMatrix kRec709LimitedMatrix = {
{11966, 40254, 4064, 16 << 16},
{-6596, -22189, 28784, 128 << 16},
{28784, -26145, -2639, 128 << 16},
};
// Kr=0.2126f Kb=0.0722f bits=8 range=kSharpYuvRangeFull
static const SharpYuvConversionMatrix kRec709FullMatrix = {
{13933, 46871, 4732, 0},
{-7509, -25259, 32768, 128 << 16},
{32768, -29763, -3005, 128 << 16},
};
const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
SharpYuvMatrixType matrix_type) {
switch (matrix_type) {
case kSharpYuvMatrixWebp:
return &kWebpMatrix;
case kSharpYuvMatrixRec601Limited:
return &kRec601LimitedMatrix;
case kSharpYuvMatrixRec601Full:
return &kRec601FullMatrix;
case kSharpYuvMatrixRec709Limited:
return &kRec709LimitedMatrix;
case kSharpYuvMatrixRec709Full:
return &kRec709FullMatrix;
case kSharpYuvMatrixNum:
return NULL;
}
return NULL;
}

59
sharpyuv/sharpyuv_csp.h Normal file
View File

@ -0,0 +1,59 @@
// Copyright 2022 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Colorspace utilities.
#ifndef WEBP_SHARPYUV_SHARPYUV_CSP_H_
#define WEBP_SHARPYUV_SHARPYUV_CSP_H_
#include "sharpyuv/sharpyuv.h"
#ifdef __cplusplus
extern "C" {
#endif
// Range of YUV values.
typedef enum {
kSharpYuvRangeFull, // YUV values between [0;255] (for 8 bit)
kSharpYuvRangeLimited // Y in [16;235], YUV in [16;240] (for 8 bit)
} SharpYuvRange;
// Constants that define a YUV color space.
typedef struct {
// Kr and Kb are defined such that:
// Y = Kr * r + Kg * g + Kb * b where Kg = 1 - Kr - Kb.
float kr;
float kb;
int bit_depth; // 8, 10 or 12
SharpYuvRange range;
} SharpYuvColorSpace;
// Fills in 'matrix' for the given YUVColorSpace.
void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space,
SharpYuvConversionMatrix* matrix);
// Enums for precomputed conversion matrices.
typedef enum {
kSharpYuvMatrixWebp = 0,
kSharpYuvMatrixRec601Limited,
kSharpYuvMatrixRec601Full,
kSharpYuvMatrixRec709Limited,
kSharpYuvMatrixRec709Full,
kSharpYuvMatrixNum
} SharpYuvMatrixType;
// Returns a pointer to a matrix for one of the predefined colorspaces.
const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
SharpYuvMatrixType matrix_type);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // WEBP_SHARPYUV_SHARPYUV_CSP_H_

Some files were not shown because too many files have changed in this diff Show More