aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Zern <jzern@google.com>2015-03-17 18:54:21 -0700
committerJames Zern <jzern@google.com>2015-03-25 11:17:23 -0700
commit9e80ee991168a0a6c2a906dd2c17c5e17df4566e (patch)
tree48b5b5c2dc881c16a703c09de1287f398e357ed3
parentd4402ea027d98455680d2494152812b477240260 (diff)
downloadwebp-marshmallow-dr-dev.tar.gz
external/webp: update to v0.4.3android-cts-6.0_r9android-cts-6.0_r8android-cts-6.0_r7android-cts-6.0_r6android-cts-6.0_r5android-cts-6.0_r4android-cts-6.0_r32android-cts-6.0_r31android-cts-6.0_r30android-cts-6.0_r3android-cts-6.0_r29android-cts-6.0_r28android-cts-6.0_r27android-cts-6.0_r26android-cts-6.0_r25android-cts-6.0_r24android-cts-6.0_r23android-cts-6.0_r22android-cts-6.0_r21android-cts-6.0_r20android-cts-6.0_r2android-cts-6.0_r19android-cts-6.0_r18android-cts-6.0_r17android-cts-6.0_r16android-cts-6.0_r15android-cts-6.0_r14android-cts-6.0_r13android-cts-6.0_r12android-cts-6.0_r1android-6.0.1_r9android-6.0.1_r81android-6.0.1_r80android-6.0.1_r8android-6.0.1_r79android-6.0.1_r78android-6.0.1_r77android-6.0.1_r74android-6.0.1_r73android-6.0.1_r72android-6.0.1_r70android-6.0.1_r7android-6.0.1_r69android-6.0.1_r68android-6.0.1_r67android-6.0.1_r66android-6.0.1_r65android-6.0.1_r63android-6.0.1_r62android-6.0.1_r61android-6.0.1_r60android-6.0.1_r59android-6.0.1_r58android-6.0.1_r57android-6.0.1_r56android-6.0.1_r55android-6.0.1_r54android-6.0.1_r53android-6.0.1_r52android-6.0.1_r51android-6.0.1_r50android-6.0.1_r5android-6.0.1_r49android-6.0.1_r48android-6.0.1_r47android-6.0.1_r46android-6.0.1_r45android-6.0.1_r43android-6.0.1_r42android-6.0.1_r41android-6.0.1_r40android-6.0.1_r4android-6.0.1_r33android-6.0.1_r32android-6.0.1_r31android-6.0.1_r30android-6.0.1_r3android-6.0.1_r28android-6.0.1_r27android-6.0.1_r26android-6.0.1_r25android-6.0.1_r24android-6.0.1_r22android-6.0.1_r21android-6.0.1_r20android-6.0.1_r18android-6.0.1_r17android-6.0.1_r16android-6.0.1_r13android-6.0.1_r12android-6.0.1_r11android-6.0.1_r10android-6.0.1_r1android-6.0.0_r7android-6.0.0_r6android-6.0.0_r5android-6.0.0_r41android-6.0.0_r4android-6.0.0_r3android-6.0.0_r26android-6.0.0_r25android-6.0.0_r24android-6.0.0_r23android-6.0.0_r2android-6.0.0_r13android-6.0.0_r12android-6.0.0_r11android-6.0.0_r1marshmallow-releasemarshmallow-mr3-releasemarshmallow-mr2-releasemarshmallow-mr1-releasemarshmallow-mr1-devmarshmallow-dr1.6-releasemarshmallow-dr1.5-releasemarshmallow-dr1.5-devmarshmallow-dr-releasemarshmallow-dr-dragon-releasemarshmallow-dr-devmarshmallow-devmarshmallow-cts-release
+ dropped some dated / unused files: INSTALL, examples/* - 3/3/15: version 0.4.3 This is a binary compatible release. * Android / gcc / iOS / MSVS build fixes and improvements * lossless decode fix (issue #239 -- since 0.4.0) * documentation / vwebp updates for animation * multi-threading fix (issue #234) Change-Id: I7777e5d35f5659488a98fd773bd2a645ac06215d
-rw-r--r--AUTHORS6
-rw-r--r--ChangeLog1
-rw-r--r--INSTALL237
-rw-r--r--NEWS9
-rw-r--r--PATENTS39
-rw-r--r--README2
-rw-r--r--README.android53
-rw-r--r--examples/dwebp.c527
-rw-r--r--examples/test.webpbin4880 -> 0 bytes
-rw-r--r--examples/test_ref.ppm4
-rw-r--r--include/webp/encode.h4
-rw-r--r--include/webp/types.h7
-rw-r--r--src/Android.mk38
-rw-r--r--src/dec/alpha.c2
-rw-r--r--src/dec/decode_vp8.h2
-rw-r--r--src/dec/idec.c29
-rw-r--r--src/dec/tree.c2
-rw-r--r--src/dec/vp8.c1
-rw-r--r--src/dec/vp8i.h2
-rw-r--r--src/dec/webp.c2
-rw-r--r--src/demux/demux.c8
-rw-r--r--src/dsp/alpha_processing.c6
-rw-r--r--src/dsp/cpu.c12
-rw-r--r--src/dsp/dec.c7
-rw-r--r--src/dsp/dsp.h9
-rw-r--r--src/dsp/enc.c6
-rw-r--r--src/dsp/enc_neon.c6
-rw-r--r--src/dsp/lossless.c6
-rw-r--r--src/dsp/lossless.h4
-rw-r--r--src/dsp/lossless_neon.c49
-rw-r--r--src/dsp/upsampling.c6
-rw-r--r--src/dsp/yuv.c6
-rw-r--r--src/utils/bit_reader.c2
-rw-r--r--src/utils/bit_reader.h2
-rw-r--r--src/utils/bit_reader_inl.h2
-rw-r--r--src/utils/bit_writer.h2
-rw-r--r--src/utils/color_cache.h2
-rw-r--r--src/utils/endian_inl.h4
-rw-r--r--src/utils/filters.h2
-rw-r--r--src/utils/huffman.c2
-rw-r--r--src/utils/huffman.h4
-rw-r--r--src/utils/huffman_encode.c2
-rw-r--r--src/utils/huffman_encode.h2
-rw-r--r--src/utils/quant_levels.h2
-rw-r--r--src/utils/quant_levels_dec.h2
-rw-r--r--src/utils/random.h2
-rw-r--r--src/utils/rescaler.h2
-rw-r--r--src/utils/thread.h4
-rw-r--r--src/utils/utils.h2
-rw-r--r--src/webp/decode.h503
-rw-r--r--src/webp/demux.h224
-rw-r--r--src/webp/encode.h520
-rw-r--r--src/webp/format_constants.h88
-rw-r--r--src/webp/mux_types.h97
-rw-r--r--src/webp/types.h48
55 files changed, 1677 insertions, 935 deletions
diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644
index 78ca2c2f..00000000
--- a/AUTHORS
+++ /dev/null
@@ -1,6 +0,0 @@
-Initial release:
-- Pascal Massimino (pascal.massimino@gmail.com)
-
-Contributors:
-- pierre.php@gmail.com (ansi-C port)
-- vikaas.arora@gmail.com
diff --git a/ChangeLog b/ChangeLog
index 7a71aa08..a6e8b4b1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,3 +10,4 @@
- 1/14: Release version 0.4.0-rc1 (change#I22be12d8)
- 7/14: Release version 0.4.1-rc1 (change#I5346984d2)
- 1/15: Release version 0.4.2 (change#I32a22786f)
+- 3/17: Release version 0.4.3 (tag: v0.4.3)
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index d3c5b40a..00000000
--- a/INSTALL
+++ /dev/null
@@ -1,237 +0,0 @@
-Installation Instructions
-*************************
-
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006, 2007 Free Software Foundation, Inc.
-
-This file is free documentation; the Free Software Foundation gives
-unlimited permission to copy, distribute and modify it.
-
-Basic Installation
-==================
-
-Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package. The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
-
-The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system.
-
- Running `configure' might take a while. While running, it prints
- some messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package.
-
- 4. Type `make install' to install the programs and any data files and
- documentation.
-
- 5. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
- 6. Often, you can also type `make uninstall' to remove the installed
- files again.
-
-Compilers and Options
-=====================
-
-Some systems require unusual options for compilation or linking that the
-`configure' script does not know about. Run `./configure --help' for
-details on some of the pertinent environment variables.
-
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
-
- ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
-You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you can use GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
- With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory. After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
-
-Installation Names
-==================
-
-By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc. You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX'.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
-Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Specifying the System Type
-==========================
-
-There may be some features `configure' cannot figure out automatically,
-but needs to determine by the type of machine the package will run on.
-Usually, assuming the package is built to be run on the _same_
-architectures, `configure' can figure that out, but if it prints a
-message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS KERNEL-OS
-
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
-If you want to set default values for `configure' scripts to share, you
-can create a site shell script called `config.site' that gives default
-values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
-Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug. Until the bug is fixed you can use this workaround:
-
- CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-`configure' Invocation
-======================
-
-`configure' recognizes the following options to control how it operates.
-
-`--help'
-`-h'
- Print a summary of the options to `configure', and exit.
-
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
- disable caching.
-
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
-
diff --git a/NEWS b/NEWS
deleted file mode 100644
index 1c437b7f..00000000
--- a/NEWS
+++ /dev/null
@@ -1,9 +0,0 @@
-- 9/10: initial release version 0.1
-- 8/12: release version 0.2.0-rc1 (head change#Ia5475247).
-- 3/13: Updated WebP with head change#I9e5ae737
-- 8/13: release version 0.3.1 (head change#Idea3464b).
-- 8/13: Updated WebP with patches required for Animation
- (#I737451d7f, #Ia300385a & #I9566a8e2).
-- 1/14: release version 0.4.0-rc1 (change#I22be12d8).
-- 7/14: release version 0.4.1-rc1 (change#I5346984d2).
-- 1/15: release version 0.4.2 (change#I32a22786f).
diff --git a/PATENTS b/PATENTS
index 4414d838..79d17d7d 100644
--- a/PATENTS
+++ b/PATENTS
@@ -1,22 +1,23 @@
Additional IP Rights Grant (Patents)
+------------------------------------
-"This implementation" means the copyrightable works distributed by
-Google as part of the WebM Project.
+"These implementations" means the copyrightable works that implement the WebM
+codecs distributed by Google as part of the WebM Project.
-Google hereby grants to you a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer, and otherwise run, modify and propagate the contents of this
-implementation of VP8, where such license applies only to those patent
-claims, both currently owned by Google and acquired in the future,
-licensable by Google that are necessarily infringed by this
-implementation of VP8. This grant does not include claims that would be
-infringed only as a consequence of further modification of this
-implementation. If you or your agent or exclusive licensee institute or
-order or agree to the institution of patent litigation against any
-entity (including a cross-claim or counterclaim in a lawsuit) alleging
-that this implementation of VP8 or any code incorporated within this
-implementation of VP8 constitutes direct or contributory patent
-infringement, or inducement of patent infringement, then any patent
-rights granted to you under this License for this implementation of VP8
-shall terminate as of the date such litigation is filed.
+Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge,
+royalty-free, irrevocable (except as stated in this section) patent license to
+make, have made, use, offer to sell, sell, import, transfer, and otherwise
+run, modify and propagate the contents of these implementations of WebM, where
+such license applies only to those patent claims, both currently owned by
+Google and acquired in the future, licensable by Google that are necessarily
+infringed by these implementations of WebM. This grant does not include claims
+that would be infringed only as a consequence of further modification of these
+implementations. If you or your agent or exclusive licensee institute or order
+or agree to the institution of patent litigation or any other patent
+enforcement activity against any entity (including a cross-claim or
+counterclaim in a lawsuit) alleging that any of these implementations of WebM
+or any code incorporated within any of these implementations of WebM
+constitutes direct or contributory patent infringement, or inducement of
+patent infringement, then any patent rights granted to you under this License
+for these implementations of WebM shall terminate as of the date such
+litigation is filed.
diff --git a/README b/README
index 13f32ea1..c3f32c5c 100644
--- a/README
+++ b/README
@@ -4,7 +4,7 @@
\__\__/\____/\_____/__/ ____ ___
/ _/ / \ \ / _ \/ _/
/ \_/ / / \ \ __/ \__
- \____/____/\_____/_____/____/v0.4.2
+ \____/____/\_____/_____/____/v0.4.3
Description:
============
diff --git a/README.android b/README.android
index 81e7ac7d..63ef2bc2 100644
--- a/README.android
+++ b/README.android
@@ -1,56 +1,21 @@
-URL: http://review.webmproject.org/gitweb?p=libwebp.git
-Version: 43/1443/1
+URL: https://gerrit.chromium.org/gerrit/gitweb?p=webm%2Flibwebp.git
+Version: v0.4.3
License: Google BSD like
Local modifications:
- Rewrite Android.mk to remove duplicate definitions and set module name
in a consistent way with other external libraries
-- Move public headers from src/webp to include/webp, so path to headers
+- Copy public headers from src/webp to include/webp, so path to headers
may be appended into CFLAGS without risk for other private headers
(e.g. bits.h) to leak into
-- Sync-patch with libwebp ver 0.1.2
-- Removed Build files necessary for building via autoconf/automake tools
+- Removed build files necessary for building via autoconf/automake tools
These files are not required to build via Android.mk
- - Makefile.am Makefile.vc Makefile.in
- - config.h.in configure config.guess config.sub configure.ac
- - autogen.sh install-sh missing depcomp ltmain.sh aclocal.m4
-- Added WebP Encoder (ver 0.1.2) as well
- - Removed some more unused Makefile.am & Makefile.in
- - Added Android.mk to encoder & decoder code levels.
-- Synced the WebP Code (Encoder/Decoder) with the head change#Ia53f845b
- - Added three color-spaces viz ARGB_8888, RGBA_4444, RGB_565
- supported by Android.
-- Fixed the Endian'ness bug for Color-Configs (RGB_565 & ARGB_4444).
- The fix is similar to jpeglib handling for JCS_RGB_565 & JCS_RGBA_8888
- color configs. Added the code under "ANDROID_WEBP_RGB" flag.
-- Sync-patch with libwebp ver 0.2.0-rc1 (head change#Ia5475247).
-- Updated WebP with head change#I3da2063b
-- Updated WebP with head change#I9e5ae737
- - 16bit swapping of RGB565 / RGB4444 colorspace. Added compile-time flag
- WEBP_SWAP_16BIT_CSP to support byte-swap (required for skia data type for
- 16bit values) output for these colorspaces.
- - Added ARM/NEON code for decoder/encoder modules.
- - Speedup in WebP compression (method 3 and above).
- - Added multi-threaded alpha encoding for lossy compression.
- - Updated WebP with head change#I9e5ae737
-- Sync-patch with libwebp ver 0.3.1 (head change#Idea3464b).
- - Add incremental decoding support for images containing ALPH and ICCP chunks.
-- Updated WebP with patches required for Animation
- (#I737451d7f, #Ia300385a & #I9566a8e2).
-- Fix memleak in WebPIDelete() (change#Id4faef1b).
-- Sync-patch with libwebp ver 0.4.0-rc1 (change#I22be12d8).
-- Bugfix for incremental decode of lossy-alpha (change#I716ce082)
-- Sync-patch with libwebp ver 0.4.1-rc1 (change#I5346984d2).
- - NEON assembly optimizations:
- - ~25% faster lossy decode / encode (-m 4)
- - ~10% faster lossless decode
- - ~5-10% faster lossless encode (-m 3/4)
- - Arch64 (arm64) & MIPS support/optimizations.
-- Sync-patch with libwebp ver 0.4.2 (change#I32a22786f).
- - Cherry-picked Alpha-decoding bug.
+- Added a local copy of cpu-features.[hc] to src/dsp
+- Removed WEBP_ANDROID_NEON check in dsp.h to avoid breaking non-NEON builds
+ where the flags in Android.mk are not set correctly currently.
-The Android.mk file creates WebP Decoder and Encoder static libraries which
-can be added to any application by Adding to LOCAL_STATIC_LIBRARIES
+The Android.mk file creates WebP decoder and encoder static libraries which
+can be added to any application by adding to LOCAL_STATIC_LIBRARIES
libwebp-decode libwebp-encode:
LOCAL_STATIC_LIBRARIES += libwebp-decode libwebp-encode
diff --git a/examples/dwebp.c b/examples/dwebp.c
deleted file mode 100644
index c84b0d1d..00000000
--- a/examples/dwebp.c
+++ /dev/null
@@ -1,527 +0,0 @@
-// Copyright 2010 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.
-// -----------------------------------------------------------------------------
-//
-// Command-line tool for decoding a WebP image.
-//
-// Author: Skal (pascal.massimino@gmail.com)
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef WEBP_HAVE_PNG
-#include <png.h>
-#endif
-
-#ifdef HAVE_WINCODEC_H
-#ifdef __MINGW32__
-#define INITGUID // Without this GUIDs are declared extern and fail to link
-#endif
-#define CINTERFACE
-#define COBJMACROS
-#define _WIN32_IE 0x500 // Workaround bug in shlwapi.h when compiling C++
- // code with COBJMACROS.
-#include <shlwapi.h>
-#include <windows.h>
-#include <wincodec.h>
-#endif
-
-#include "webp/decode.h"
-#include "./example_util.h"
-#include "./stopwatch.h"
-
-static int verbose = 0;
-#ifndef WEBP_DLL
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-extern void* VP8GetCPUInfo; // opaque forward declaration.
-
-#if defined(__cplusplus) || defined(c_plusplus)
-} // extern "C"
-#endif
-#endif // WEBP_DLL
-
-//------------------------------------------------------------------------------
-
-// Output types
-typedef enum {
- PNG = 0,
- PAM,
- PPM,
- PGM,
- YUV,
- ALPHA_PLANE_ONLY // this is for experimenting only
-} OutputFileFormat;
-
-#ifdef HAVE_WINCODEC_H
-
-#define IFS(fn) \
- do { \
- if (SUCCEEDED(hr)) { \
- hr = (fn); \
- if (FAILED(hr)) fprintf(stderr, #fn " failed %08lx\n", hr); \
- } \
- } while (0)
-
-#ifdef __cplusplus
-#define MAKE_REFGUID(x) (x)
-#else
-#define MAKE_REFGUID(x) &(x)
-#endif
-
-static HRESULT CreateOutputStream(const char* out_file_name, IStream** stream) {
- HRESULT hr = S_OK;
- IFS(SHCreateStreamOnFileA(out_file_name, STGM_WRITE | STGM_CREATE, stream));
- if (FAILED(hr)) {
- fprintf(stderr, "Error opening output file %s (%08lx)\n",
- out_file_name, hr);
- }
- return hr;
-}
-
-static HRESULT WriteUsingWIC(const char* out_file_name, REFGUID container_guid,
- unsigned char* rgb, int stride,
- uint32_t width, uint32_t height, int has_alpha) {
- HRESULT hr = S_OK;
- IWICImagingFactory* factory = NULL;
- IWICBitmapFrameEncode* frame = NULL;
- IWICBitmapEncoder* encoder = NULL;
- IStream* stream = NULL;
- WICPixelFormatGUID pixel_format = has_alpha ? GUID_WICPixelFormat32bppBGRA
- : GUID_WICPixelFormat24bppBGR;
-
- IFS(CoInitialize(NULL));
- IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL,
- CLSCTX_INPROC_SERVER,
- MAKE_REFGUID(IID_IWICImagingFactory),
- (LPVOID*)&factory));
- if (hr == REGDB_E_CLASSNOTREG) {
- fprintf(stderr,
- "Couldn't access Windows Imaging Component (are you running "
- "Windows XP SP3 or newer?). PNG support not available. "
- "Use -ppm or -pgm for available PPM and PGM formats.\n");
- }
- IFS(CreateOutputStream(out_file_name, &stream));
- IFS(IWICImagingFactory_CreateEncoder(factory, container_guid, NULL,
- &encoder));
- IFS(IWICBitmapEncoder_Initialize(encoder, stream,
- WICBitmapEncoderNoCache));
- IFS(IWICBitmapEncoder_CreateNewFrame(encoder, &frame, NULL));
- IFS(IWICBitmapFrameEncode_Initialize(frame, NULL));
- IFS(IWICBitmapFrameEncode_SetSize(frame, width, height));
- IFS(IWICBitmapFrameEncode_SetPixelFormat(frame, &pixel_format));
- IFS(IWICBitmapFrameEncode_WritePixels(frame, height, stride,
- height * stride, rgb));
- IFS(IWICBitmapFrameEncode_Commit(frame));
- IFS(IWICBitmapEncoder_Commit(encoder));
-
- if (frame != NULL) IUnknown_Release(frame);
- if (encoder != NULL) IUnknown_Release(encoder);
- if (factory != NULL) IUnknown_Release(factory);
- if (stream != NULL) IUnknown_Release(stream);
- return hr;
-}
-
-static int WritePNG(const char* out_file_name,
- const WebPDecBuffer* const buffer) {
- const uint32_t width = buffer->width;
- const uint32_t height = buffer->height;
- unsigned char* const rgb = buffer->u.RGBA.rgba;
- const int stride = buffer->u.RGBA.stride;
- const int has_alpha = (buffer->colorspace == MODE_BGRA);
-
- return SUCCEEDED(WriteUsingWIC(out_file_name,
- MAKE_REFGUID(GUID_ContainerFormatPng),
- rgb, stride, width, height, has_alpha));
-}
-
-#elif defined(WEBP_HAVE_PNG) // !HAVE_WINCODEC_H
-static void PNGAPI error_function(png_structp png, png_const_charp dummy) {
- (void)dummy; // remove variable-unused warning
- longjmp(png_jmpbuf(png), 1);
-}
-
-static int WritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
- const uint32_t width = buffer->width;
- const uint32_t height = buffer->height;
- unsigned char* const rgb = buffer->u.RGBA.rgba;
- const int stride = buffer->u.RGBA.stride;
- const int has_alpha = (buffer->colorspace == MODE_RGBA);
- png_structp png;
- png_infop info;
- png_uint_32 y;
-
- png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
- NULL, error_function, NULL);
- if (png == NULL) {
- return 0;
- }
- info = png_create_info_struct(png);
- if (info == NULL) {
- png_destroy_write_struct(&png, NULL);
- return 0;
- }
- if (setjmp(png_jmpbuf(png))) {
- png_destroy_write_struct(&png, &info);
- 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_bytep row = rgb + y * stride;
- png_write_rows(png, &row, 1);
- }
- png_write_end(png, info);
- png_destroy_write_struct(&png, &info);
- return 1;
-}
-#else // !HAVE_WINCODEC_H && !WEBP_HAVE_PNG
-static int WritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
- (void)out_file;
- (void)buffer;
- fprintf(stderr, "PNG support not compiled. Please install the libpng "
- "development package before building.\n");
- fprintf(stderr, "You can run with -ppm flag to decode in PPM format.\n");
- return 0;
-}
-#endif
-
-static int WritePPM(FILE* fout, const WebPDecBuffer* const buffer, int alpha) {
- const uint32_t width = buffer->width;
- const uint32_t height = buffer->height;
- const unsigned char* const rgb = buffer->u.RGBA.rgba;
- const int stride = buffer->u.RGBA.stride;
- const size_t bytes_per_px = alpha ? 4 : 3;
- uint32_t y;
-
- if (alpha) {
- fprintf(fout, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\n"
- "TUPLTYPE RGB_ALPHA\nENDHDR\n", width, height);
- } else {
- fprintf(fout, "P6\n%d %d\n255\n", width, height);
- }
- for (y = 0; y < height; ++y) {
- if (fwrite(rgb + y * stride, width, bytes_per_px, fout) != bytes_per_px) {
- return 0;
- }
- }
- return 1;
-}
-
-static int WriteAlphaPlane(FILE* fout, const WebPDecBuffer* const buffer) {
- const uint32_t width = buffer->width;
- const uint32_t height = buffer->height;
- const unsigned char* const a = buffer->u.YUVA.a;
- const int a_stride = buffer->u.YUVA.a_stride;
- uint32_t y;
- assert(a != NULL);
- fprintf(fout, "P5\n%d %d\n255\n", width, height);
- for (y = 0; y < height; ++y) {
- if (fwrite(a + y * a_stride, width, 1, fout) != 1) {
- return 0;
- }
- }
- return 1;
-}
-
-// format=PGM: save a grayscale PGM file using the IMC4 layout
-// (http://www.fourcc.org/yuv.php#IMC4). This is a very convenient format for
-// viewing the samples, esp. for odd dimensions.
-// format=YUV: just save the Y/U/V/A planes sequentially without header.
-static int WritePGMOrYUV(FILE* fout, const WebPDecBuffer* const buffer,
- OutputFileFormat format) {
- const int width = buffer->width;
- const int height = buffer->height;
- const WebPYUVABuffer* const yuv = &buffer->u.YUVA;
- int ok = 1;
- int y;
- const int pad = (format == YUV) ? 0 : 1;
- const int uv_width = (width + 1) / 2;
- const int uv_height = (height + 1) / 2;
- const int out_stride = (width + pad) & ~pad;
- const int a_height = yuv->a ? height : 0;
- if (format == PGM) {
- fprintf(fout, "P5\n%d %d\n255\n",
- out_stride, height + uv_height + a_height);
- }
- for (y = 0; ok && y < height; ++y) {
- ok &= (fwrite(yuv->y + y * yuv->y_stride, width, 1, fout) == 1);
- if (format == PGM) {
- if (width & 1) fputc(0, fout); // padding byte
- }
- }
- if (format == PGM) { // IMC4 layout
- for (y = 0; ok && y < uv_height; ++y) {
- ok &= (fwrite(yuv->u + y * yuv->u_stride, uv_width, 1, fout) == 1);
- ok &= (fwrite(yuv->v + y * yuv->v_stride, uv_width, 1, fout) == 1);
- }
- } else {
- for (y = 0; ok && y < uv_height; ++y) {
- ok &= (fwrite(yuv->u + y * yuv->u_stride, uv_width, 1, fout) == 1);
- }
- for (y = 0; ok && y < uv_height; ++y) {
- ok &= (fwrite(yuv->v + y * yuv->v_stride, uv_width, 1, fout) == 1);
- }
- }
- for (y = 0; ok && y < a_height; ++y) {
- ok &= (fwrite(yuv->a + y * yuv->a_stride, width, 1, fout) == 1);
- if (format == PGM) {
- if (width & 1) fputc(0, fout); // padding byte
- }
- }
- return ok;
-}
-
-static void SaveOutput(const WebPDecBuffer* const buffer,
- OutputFileFormat format, const char* const out_file) {
- FILE* fout = NULL;
- int needs_open_file = 1;
- int ok = 1;
- Stopwatch stop_watch;
-
- if (verbose)
- StopwatchReadAndReset(&stop_watch);
-
-#ifdef HAVE_WINCODEC_H
- needs_open_file = (format != PNG);
-#endif
- if (needs_open_file) {
- fout = fopen(out_file, "wb");
- if (!fout) {
- fprintf(stderr, "Error opening output file %s\n", out_file);
- return;
- }
- }
-
- if (format == PNG) {
-#ifdef HAVE_WINCODEC_H
- ok &= WritePNG(out_file, buffer);
-#else
- ok &= WritePNG(fout, buffer);
-#endif
- } else if (format == PAM) {
- ok &= WritePPM(fout, buffer, 1);
- } else if (format == PPM) {
- ok &= WritePPM(fout, buffer, 0);
- } else if (format == PGM || format == YUV) {
- ok &= WritePGMOrYUV(fout, buffer, format);
- } else if (format == ALPHA_PLANE_ONLY) {
- ok &= WriteAlphaPlane(fout, buffer);
- }
- if (fout) {
- fclose(fout);
- }
- if (ok) {
- printf("Saved file %s\n", out_file);
- if (verbose) {
- const double write_time = StopwatchReadAndReset(&stop_watch);
- printf("Time to write output: %.3fs\n", write_time);
- }
- } else {
- fprintf(stderr, "Error writing file %s !!\n", out_file);
- }
-}
-
-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"
- "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"
- " -pgm ......... save the raw YUV samples as a grayscale PGM\n"
- " file with IMC4 layout.\n"
- " -yuv ......... save the raw YUV samples in flat layout.\n"
- "\n"
- " Other options are:\n"
- " -version .... print version number and exit.\n"
- " -nofancy ..... don't use the fancy YUV420 upscaler.\n"
- " -nofilter .... disable in-loop filtering.\n"
- " -mt .......... use multi-threading\n"
- " -crop <x> <y> <w> <h> ... crop output with the given rectangle\n"
- " -scale <w> <h> .......... scale the output (*after* any cropping)\n"
- " -alpha ....... only save the alpha plane.\n"
- " -h ....... this help message.\n"
- " -v ....... verbose (e.g. print encoding/decoding times)\n"
-#ifndef WEBP_DLL
- " -noasm ....... disable all assembly optimizations.\n"
-#endif
- );
-}
-
-static const char* const kStatusMessages[] = {
- "OK", "OUT_OF_MEMORY", "INVALID_PARAM", "BITSTREAM_ERROR",
- "UNSUPPORTED_FEATURE", "SUSPENDED", "USER_ABORT", "NOT_ENOUGH_DATA"
-};
-
-int main(int argc, const char *argv[]) {
- const char *in_file = NULL;
- const char *out_file = NULL;
-
- WebPDecoderConfig config;
- WebPDecBuffer* const output_buffer = &config.output;
- WebPBitstreamFeatures* const bitstream = &config.input;
- OutputFileFormat format = PNG;
- int c;
-
- if (!WebPInitDecoderConfig(&config)) {
- fprintf(stderr, "Library version mismatch!\n");
- return -1;
- }
-
- for (c = 1; c < argc; ++c) {
- if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
- Help();
- return 0;
- } else if (!strcmp(argv[c], "-o") && c < argc - 1) {
- out_file = argv[++c];
- } else if (!strcmp(argv[c], "-alpha")) {
- format = ALPHA_PLANE_ONLY;
- } else if (!strcmp(argv[c], "-nofancy")) {
- config.options.no_fancy_upsampling = 1;
- } else if (!strcmp(argv[c], "-nofilter")) {
- config.options.bypass_filtering = 1;
- } else if (!strcmp(argv[c], "-pam")) {
- format = PAM;
- } else if (!strcmp(argv[c], "-ppm")) {
- format = PPM;
- } else if (!strcmp(argv[c], "-version")) {
- const int version = WebPGetDecoderVersion();
- printf("%d.%d.%d\n",
- (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
- return 0;
- } else if (!strcmp(argv[c], "-pgm")) {
- format = PGM;
- } else if (!strcmp(argv[c], "-yuv")) {
- format = YUV;
- } else if (!strcmp(argv[c], "-mt")) {
- config.options.use_threads = 1;
- } else if (!strcmp(argv[c], "-crop") && c < argc - 4) {
- config.options.use_cropping = 1;
- config.options.crop_left = strtol(argv[++c], NULL, 0);
- config.options.crop_top = strtol(argv[++c], NULL, 0);
- config.options.crop_width = strtol(argv[++c], NULL, 0);
- config.options.crop_height = strtol(argv[++c], NULL, 0);
- } else if (!strcmp(argv[c], "-scale") && c < argc - 2) {
- config.options.use_scaling = 1;
- config.options.scaled_width = strtol(argv[++c], NULL, 0);
- config.options.scaled_height = strtol(argv[++c], NULL, 0);
- } else if (!strcmp(argv[c], "-v")) {
- verbose = 1;
-#ifndef WEBP_DLL
- } else if (!strcmp(argv[c], "-noasm")) {
- VP8GetCPUInfo = NULL;
-#endif
- } else if (argv[c][0] == '-') {
- fprintf(stderr, "Unknown option '%s'\n", argv[c]);
- Help();
- return -1;
- } else {
- in_file = argv[c];
- }
- }
-
- if (in_file == NULL) {
- fprintf(stderr, "missing input file!!\n");
- Help();
- return -1;
- }
-
- {
- Stopwatch stop_watch;
- VP8StatusCode status = VP8_STATUS_OK;
- int ok;
- size_t data_size = 0;
- const uint8_t* data = NULL;
-
- if (!ExUtilReadFile(in_file, &data, &data_size)) return -1;
-
- if (verbose)
- StopwatchReadAndReset(&stop_watch);
-
- status = WebPGetFeatures(data, data_size, bitstream);
- if (status != VP8_STATUS_OK) {
- goto end;
- }
-
- if (bitstream->has_animation) {
- fprintf(stderr,
- "Error! Decoding of an animated WebP file is not supported.\n"
- " Use webpmux to extract the individual frames or\n"
- " vwebp to view this image.\n");
- }
-
- switch (format) {
- case PNG:
-#ifdef HAVE_WINCODEC_H
- output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR;
-#else
- output_buffer->colorspace = bitstream->has_alpha ? MODE_RGBA : MODE_RGB;
-#endif
- break;
- case PAM:
- output_buffer->colorspace = MODE_RGBA;
- break;
- case PPM:
- output_buffer->colorspace = MODE_RGB; // drops alpha for PPM
- break;
- case PGM:
- case YUV:
- output_buffer->colorspace = bitstream->has_alpha ? MODE_YUVA : MODE_YUV;
- break;
- case ALPHA_PLANE_ONLY:
- output_buffer->colorspace = MODE_YUVA;
- break;
- default:
- free((void*)data);
- return -1;
- }
- status = WebPDecode(data, data_size, &config);
-
- if (verbose) {
- const double decode_time = StopwatchReadAndReset(&stop_watch);
- printf("Time to decode picture: %.3fs\n", decode_time);
- }
- end:
- free((void*)data);
- ok = (status == VP8_STATUS_OK);
- if (!ok) {
- fprintf(stderr, "Decoding of %s failed.\n", in_file);
- fprintf(stderr, "Status: %d (%s)\n", status, kStatusMessages[status]);
- return -1;
- }
- }
-
- if (out_file) {
- printf("Decoded %s. Dimensions: %d x %d%s. Now saving...\n", in_file,
- output_buffer->width, output_buffer->height,
- bitstream->has_alpha ? " (with alpha)" : "");
- SaveOutput(output_buffer, format, out_file);
- } else {
- printf("File %s can be decoded (dimensions: %d x %d)%s.\n",
- in_file, output_buffer->width, output_buffer->height,
- bitstream->has_alpha ? " (with alpha)" : "");
- printf("Nothing written; use -o flag to save the result as e.g. PNG.\n");
- }
- WebPFreeDecBuffer(output_buffer);
-
- return 0;
-}
-
-//------------------------------------------------------------------------------
diff --git a/examples/test.webp b/examples/test.webp
deleted file mode 100644
index 3e4bca1d..00000000
--- a/examples/test.webp
+++ /dev/null
Binary files differ
diff --git a/examples/test_ref.ppm b/examples/test_ref.ppm
deleted file mode 100644
index 97719f01..00000000
--- a/examples/test_ref.ppm
+++ /dev/null
@@ -1,4 +0,0 @@
-P6
-128 128
-255
-ËáûËáûËáûËáûËáûËáûËáûËáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÐãýÐãýÐãýÐãýÒäþÒäþÒäþÒäþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒäþÒäþÒäþÒäþÓåÿÓåÿÓåÿÓåÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèýÔèýÔèýÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷ËáûËáûËáûËáûËáûËáûËáûËáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÏäýÐãýÐãýÐãýÒäþÒäþÒäþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒäþÒäþÒäþÒäþÓåÿÓåÿÓåÿÓåÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèýÔèýÔèýÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷ËáûËáûËáûËáûËáûËáûËáûËáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÏäûÏäûÏäûÏäûÐåýÐåýÐåýÐåýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒäþÒäþÒäþÒäþÓåÿÓåÿÓåÿÓåÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèýÔèýÔèýÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷ËáûËáûËáûËáûËáûËáûËáûËáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÌáûÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÎåûÎåûÎåûÎåûÏæýÏæýÏæýÏæýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒäþÒäþÒäþÒäþÓåÿÓåÿÓåÿÓåÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèýÔèýÔèýÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷Ïå÷ËáûËáûËáûËáûÌâýÌâýÌâýÌâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÎåûÎåùÎåùÎåùÏæúÏæúÏæúÏæýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÓåÿÓåÿÓåÿÓåÿÔæÿÔæÿÔæÿÔæÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÒèùÒèùÒèùÒèùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ËáûËáûËáûËáûÌâýÌâýÌâýÌâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåýÒèûÒèûÒèûÒèûÐæúÐæúÐæúÐæúÐåýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÓåÿÓåÿÓåÿÓåÿÔæÿÔæÿÔæÿÔæÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÒèùÒèùÒèùÒèùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ËáûËáûËáûËáûÌâýÌâýÌâýÌâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäÿÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåýÐæúÒåøÒåøÒåøÒåøÒåøÒåøÐæúÐåýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÓåÿÓåÿÓåÿÓåÿÔæÿÔæÿÔæÿÔæÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÒèùÒèùÒèùÒèùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ËáûËáûËáûËáûÌâýÌâýÌâýÌâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäÿÐãÿÐãÿÐãÿÏäýÏäýÏäýÐãýÒäþÒåýÒåýÒåýÏáóÏáóÏáóÏáñÔåöÔåöÔåöÔåøÒåúÒåýÒåýÐåýÐåýÐåýÐåýÐåþÓåÿÓåÿÓåÿÓåÿÔæÿÔæÿÔæÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÔèÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéÿÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÔêûÔêûÔêûÔêûÔêûÔêûÔêûÔêûÓéúÓéúÓéúÓéúÒèùÒèùÒèùÒèùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒæÿÐåþÒäþÐãýÎáúÒâûÐáúÕåÿÎáýÔæÿÔæÿÓãýÏßøÉÚð·Æ܇–ª‰—©›­±»ÎŸª»©³ÅÌÖèÖáòÓáñÖèøÔåö×éûÒåøÒåúÖêÿÐæúÒæþÓæþÓæþÓæþÓæþÔèÿÔèÿÔèÿÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÕëÿÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëý×ëþ×ëþ×ëþ×ëþÖêýÖêýÖêýÖêýÕéûÕéûÕéûÕéûÔèúÔèúÔèúÔèúÓæùÓæùÓæùÓæùÒåøÒåøÒåøÒåøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒäþÒäþÓãý×èÿÕãþÒßúÕäÿÌÛøÈÙò«Åm{•dqˆhtŒlvŒs{…‹y‘‡Ÿ‘—¨¤ªº°¶Æ½ÆÕÎÜêÓäóÕæ÷ÔåöÖèúÓæùÐäùÔêþÓæûÓæûÓæûÓæûÔèýÔèýÔèýÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëý×ëþ×ëþ×ëþ×ëþÖêýÖêýÖêýÖêýÕéûÕéûÕéûÕéûÔèúÔèúÔèúÔèúÓæùÓæùÓæùÓæùÒåøÒåøÒåøÒåøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÌáùÎãûÓåÿÕèÿÒâûÓãýÔâýÙæÿÓáû©·Òlz•\j„mz”hqŒmw‚‹¡†‰ž¥‚–‡‹ž‚”°³Å¸½Ë•›©¿ËÙÓãòÖæö×æøÔåöÖèúÕéûÐä÷ÓæûÓæûÓæûÓæûÔèýÔèýÔèýÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëý×ëþ×ëþ×ëþ×ëþÖêýÖêýÖêýÖêýÕéûÕéûÕéûÕéûÔèúÔèúÔèúÔèúÓæùÓæùÓæùÓæùÒåøÒåøÒåøÒåøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ÍâýÍâýÍâýÍâýÎãþÎãþÎãþÎãþÎãûÎãûÎãûÎãûÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÓèÿÒæÿÐãýÏâûÓãýÕåÿ±¿Úªr€›Wd~\i‚~‹¤˜¢½jq‡Žªz˜„…›œ²‚„š…†›‚…–—š©²´Á¯³¿–Ÿ¬±½ËÆÔäÔâòÙèùÔãôÖèúÕæùÓæûÓæûÓæûÓæûÔèýÔèýÔèýÔèýÕéþÕéþÕéþÕéþÕéþÕéþÕéþÕéþÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëýÕëý×ëþ×ëþ×ëþ×ëþÖêýÖêýÖêýÖêýÕéûÕéûÕéûÕéûÔèúÔèúÔèúÔèúÓæùÓæùÓæùÓæùÒåøÒåøÒåøÒåøÐæøÐæøÐæøÐæøÏå÷Ïå÷Ïå÷Ïå÷ÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÓèÿÉÞ÷ÚìÿÔæÿÈÙòy‰£M[vXfVc}[deo‰ipŒ‡Žªfj‡Œ¬xz—}}˜~{•qo†‘¥—–©‰ˆ˜——¤ž¡­ÆÌÚ½ÆÕ˜¢±¯¹ËÖáò×å÷Úèù×æúÖæýÔèýÔèýÔèýÔèýÔèýÔèýÔèýÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþ×íÿ×íÿ×íÿ×íÿ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþÖêýÕéûÔèúÕéûÕéûÕéûÕéûÓæùÓæùÓæùÓæùÓæùÓæùÓæùÓæùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒæÿÒäþÅ×ñfwM]wLZtMZsOXq_f€jq~žrv“rs“ˆ‰©……¤ss‘vs}–ž²›š¬€€šš¥¤¨²·»Ç‹ž‘—¨ˆ‘¡­¶ÈÓÝïÚä÷ÛéúÖèúÔèýÔèýÔèýÔèýÔèýÔèýÔèýÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþ×íÿ×íÿ×íÿ×íÿ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþÖêýÕéûÔèúÕéûÕéûÕéûÕéûÓæùÓæùÓæùÓæùÓæùÓæùÓæùÓæùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒæÿÏäý½ÏéXk…IZsL\vP^yN[tbi‚sx‘Ž“¬€‚Ÿ~€‚‚¢©¨Ë¡}}›qq~—œ²œž­‚…‘±´¿¤¨²„¨¬º{€Ž‰Ÿ˜ž¯³»Î×ßò×å÷ÖèúÔèýÔèýÔèýÔèýÔèýÔèýÔèýÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþ×íÿ×íÿ×íÿ×íÿ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþÖêýÕéûÔèúÕéûÕéûÕéûÕéûÓæùÓæùÓæùÓæùÓæùÓæùÓæùÓæùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÎãþÎãþÎãþÎãþÏäÿÏäÿÏäÿÏäÿÏäýÏäýÏäýÏäýÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåýÐåýÐåþÐåþÍßù[m‡GWqLZtIWrFQmox“›Ÿ´¡¤¸‘•ªyzss¤¤Â½¹Ù²°Ì‰‹£lm„z{vx‰œž««¯¹ÌÏÚ“›Œš›ž©˜›¨„‘•£ª°ÀÔÚê×âó×æúÔèýÔèýÔèýÔèýÔèýÔèýÔèýÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖêÿÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþÖìþ×íÿ×íÿ×íÿ×íÿ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþÖêýÕéûÔèúÕéûÕéûÕéûÕéûÓæùÓæùÓæùÓæùÓæùÓæùÓæùÓæùÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐæøÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÏåÿÏåÿÏæþÏæþÎãúÏåùÖêÿÒåýºÍæk~šJXvLWvLTqFNkQXtlqˆÆÈÚ£¥²áäï··Ä…„–£¢·ÎÍâÝÜïìëû¸¸Å£¢²yy†——£²²»ººÆˆˆ‘•–œž¤­­·•˜£‚…‘¡¥±¬±¿ÕÞíÖå÷×éûÔèúÓæùÔêþÔêþÔéÿÕéþÖêÿÙêýÙêýÙêýÙêýÙêýÙêýÙêýÖêýÖêýÖêýÖêý×ëþ×ëþ×ëþ×ëþ×íÿ×íý×íý×íý×íý×íý×íý×íý×íý×íý×íý×íý×íý×íý×íý×íýÙíýÙíýÙíýÙíý×ìû×ìû×ìû×ìû×íýÖìûÕëúÔêùÔêùÔêùÔêùÔêùÓéøÓéøÓéøÓéøÒè÷Òè÷Òè÷Òè÷ÐæöÐæöÐæöÐæöÐæöÐæöÐæöÐæöÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÏåÿÏåÿÏæþÐåýÕêÿÐäùÏãø¬ÀÕVi‚IXvN\yHPpLSpHOlei†¨“•¢²²»ÚÛáÒÒÛ‚‘”“£º¹ÉÌÌÙ°°»——£ŒŒ˜yy†··À££¬žžª‹›š¡¯­´ªª³»»Åª­¸œŸªšžª£©·ÌÚêÒãóÚëûÚíÿÕéûÔêþÔéÿÕéþÙêýÙêýÙêýÙêýÙêýÙêýÙêýÙêýÖêýÖêýÖêýÖêý×ëþ×ëþ×ëþ×ëþ×íý×íý×íý×íý×íý×íý×íý×íý×ïû×ïû×ïû×ïû×ïû×ïû×ïû×ïûÙíûÙíûÙíûÙíû×ìú×ìú×ìú×ìú×ïûÖíúÕìùÔëøÔëøÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÐèôÐèôÐèôÐèôÐèôÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÏæþÏæþÐåþÐåýÐäûÐäû½ÍãSc{FVpIWtS^}MUtLSpHOllp“•­ˆ‹š¡©Ž‘—‰•jly…‡–wy†“Ÿikxjlysv…ˆ‹šÉÍ×…ˆ“xz‡œ¦¥¯©¨±šš£­­·²¶À•˜£¦«¶‡Ž˜¦²ÀÈÖæ×è÷×éùÙêýÕéþÕéþÕéþÙêýÙêýÙêýÙêýÙêýÙêýÙêýÙêýÖêýÖêýÖêýÖêý×ëþ×ëþ×ëþ×ëþ×íý×íý×íý×íý×íý×íý×íý×íý×ïû×ïû×ïû×ïû×ïû×ïû×ïû×ïûÙíûÙíûÙíûÙíû×ìú×ìú×ìú×ìú×ïûÖíúÕìùÔëøÔëøÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÐèôÐèôÐèôÐèôÐèôÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÏæþÐåýÐåýÒåýÒåý£³ÌTd}IWqIWrQ]{P\zOWwLTqFMjcf„z–il~x{†y}…z~ˆ]_o~€¥¨´kmzikxehw^artwˆŽ~€‡‰˜sv…iit£¢«ÂÂÌ••ž‰—}€‹‘–¡†‹•—ž©ÌÕâÖâðÝëûÜëý×éûÕéûÕéþÙêýÙêýÙêýÙêýÙêýÙêýÙêýÙêýÖêýÖêýÖêýÖêý×ëþ×ëþ×ëþ×ëþ×íý×íý×íý×íý×íý×íý×íý×íý×ïû×ïû×ïû×ïû×ïû×ïû×ïû×ïûÙíûÙíûÙíûÙíû×ìú×ìú×ìú×ìú×ïûÖíúÕìùÔëøÔëøÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÐèôÐèôÐèôÐèôÐèôÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÓèÿÎãúÕéÿÈÜóqšIZrJXrIWrO[yJVtPXxT\{FNkV]zv}˜osX\pqv„fkw‚‡“fj{ˆŒ†‘sx„†‹˜y}Žhkei}X]kty‡‡‹œcewbbo†„°°»½½È±´½ÇËÓ·½Ä¡¦­·»Æ¶ºÅÀÇÒ×ãïÙæ÷ÙèùÖèúÙìÿÖêýÖêýÖêýÖêý×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþÙìÿÙìÿÙìÿÙìÿ×íý×íý×íý×íý×íý×íý×íý×íý×ïû×ïû×ïû×ïû×ïû×ïû×ïû×ïûÙíûÙíûÙíûÙíû×ìú×ìú×ìú×ìúÕìùÕìùÕìùÕìùÔëøÔëøÔëøÔëøÔëøÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÐèôÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåýÎäøÓæûÄ×ï^o‡HXqM[vDQlP\xNZxIUsLTsMUtHPm]e‚krŽSZsSWoW[pfj{qt†txŒjm]arZ^lmq‚^bv[^sdh}fj{dhyil€ehy~~‹˜–£¢¢­©©´¢¥­»¿Çª°·±·¾ÁÅËÌÏ׶ºÅÁÈÓÚåóÚèøÛìýÖêýÖêýÖêýÖêýÖêý×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþ×ëþÙìÿÙìÿÙìÿÙìÿ×íý×íý×íý×íý×íý×íý×íý×íý×ïû×ïû×ïû×ïû×ïû×ïû×ïû×ïûÙíûÙíûÙíûÙíû×ìú×ìú×ìú×ìúÕìùÕìùÕìùÕìùÔëøÔëøÔëøÔëøÔëøÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÐèôÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåýÕéþ²ÆÛTdzEUmM[tAOjWcMXwJSrS[zIQqJSr[c€^f„NWrLSoPTqINhW\sim‚X]tae}V\oX^qU[m]bwW\s]bykq„flV[pTWkqp€•“¡ªª¶˜˜¤ˆŒ”Œ—…‹²¶»·¸»ÌËÏÚÝå½Á̹ÂÏÔâòÛêûÕéûÖêýÕëýÕëýÕëýÖìþÖìþÖìþÖìþ×ëþ×ëþ×ëþ×ëþÙìÿÙìÿÙìÿÙìÿ×íý×íý×íý×íý×íý×íý×íý×íý×ïû×ïû×ïû×ïû×ïû×ïû×ïû×ïûÙíûÙíûÙíûÙíû×ìú×ìú×ìú×ìúÕìùÕìùÕìùÕìùÔëøÔëøÔëøÔëøÔëøÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÐèôÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÐåþÒåý³ÄÚN^tIZpIWqHVqQ_zJXvLWvNZxEPoLWvQZyV^{W_}U\yOVsQUsTWt{€š\azSWqPUoPUlOTiV[pmr‡TXrOTmmr‡x}‘_d{X\qz}Œœœ¨›––¢z~ˆ†‰”{‰ww€Œ‹‘ÆÅÌÌÌÕ¥ª´°·ÁÅÐÞ×åöÛëúÙêúÖêýÖêýÕëýÖìþÖìþÖìþÖìþ×ëþ×ëþ×ëþ×ëþÙìÿÙìÿÙìÿÙìÿ×íý×íý×íý×íý×íý×íý×íý×íý×ïû×ïû×ïû×ïû×ïû×ïû×ïû×ïûÙíûÙíûÙíûÙíû×ìú×ìú×ìú×ìúÕìùÕìùÕìùÕìùÔëøÔëøÔëøÔëøÔëøÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÐèôÒæþÒæþÒæþÒæþÓèÿÓèÿÓèÿÓèÿÒäþÔæÿÕèÿÐãýÐãýÕèÿÕèÿ¨¸ÒZhN[tN[tO]xQ_zM[vLZtL\vJZwBQoP^{Q]{W_W]~W[{UXwQUs\_}hl†TXrLOmIMkDGdDH_EI^‚‡œlq‹TXr~‚š„›TWtaeqv„¦ª´‡‹•~€qp€‡†–Œœ‚€‰‡”¡Ÿ©ÅÅг·Á¡¥°¤©³ÅÌÕÙâìÜêúÞíÿÚëûÖëúÖìû×íý×ðþÙñÿ×íýÙíýÙíýÙíýÙíýÙíýÙíýÙíý×íý×ïû×ïû×ïûÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðúÙðúÙðúÙðú×ïù×ïù×ïù×ïùÖíúÖíúÖíúÖíúÕìùÕìùÕìùÕìùÕìùÔëøÔëøÔëøÓê÷Óê÷ÒéöÒéöÓê÷ÒéöÒéöÒéöÒéöÐèôÐèôÐèôÒæþÒæþÒæþÒæþÓèÿÓèÿÓèÿÓèÿÒäþÖéÿÒäþÓåÿÐãýÐãý}©O_yNZvNVsLWsQ]yLWsN\wN\wHXrIZsHWtSa~S^}[abe†hi‹WXxW[yVZwZ^xTWtPTrOSqNQoBGaINc{€•^c}[_y–›²€…œX\yQVpjo}ˆ—¢¤±­°¿wv†‰ˆ›‰†šš–ª‰‡•rp}——£¿¿Ë„‡¢¥­»ÁÆÉÐÚÝé÷ÙæøÜëýÝïÿÚïþÙïþÖïýÕíû×íýÙíýÙíýÙíýÙíýÙíýÙíýÙíý×ïû×ïû×ïû×ïûÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðúÙðúÙðúÙðú×ïù×ïù×ïù×ïùÖíúÖíúÖíúÖíúÕìùÕìùÕìùÕìùÕìùÕìùÕìùÔëøÓê÷Óê÷Óê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÐèôÒæþÒæþÒæþÒæþÓèÿÓèÿÓèÿÓèÿÔæÿÓãýÖæÿÕåÿÛëÿw‡¡M]wDQlLWsLTqS[xV^{O[wS^zLWsBPkLZtO]xUa}Zbls_copž^bUXv\azW\vGJiHLjMPmFJbIObX^qZ^vy~•Ÿ¥¸w{UZq[_tty‡ty…‡‰–ž…„”‰ˆ˜£¡±¬ªº»»Èvv‚‹ŸŸ«¦ª²©¬´¤¨°¹¾ÈÛæôÛéùÛëúÙêùÛðþÙðýÖïûÕíú×íýÙíýÙíýÙíýÙíýÙíýÙíýÙíý×ïû×ïû×ïû×ïûÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðúÙðúÙðúÙðú×ïù×ïù×ïù×ïùÖíúÖíúÖíúÖíúÕìùÕìùÕìùÕìùÕìùÕìùÕìùÕìùÔëøÓê÷Óê÷Óê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÐèôÒæþÒæþÒæþÒæþÓèÿÓèÿÓèÿÔèÿÖæÿÔäþÓãý×èÿ~Ž¨HXrHXrIWrIUqMUrQZwNVsQZwPXvNVsJVrS_yO\vU^y^eVZw^bsv“†ˆ¥y}šUZs]byX]wPTqPTqMQkNSjPViLQdSWo~‚—ž¤·jp‚]bw[_trv‡UZhZ\kkm}€šš¦±¯½À¾Ì©©¶ffsxx…‰‰•Œš–š¢˜œ¤ž£­ÆÏÞÝëûÜêúÛëúÙíûÖíúÙðýÚñþÙíýÙíýÙíýÙíýÙíýÙíýÙíýÙíý×ïû×ïû×ïû×ïûÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðúÙðúÙðúÙðú×ïù×ïù×ïù×ïùÖíúÖíúÖíúÖíúÕìùÕìùÕìùÕìùÕìùÕìùÕìùÕìùÔëøÔëøÔëøÓê÷Óê÷Óê÷Óê÷Óê÷ÒéöÒéöÒéöÒéöÒæþÒæþÒæþÒæþÒæþÒæþÒæþÓæþÚêÿÏÝøÎÜ÷hvHVqHVqHVqGUpHTpOWtU]zLTqLTqOVsLSpS\wOXqV]wU\v]b{ptŽjoˆkmˆz}—kp‰X]wLPhNSjTWtOSpW\vLPhMQfPUjV[rae}U[mU[mkp…X]r^bv^bvehybdseerŸŸ«©¦³¢Ÿ¬‹‰škm}fixtw„Œ˜˜¢¤±Ÿ¥³ÎÚèÜêøÙéöÞñýÙíùÙðúÕìùÚïþÚïþÚïþÚïþÚïþÚïþÚïþÚïþÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÚñþÚñþÚñþÚñþÚñþÚñþÚñþÚñþÚñûÚñûÚñûÚñûÙðúÙðúÙðúÙðú×ïû×ïû×ïû×ïûÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÕìùÔëøÔëøÔëøÔëøÔëøÔëøÓê÷ÒéöÒéöÒéöÒæþÒæþÒæþÒæþÒæþÒæþÒæþÓæþÕåÿÎÜ÷drFToIWrESmFToMXtS^zU]zHPmLSpJQoU\y\c€sw”[_w\ax^czdi€chchdf_bzSWoNSjX]r\ax\azOTmPUlae}QVmHMdLPjINhMQfdj}y~“ejVZojm‚€–‹œŽ‡‡“¨¦°žž¨y{‹…‡˜€‚‘z}Œ}{Œœ‘‘ž¨ª·•›©ÀÉÙÙäòÙæôÚê÷ÜïúÙíùÛòýÚïýÚïþÚïþÚïþÚïþÚïþÚïþÚïþÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÚñþÚñþÚñþÚñþÚñþÚñþÚñþÚñþÚñûÚñûÚñûÚñûÙðúÙðúÙðúÙðú×ïû×ïû×ïû×ïûÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÕìùÔëøÔëøÔëøÔëøÔëøÓê÷ÒéöÒéöÒæþÒæþÒæþÒæþÒæþÒæþÒæþÓæþÕãþw‚žHTpMXtO[wLWsNZvT_{P\xLTqIQoLSpOSq\_~il‹„¡mpˆSVkdh}…ˆW[p[^sUZoNShV[r_h~^fzw“qx‘PWqPXockDJdGNjNUqFMiXawt}€ˆœV[rSUmtw‘¦”–¨ª››¤±°·‰‹xz‡‚”„†—‹ž}{Œ”“£œš¨´´Á‘–¤¦°½ËÖâÜëöÝíøÝðù×íöÚïúÚïýÚïþÚïþÚïþÚïþÚïþÚïþÚïþÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÚñþÚñþÚñþÚñþÚñþÚñþÚñþÚñþÚñûÚñûÚñûÚñûÙðúÙðúÙðúÙðú×ïû×ïû×ïû×ïûÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÔëøÔëøÔëøÔëøÔëøÔëøÓê÷ÒéöÒæÿÒæþÒæþÒæþÒæþÓæþÓæþÕåþ}‹¥DOkIUqMXtJVrMXtP\xS^zLWvHPpGNkELiNQodh…Œª¦©Ä›ž³[^r{“ilSVkQUjMQfGLaJSf_h{ltˆW_vT[t^eJSiGNhNUqLSoFMjFMiIPjrzV^tLPhOQlxz“˜š°„…š‡†–˜¸·¾•”‚‚„†—„†—xw‰ts„Ÿ››¨´´Á«­º—œ¨©°ºÍÙâÛêòÚêôßòûÜòúÚïýÚïþÚïþÚïþÚïþÚïþÚïþÚïýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÙðýÚñþÚñþÚñþÚñþÚñþÚñþÚñþÚñûÚñûÚñûÚñûÚñûÙðúÙðúÙðúÙðú×ïù×ïû×ïû×ïûÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÖíúÔëøÔëøÔëøÔëøÔëøÔëøÔëøÓê÷ÓèÿÐåþÓåÿÓåÿÒåýÓãûÔäúm{•LWsJSpJSpNVsT\yZbXa~NVvGOqFLoGMmIPlQXrbj~š¢´´ºÍˆ¢fk€im‚\axNSjJOfQVmLPeV[p^cxchFIfMTqHOlFOjNUqZa}FIfQUrMPmTWtej„MQkMQkWZt}šxz“[\rbasfev˜–¤›‹˜ŽŒœŸœ°]\oa_r‹‰šŸŸ¬ÄÄл»Ç¤¤­¡¤¯¦­·Ë×ÞÝìôÝð÷ÝðùÜïúÜíýÜíýÜíýÜñÿÜñÿÛòÿÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÜóþÜóþÜóþÜóþÜóþÜóþÜóþÜóûÛòúÛòúÚñùÚñùÚñùÚñùÚñùÚñùÙðøÙðúÙðúÙðú×ïù×ïù×ïù×ïù×ïù×ïù×ïù×ïùÖíøÖíøÖíøÖíøÕì÷Õì÷Õì÷Õì÷ÔëöÔëöÔëöÓêôÐãýÖéÿÓæþÔäýÔäý×åÿp~—TazNVsLTsLTsNVvV^~V^~NVvEMlGMpNTwLSpFMi[cypxŒ¦¶«´Ä^cx_d{\axW\sTXpNSjNSj\avioZ^sdi‚FIfGNkIOpGOlSZvfk…^c}}›[_yPTqei†OTmNSlbdª]_x]^t{zzyŒœšªŽŒœ•Ÿ—“¤ž›¯]Zm[Zlkj}›¬³³¿º¹Â¾½Ä¬¬¶¨­´±»ÄÐÝäßñøÚêôÝíúÝíúÜïúÜïúÜñýÜñýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷ÖíöÖíöÖíöÖíöÕìôÕìôÕìôÕìôÔëóÔëóÔëóÓêò×éûÒãöÕåû×æýÖäþ„ªIVpW_}PXxMUwMUwPXzU]NVxGOqDLmNTwIOpBIfJQmLTjmv‰¯·Épx‹W\schZ^vMQiSWoOTkPUjaez\btioae}AEbLSpLSpGOlJQkW\sswŒ£¥¾twX[vik†JMjQTopršMOh\]syx‹‰ˆ˜£¡±‹˜˜¨ˆšsp„ro‚a_r^]p‰Œ›¯¯º³²»·¶½ÀÀÉ£ª¯¶¿¿ÌÓÛêòÜì÷ÝíúÝíúÜïúÜïúÜñýÜñýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷ÖíöÖíöÖíöÖíöÕìôÕìôÕìôÕìôÔëóÔëóÔëóÓêòÕåô×è÷Öå÷×äùŒ˜°PZtS\wLTqQZyNVxNVxQZ{OWyHPrFNpIQqQWxW^{LSoMTmHOiS[qz‚–[cwX]wV[tHMf@E\INebf~PUjrx‹iodjzPUjHMfOVrHOlMUrFMiHMdX\qjm‚ei~š€‚›PSkik„wy‘lo‡TWl_av{zŽ¢Ÿ­Žœ¡œ«“ŽŸŒŸ¡rq„ZXkmp¡¡¬–•žº¹ÀËËÔ›ž¦ž¥¯¬·¿ËÖßÛêôÝíúÝíúÜïúÜïúÜñýÜñýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÛòýÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÜóûÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷×ï÷ÖíöÖíöÖíöÖíöÕìôÕìôÕìôÕìôÔëóÔëóÔëóÓêò•¤¯¯¾È½ËÙz…–S\rV]wQXtV]zS[zT\{PXxLTsFNmIQqOWwT\{W^zQXtJQkELeELeNUoU]sGNhGLePTqNSlUZqMQipt‰[_tz€jq{}„ŽX^oHMdT[wOVsNVvSZwUWrHI_TUkrsˆ€•wxhi~st‰UXmMPeUXmst‰Œœ••¢­«¹•“Ÿ¤Ÿ¯ª¥·¨¤¸¢ž²¡Ÿ²qp‚mp››¦¡Ÿ©¬«²´´¾³·¿Ÿ¤¯«²»ª±»ÙäðáïýÜìùáóÿáóÿÜñýÜñýÛòýÛòýÜóþÜóþÜóþÜóþÜóþÜóþÜóþÜóþÝôýÝôýÝôýÝôýÝôýÝôýÝôýÝôýÜóûÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÖíöÖíöÖíöÖíöÖíöÖíöÖíöÖíöÕìôÕìôÕìôÔëóeqzit~NZeOXhPXlX]tX]w[^{QXvS[xS[xPXvNVsQZwT\yT\yMTmMTmBIcAHbMTmELeBIc@GcIMjOSpOTmjoˆrwŽhldj}MScPWaahrMScV[pT[tQXvOWtT[wVXqVWlijqs…actqs…ŒŽvx‰SVjTWlW[ohj{‘¡¦¦³œš¦›¨¶±À£ž°Ž‹žŒˆœ¢š˜«“¢›š˜¢Œ“¹¹ÂÅÅΦª´¯³¾¦«·¶¿ÌáïýÞïûáóÿáóÿÜñýÜñýÛòýÛòýÜóþÜóþÜóþÜóþÜóþÜóþÜóþÜóþÝôýÝôýÝôýÝôýÝôýÝôýÝôýÝôýÜóûÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÖíöÖíöÖíöÖíöÖíöÖíöÖíöÖíöÕìôÕìôÕìôÔë󀉔y‚bkxNTdV\oX\qW[p^aySZsU^yU^yQ[vS\wU^yS\wNWpFNdAI_BJa>E^GNhGNj7>Z;B_?Ba?B_BGaX]wINech}‰¢GM]DIWOUeafy_dyJSiMTmWawdl€[]ofevsr‚hfwfevml}š˜«ž¡²qtˆ_cxadx[]o€¦¦³›¨œš¦­©¸–‘£}yzw‹{z†…—•—¦œŽ–Œ‹‘©©²ÀÀɲ¶À¸»Æ´·Äœ¢°ÁÏÝÜìùáóÿÞñýÜñýÜñýÛòýÛòýÜóþÜóþÜóþÜóþÜóþÜóþÜóþÜóþÝôýÝôýÝôýÝôýÝôýÝôýÝôýÝôýÜóûÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÖíöÖíöÖíöÖíöÖíöÖíöÖíöÖíöÕìôÕìôÕìôÔë󅌖t{†pt€lqhlzehyTVh_avZ^sXatU]sPXoQXrT[tNUoELeAHbDH_AF_@GaELh=Da=Da@Gd>A_>A^JNkHMfAF]PUjOTiOUhX^qsyŒejOTiS[qFNdLViT\pX\pZ\m^arihzdcvjiy‹‰š£¢´rsˆy}~“xz‰wy†„„——£‰‡”~{‰‡…“‰‡—‰†…—‹‰š”–£ŒŒ—š˜¢¸·¾»»Å¾¾Ç¿¿Ë½½È¶¶Áª¯º›¦ÓãðáñþÜïúÞñýÜñýÜñýÛòýÜóþÜóþÜóþÜóþÜóþÜóþÜóþÜóþÝôýÝôýÝôýÝôýÝôýÝôýÝôýÝôýÜóûÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÖíöÖíöÖíöÖíöÖíöÖíöÖíöÖíöÕìôÕìôÕìôÔë󓕘£ˆŒ–‹Ž˜ÆÉÔ±±½šš¥››¨sv‚hjyps…VZmUZqPUoLOlFIhFIhGHhEFeAEc@Db@Dd>Dd>Eb>Eb?FbHOkFMiAHbAHbBIcNVlXatS[m]eydl€U]sLSlJQkLSlTWtHJhOQj]^tcdyxz‰±±¾‡†–mp}~“‘”£ž¡­–˜¥‚…‘Žvv‚Œss€‹‹—Žž€……‘““Ÿ©œ›¤­¬¶º¹Â¾½Æ¤£¬¹¸Á¾½Æ²¶À—ž©œ¨³ßïùáñûÛíùßòþÝòÿÚïúÞóÿÞôýÞôýÞôýÞôýÞôýÞôýÞôýÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÝöúÝöúÝöúÝöúÜôùÜôùÜôùÜôùÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÕïöÕïöÕïöÕïöÔíôÔíôÔíôÓì󖉋›œ¢¢£©³´ºÙÚßÈÉϬ­³½¾Ä··À¨ª·[]obc{bdMNmIMkJLkLMlIJjFGi@Dd@Dd>Dd>Eb?Fb>EaGNjDJfBIeAHd?FbFMfDLb@H\IQeckQZpIPjFMfOVrMPoLOmPSm]_x]^spr„……‘~}“~€‘vx‡‡‰–¢¥°£¥²prvx‡Ž……‘ss€ŽŽ›~~‹šªš—¤œ›¤¤£¬ÓÒÛ¤£¬­¬¶³²»°°¹±¶À‚Œ–ÒÝéßïùáñþáóÿßôÿÝòþÞôýÞôýÞôýÞôýÞôýÞôýÞôýÞôýÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÝöúÝöúÝöúÝöúÜôùÜôùÜôùÜôùÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÕïöÕïöÕïöÕïöÔíôÔíôÔíôÓìóÁÂƤ¥©Œ”•˜—˜œÞßãÎÏÓÅÆÉ¿ÀÄ´¶»··Â{zcd}hh†VWyLMoILiJMjHJhEFe@Db@Db>Eb>Eb?Fb>EaELhAHdAHdAHd>Ea@GcELh>E^ELe]e{JSiGOcNVjV^rPUoNSlOQjX\qQShbdvom€{z{}‘mpQTc[]j…ˆ“‹š†ˆ—ŒŽ††“ddqbboyy†ˆˆ•ŒŒ˜œ““Ÿ›¨›š£ž¦²±ºž¦¦¥¯¡Ÿ©š´¹Ä˜Ÿª¬¶ÀâíùáñûÞñýÛðûÝòþÞôýÞôýÞôýÞôýÞôýÞôýÞôýÞôýÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÝöúÝöúÝöúÝöúÜôùÜôùÜôùÜôùÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÕïöÕïöÕïöÕïöÔíôÔíôÔíôÓìóÉËÍ´¶¸¦¨ª‘“•‹ŒŽ·¸ºÜÝßÚÛݸ¹»²³·ÇÇЪ©¹zxdd€__NOoDFaDFaAD^?A^@Da@Db>Eb>Eb@Gc>EaDJf?Fb=D_@Gc>Ea@GcFMi@GcJQkXawPXoJSfXasPXlGLcQVm\_tQUjSTi\^pts„vt‡‚—ik}UWfikxx{†…‡”‡‰˜‘¡^^kzz‡‚‚‰‰–‡‡”‘‘ž””¡”‘ž£¢«¡Ÿ©±°¹†…Ž£¢«¢¡ªŸŸ©²¶À­²½‹‘œÚãíãòýáóýÞóÿáöÿÞôýÞôýÞôýÞôýÞôýÞôýÞôýÞôýÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÝöúÝöúÝöúÝöúÜôùÜôùÜôùÜôùÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ï÷×ï÷×ï÷×ï÷ÕïöÕïöÕïöÕïöÔíôÔíôÔíôÓì󩫪¾À¿‘”“ˆ‹‰mpoz}{ËÍÌßâáÖÖÖÒÒÔÁÀÇÀ¾Ë²±Ä–”«de~OOkHLaGJ_HJcFHa@E^=@]:A]=D_>Ea?Fb>Ea;B^>Ea?Fb@GcAHdMTmSZsHPfFNdS[qOWmQZpLTjJOi_d{JNc_cw]_qjl{llyŒy{VXjWZirtlpz€‚•—¦¢¤³””¡ww„}}‰‹‹—††“””¡¡¡­““Ÿ›˜¥”“œ›š£ÆÅΣ¢«ž¦ª©²°¯¸ßß黻ǔ˜£ºÄÎÝìôáóýßöþÛòúÞôýÞôýÞôýÞôýßöþßöþßöþßöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞ÷ûÞ÷ûÞ÷ûÞ÷ûÝöúÝöúÝöúÝöúÜóûÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ñø×ñø×ñø×ñøÖð÷Öð÷Öð÷Õïö~±²´‰‹‚…deh‘”¯°²ÎÎθ¶·ÓÐÔÜÚÞÒÐ×°­ºª©¹wvˆWXmOSdNQeNQeLOd@E\>B\:A]>Ea?Fb>Ea;B^=D_@Gc?Fb>Ea=D]=E[FNdDLbMUkS[qQZpT[tU\vV[rejTWlX\pcewjlyyy…ŽŽ›y{\^plo~y{ˆ‹Ž˜”–£vx‡~€••¢‘‘ž‚‚““Ÿ••¢‰‰–––£˜˜¥Ÿª¡Ÿ©¦¥¯Ÿž¨±°¹£¢«©¨±ª©²±°¹´³½¬°º‹‘›ßëôÛíôÞôýß÷ÿÞôýÞôýÞôýÞôýßöþßöþßöþßöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞ÷ûÞ÷ûÞ÷ûÞ÷ûÝöúÝöúÝöúÝöúÜóûÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ñø×ñø×ñø×ñøÖð÷Öð÷Öð÷Õïö¡¢¥”•˜‚„‡{}€dei…†‰˜šššœ›˜šÅÀÁÛÙÜÓÐÔÍÌÐÆÅÌ°°¹eisV[fTXfQUfOSfAF]>B\;B^?Fb>Ea;B^=D_=D_?Fb>Ea=D_;B\BJaEMa@H^MUkIQhJSiNUoV^tdi~{”W[odhysv…z}Œ¢¢¯qp€VXjxzŒrt„vx…€„Ž“•¢fixdfvŽŽ›ww„‡‡”££°¾¾Ë——¤››¨œš¦š˜¢¯­·ÁÀÉ¥¤­´³½­¬¶°¯¸¦£«ÍÉÔ½½Æž£­©¶½Þð÷ÞôúÝöúÞôýÞôýÞôýÞôýßöþßöþßöþßöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞöþÞ÷ûÞ÷ûÞ÷ûÞ÷ûÝöúÝöúÝöúÝöúÜóûÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ñø×ñø×ñø×ñøÖð÷Öð÷Öð÷Õïö°±´°±´¥¦ªŽ“{}€efjmor_^c¯¬°ÕÓÖ—•˜¦¤¨”Œ‹•–œ‰‰“^blV[fSWePTeBF[?D[?B_>Ea;B^=D_=D_>Ea:A];B^=D_>EaFNdAI_;DZJQkHOiBIc;B\AHbV[pafy]arhlzy{‹ž­jiywy‹bdvjl{}Œfiv~€oq~zz‡˜˜¤ŽŽšœ‡‡“~~‰““Ÿ««¸““žœ›¤¡Ÿ©˜—¡£¢«œ¥ª©²Ÿž¨¶´»¥¢ªÒÐ×ÀÁǯ´»¥°¶Úéðßñ÷ãöýÞôúÞôýÞôýÞôýßöþßöûßöûßöûÞöþÞöþÞöþÞöþÞöþÞ÷ûÞ÷ûÞ÷ûÞ÷ûÞ÷ûÞ÷ûÞ÷ûÝöúÝöúÝöúÝöúÜôùÜóûÜóûÜóûÛòúÛòúÛòúÛòúÚñùÚñùÚñùÚñùÙðøÙðøÙðøÙðø×ñø×ñø×ñø×ñøÖð÷Öð÷Öð÷Õïö¶´¹¨¦«Ÿž£š˜~}zy~‹‰Žtsxqpt«ª¯ÄÂÉŒ“VU^WV_ljwyy…lpzTWbSVaUWfGJ^GIb@Da>Eb?Fc>Gb=Fa;E];E];E_;E_;E_?Ha?Ha?Ha?Hc@Id>Gb>GbAHdMQiNSh_ctqv„‡‰–Žvt…sr‚zy‰kjzvt…~Žyy†••¢““Ÿ––¢±°¹©¨¯ž¦•”€‰”‘žŽ›¡ž«¢¡ª—–Ÿ‹‰£¢©ÐÏÖª©°¥¤«°¯³±°´ª«¯³¸º²¶»°¶½´»ÂÖáæßïöáóúÝöúÞ÷ûÞ÷ûßøýáùýâøýá÷ûá÷ýá÷ýá÷ýá÷ýâøþâøýâøýâøýáùýáùýßøûÞ÷úÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöúÝöúÝöúÜôùÜôùÜôùÜôùÛóøÛóøÛóøÛóøÚò÷Úò÷Úò÷Úò÷×ñö×ñö×ñö×ñöÖðôÖðôÖðôÕïórqv¥¤©›šžœ›Ÿ{z“‘–„‚‡wvz€†¥¤«º¹Â˜—¡a^k_]jb_mdbpss\_hNQ\\^kNQeGIbDGd>A_?Fc>Fc=Fa;E];E];E_;Da;Da>Gb>G_>Gb>Gb=Fa=Fa?GdELhUZsOTi]ar€…“‚…‘sv‚yxˆkjzom~dcs~Ž‰ˆ˜~~‹}}‰šš¥““œ°¯¶¬«°¨¦­›š¡•”¬«´”‘ž”‘ž¥¤­–•ž”“š¢¡¨´³¸ÅÄÈÓÒÖ½»À¬­°ª«­º»¿»¿Å¤¨°ÀÆÍž¤«äï÷âôûÞ÷ûÝöúÜôùâúþÞ÷úß÷øãùþá÷ýá÷ýá÷ýá÷ýâøýâøýâùúâùúáùýáùýßøûÞ÷úÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöùÝöùÝöùÜôøÜôøÜôøÜôøÛóøÛóøÛóøÛóøÚò÷Úò÷Úò÷Úò÷×òô×òô×òô×òôÖñóÖñóÖñóÕðò}{€wvzrqvvty€…°¯³¡Ÿ¤”‹‰‰ˆ‰ˆ‘š˜¢„ŽŒ‰–a^lZWe^^j[^iZ]h]_lPTeJNcGLe@Db?Fc>Fc=Fa;E_;E_;E_;Da;Da=Fa=F^=Fa=Fa=Fa=Fa?GdELh\azOTicfx€…“jly\^k{z‹_^oVUebaqqp€~Ž}}‰ss€˜–©¨¯«ª¯¯­´œ£¡Ÿ©ÆÅΨ¥²Ž›­¬¶‘šž¤¥¤«¡Ÿ¤ÂÁÆëêïÌËÏÆÆȱ±³ÅÆɾ¿Å¯²º½ÀÈ“˜ŸÁÌÔßñøßöûÞôúßöûßöúãùþâúûÞ÷úá÷ýá÷ýá÷ýá÷ýâøýâøýâùúâùúáùýáùýßøûÞ÷úÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöùÝöùÝöùÜôøÜôøÜôøÜôøÛóøÛóøÛóøÛóøÚò÷Úò÷Úò÷Úò÷×òô×òô×òô×òôÖñóÖñóÖñóÕðò¿¾Â‰ˆ\[_edi„‚‡±°´¶´¹—–›”“š‹‰„‚Œ[Zc…‚¿½É“žcao]]iVZdkoy_boNQcNQfGLeGJh?Fb>Fc=Fa;E_;E_;E_;Da;E_=F^=F^=Fa=Fa@Id>Gb>FcAHdGLeX]rcfxdiw]_leht~Žbaq\[ksr‚xw‡{z‹‚‚yy†‰‰•••ž£¢©ª©­³²¹ž¤”“œª©²¡ž«¤¢¯·¶¿Œ‹”¤£ªª©°¦¥ª©¨¬ÇÆËÁÀŽ½¿¿¿Áº¹¾ÆÇ͹¹Â¾ÁɾÁÉ”ÒáéÞñøä÷þäúÿâøýá÷ûßøùáùýá÷ýá÷ýá÷ýá÷ýâøýâøýâùúâùúáùýáùýßøûÞ÷úÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöùÝöùÝöùÜôøÜôøÜôøÜôøÛóøÛóøÛóøÛóøÚò÷Úò÷Úò÷Úò÷×òô×òô×òô×òôÖñóÖñóÖñóÕðò©¨¬´³¸edi~‚¡Ÿ¤—–›­¬±¬«°š˜Ÿ–•œž¦~}†WUb¬ª·ÍËÙhesbbmps~Z]ecfq_drMPdINeJOiAHd=Fa=Eb;Da;Da;Da;E_;E_;E];E];E_;E_>Gb;E_AIfJQmJOiW\qZ]olq_boz}‰€ml}ihxrq~}vt…tttt””Ÿ¦¬«²¬«°ª©°š˜Ÿ“‘›ž¦¥£°½ºÇ¦¥¯–•žŒ“š˜Ÿœ›Ÿ¦¥ª¿¾ÂÆÅÉÀ¾ÁÅÂÆ¿¾ÂÔÓÚ²²»»»Å¾ÁÉŸ¤¯…šÉÙáäöýÜïöá÷ûãùþãûýäýÿâøþâøþâøþâøþâøýâøýâùúâùúáùýáùýáùýáùýßøûßøûßøûßøûÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöùÝöùÝöùÛó÷Ûó÷Ûó÷Ûó÷ÚòöÚòöÚòöÚòö×òô×òô×òô×òôÖñóÖñóÖñóÕðò»º¿ÂÁÆ¡Ÿ¤Œ‹©¨¬£¢¦–•š”“—¨¦­œ›¢ž¦°¯¸‚€[Xe^\j¸¶Ä]]iX\f_ck\_jlq}fj{DH]GLcDJd>Gb=Eb;Da;Da;Da;E_;E_;E];E];E_;E_=Fa;E_?GdGNjPUoQVkSVhlqvx…y{ˆedtedtxw‡xw‡sr‚„‚“‰‰–qq~‰‰•¨¨±ÆÅ̽»À±°·½»ÂŸž¨Ž—“{y†€ˆ˜¤£ª“‘˜”¦¥ª»º¿ËÉÎÈÆÉËÈÌÂÀÅÀ¿Æ»ºÄ¿¿ÈÂÂÌ°´¿}†œ¥ßï÷èùÿáôùá÷ûáùúáùýâøþâøþâøþâøþâøýâøýâùúâùúáùýáùýáùýáùýßøûßøûßøûßøûÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöùÝöùÝöùÛó÷Ûó÷Ûó÷Ûó÷ÚòöÚòöÚòöÚòö×òô×òô×òô×òôÖñóÖñóÖñóÕðòÐÏÔ¯­²¥¤©¦¥ª—–››šžœ¡‘•‘—ˆ‡Ž–•ž¸·ÀÆÄÐ^\ib_mqo}SS^Z]h[^fadohlx}FL^=AVFMf@Id=Eb=Eb;Da;Da;E_;E];E];E];E_;E_:D^:D^=EbAHdFJdNShMPb]bp„‘ž„‚“‡†–xw‡€yxˆ€šŒtt€ŽŽ—±°·º¹¾¦¥¬¹¸¿­¬¶–•ž¥£°š˜—¡š˜¢•”›š˜ŸŽ‘©¨¬»º¿ËÉÎâßãÔÎÓÄÁÆÌÈÐÏÎ×ÎÍÖ»»Å¦ª´£ª´y‚¬¸Áè÷ÿåùþßöúßøùßøûâøþâøþâøþâøþâøýâøýâùúâùúáùýáùýáùýáùýßøûßøûßøûßøûÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöùÝöùÝöùÛóôÛóôÛóôÛóôÚòóÚòóÚòóÚòó×òô×òô×òô×òôÖñóÖñóÖñóÕðòÈÇ̪©­–•š¯­²©¨¬£¢¦³²·­¬±£¢¦{z‡†œ›¤¤¢¯ljwVTbVVcNP]Z]hilwbepcfqimyrv‡FL^BJaDJd?Fb>Eb=Da;Da;E_;E];E];E_;E_;E_9B]:D^;Da=D_@Ga?D[FI]ps…ŒŽœž«——¤‚‘‚‘xw‡~Ž€€‡‡”„„vv††¿¾Å²±¶ª©°–•œ‰ˆ‘¡Ÿ©¸·À©¨±»ºÄ­¬³¸·¾¡Ÿ¦—–›­¬±¾½ÁÄÂÇÍËÎÍËι·»½º¿°¯¶³²»ÁÁËÁÁ˾ÁÌ¢¦²‚‰”Ë×ÞåôûèûÿâøýßøûáùýáùþâøþâøýâøýâøýáùúáùúáùúáùýáùýáùýßøûßøûßøûßøûÞ÷úÞ÷úÞ÷úÞ÷úÝöùÝöùÝöùÝöùÛóôÛóôÛóôÛóôÚòóÚòóÚòóÚòó×òô×òô×òô×òôÖñóÖñóÖñóÕðòÇÇÉÏÏÒÀÀÂ¥¥¨““•¨¨ª··¹¯¯±›››œœœ‚…rsy˜˜¢hhtNM]NP_SUdacrllxffrllxrt}ŽfizAEZHJcJNkDGd>A_9@];B^@Ga?Fb?Fc>Eb>Eb=D_;B^;B^=D_;B\AF_DHb@B[LOcmpŽ˜›¨‹‹—zz‡Žrr~xx„tt€‹‚‚Œ¶·½¹ºÀ°±·¥¦¬•–œ«¬²³´º±²¸¯­´²±¶·¶ºº¹¾Ÿž£¡Ÿ¤½»ÀÇÆËÁÀŲ±¶´³¸º¹¾³²·ÐÏÖÆÅÌÄÂɾ½Æ´´ÀŽ‘œ•œ¥Ýêñè÷ÿåøÿá÷ýáûþáûþâúþãúûäûýãûýâýýâýýâúûâúûâúûâúûáùúáùúáùúáùúßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÛööÛööÛööÛööÚôôÚôôÚôôÚôôÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïðÞÞáÈÈ˽½¿³³¶••—““•ÀÀÂÇÇÉ«««¯¯¯º»¾‰‹Ž[^fTVcPSbX[lVXjbdsoo{±±½››¦~~‰hhtkjz^_tHI_HJeMOlFIf?B_9@\;B^>Eb>Eb>Eb>Eb>Ea=D_;B^;B^;B\@Ga>A^@E^QUjNQcUWd…••¡……‡‡“iitffrllx€€Œ‰‰•°°¹´¶»±²¸£¤ª…†Œ¯°¶¦¨­²³¹¹¸½²±¶¸·»ÁÀŹ¸½›šž¢¡¥»º¿ÉÈ͹¸½¬«°·¶º´³¸Ù×ÜÄÂÇÈÇÎÀ½Ç¥¤­²²»‡Œ–¥¯¹ßëôæ÷ÿäúÿáûþáûûâúûãúûäûýãûýâýýâýýâûùâûùâûùâûùáúøáúøáúøáúøßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÛööÛööÛööÛööÚôôÚôôÚôôÚôôÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïðßßâÒÒÔššœŸ££¥““•­­°³³¶¯¯¯ŸŸŸ—˜›¯°³z~†jlyNP_QTewy‹hjyzz‡””¡ÈÈÔ\\hllyts„y{PQfEG_HJeGJhAEb=D_>Ea>Eb>Eb=Da=Da>Ea>Ea=D_;B^=D]9@Z@Da?D]PTi^bsdfswz…]]immy‰‰•{{‡jjvzz†††‘““ž¢¢«³´º¹ºÀ²³¹–—‘“˜³´º©ª°¸·»²±¶­¬±¯­²¾½Á¸·»±°´¥¤©¾½ÁÇÆ˺¹¾”“—½»À·¶ºÀ¿ÄÎÍÔÇÆÏ°¯¸½½Æšž©x‰±½Æéøÿä÷þâúþáûûâúûâúûãûýãûýâýýâýýâûùâûùâûùâûùáúøáúøáúøáúøßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÛööÛööÛööÛööÚôôÚôôÚôôÚôôÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïðÌÌÎ××Ú³³¶ªª¬°°²¬¬¯ššœ””–¡¡¡¥¥¥£¤¦¤¥©˜œ¤‚…‘WZiTVhpr„\^m~Žffs““ŸZZe‰‰–¡¡­¤¦¶twˆEH]FHaLPjGJh?Fb;B^=Da=Da=Da=Da=D_>Ea>Ea=D_>E^:A[;?\@E^NQfcfx…‡”£¦±ŒŒ—€€Œww‚„„{{‡‹œŽŽš˜˜¢´¶»³´º³´º¤¥«‚ˆ¤¥«¡¢¨´³¸³²·±°´·¶ºÌËϽ»À¾½Á¹¸½¿¾Â»º¿ÆÅɘ—œÌËÏÂÁÆìëðáßæÄÂÌÇÆ϶¶¿°³¾y€‹‰“ë÷ÿãôûãùþáûûâúûâúûãûýãûýâýýâýýâûùâûùâûùâûùáúøáúøáúøáúøßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÛööÛööÛööÛööÚôôÚôôÚôôÚôôÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïðÄÄÆÌÌÎÏÏÒ¸¸ººº½³³¶ÂÂŬ¬¯˜˜˜“”–—˜œœŸ¨‡‰–LN]IL]qs‚lo~kjzNM]FFSOO\eeq~~‹y{ˆ…‡–_cw>@XOTmFIfAHd>Ea>Eb>Eb>Eb>Eb9@\:A]>Ea>Ea=D]=D];?\HMfHLa\_q„¬°º¯¯º““ž††‘‰‰•ŽŽšˆˆ”——£ˆˆ”¦¥¦¬¯°¶²³¹¸¹¿š›¡Ž”°±·´³¸¹¸½±°´º¹¾ÅÄÈÇÆ˽»À¹¸½ÅÄÈÈÇÌÅÄȤ£¨¨¦«ÖÕÚãâæÝÜãÔÓÜËÉÓÀÀÉÍÐÛ–›¦—¢ÈÎÜë÷ÿãùþãûýâýýâýýâýýâýýãûýãûýãýúâûùáúøáúøáúøáúøáúøáúøßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÜ÷÷Ü÷÷Ü÷÷Ü÷÷ÛööÛööÛööÛööÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïðÀÀ··¹ËË;¾À¨¨ª¶¶¸ÈÈËÇÇɲ²²ªªª¬­°Ÿ¡¤˜œ¤›ªGIXIL]SUdehw„‚“XWhML\^^k]]ipp{Ž‘œ¯±À“–ªILdINhHLiAHdAHd?Fc>Eb>Eb>Eb:A]:A]=D_>Ea>E^@Ga>A^AF_AEZ]arrt{‰}}ˆˆˆ”……›——£¥¥±ŸŸ«¦¦°ª«±¸¹¿¶·½­¯´±²¸†‡ª«±»º¿ÌËÏÂÁÆ«ª¯¹¸½ÍÌÐÄÂǺ¹¾·¶º½»À¾½Á±°´¿¾ÂßÞãÄÂÇÝÜãíìöÂÁËÇÇÐÐÐÜÅÇÔ”Ÿª¯½ëôÿåùþâúûâýýâýýâýýâýýãûýãûýãýúâûùáúøáúøáúøáúøáúøáúøßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÜ÷÷Ü÷÷Ü÷÷Ü÷÷ÛööÛööÛööÛööÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïðÁÁĺº½ÅÅǾ¾À“¥¥¨»»¾ÁÁÄÅÅž¾¾³´·°±´¬°¸”–£LN]OQc\^macr…„”ji{TScbboZZejjs¯²ºº½É_ctVZo@E^>A^FMiBIeBIf?Fc>Eb>Eb:A];B^=D_=D_?F_>E^@Da@E^GJ_\_q{~‹z~ˆss††‘……‹‹‹–˜˜¤““ž›¤¤­ÍÎÔ»½Â³´º¤¥«Ÿ¡¦­¯´ž¤±°´¿¾ÂÏÎÓ­¬±±°´ž¢¯­²ÂÁÆ¿¾Â³²·¸·»«ª¯º¹¾¿¾ÂÍÌÐ÷öýÙ×áÄÂ̽½ÆÆÆÒ××äšœ©“¢ÉÐÛèùÿâúûâýýßþýßþýâýýãûýäûýãýúâûùáúøáúøáúøáúøáúøáúøßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÜ÷÷Ü÷÷Ü÷÷Ü÷÷ÛööÛööÛööÛööÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïðÇÇÉÄÄƽ½¿½½¿¦¦©¹¹»±±³³³³ÁÁ¿ÇÇDz³¶°±´ªª³¡¡­NM_IL]UWiik}PObqp‚edt^^kaaljjs­­·©¬·}Ž{}‘SUmFHcHLiGJhDJfAJe>Gb>Ea:A];B^>Ea=D_?F_9@Z@DaFJd=?WLOc~‚Žwz…ooz‚‚Ž——£‚‚Žˆˆ”––¢……–—•–œ³´º¿ÀÆŒ“¡¢¨½½Æ¦¨­¨¦«ÅÄÈÎÍÒ´³¸¬«°·¶ºÀ¿Ä²±¶»º¿ÅÄÈÇÆ˶´¹À¿ÄÎÍÒÜÛßÔÓ××ÖÝãâé¿ÀƬ¬¶ÀÀÌ´´ÁŒœ¡¬áð÷åùûâúûâýýâýýâýýãûýãýúãýúâûùáúøáúøáúøáúøáúøáúøßøùßøùßøùßøùÞ÷øÞ÷øÞ÷øÞ÷øÜ÷÷Ü÷÷Ü÷÷Ü÷÷ÛööÛööÛööÛööÙñòÙñòÙñòÙñò×ðñ×ðñ×ðñÖïð‘‘‘ÀÀÀ«««ËË˾¾¾ÁÁÁ¹¹¹½½½ÄÄÁ¿¿¿ÎÎЭ¬³¯¬¹Ÿ­PMaNMbHF]qo†\[pzyŒ€\\i‚‚Žllv}~„‚‚Œ˜˜¤­¬½›²NLeNLhJMjJTlGTkANe=F^=D]:A[;?\=@]?D]?D]?B_?B_AF_?DXfmx~„‹swvvŽŽ—~~‡ww„žž«‡‡“–¥¤«‹‰“£¢«“‘˜œ›¤¯¬¹¡Ÿ©¢¡¥²²´ÏÏÒÀÀÂÆÆȱ±³££¥±±³½½¿ÈÈËÇÇÉÂÂÅÄÄÆÇÇÉÍÍÏÌÌÎñðôöôùÈÇÌ­¬³¿¾ÅÅÄÍ‘œ–š¤¸ÂËæöýäöùëÿÿãýúãþûÞýùâþøäþùãýøâû÷âû÷áúöáúöáúöáúøßù÷ßù÷ßù÷ßù÷ÞøöÞøöÞøöÞøöÝ÷ôÝ÷ôÝ÷ôÝ÷ôÜöóÜöóÜöóÛôòÚóñÚóñÚóñÚóñÙòðÙòðÙòð×ñïxxxÌÌÌÒÒÒ¶¶¶ÌÌÌœœœ‡‡‡°°°¦¦¤¢¢¢¸¸º²±¸°­º¢Ÿ­OL_LH^VTkWUlMLahfy˜˜¥ddpœœ¥ss}iho…„‹¥¤­±¯½ÉÆÚ‰†XToTTpDMeN[rDPh>G_:A[:A[>A^>A^?D]?D]?B_?B_BFc=AXZ_my~ˆtx‚ppyˆˆ‘‰‰•““Ÿ‹‹—zz‡””ŸŽ—Ÿž¥–•žŒ••”Ž—¶³À»ºÄš˜²²´ÁÁĸ¸º¿¿ÁÇÇɬ¬¯¡¡£»»¾ÆÆȾ¾ÀÁÁÄÀÀÂÅÅÇÌÌÎÇÇÉããåÂÂÅÒÐÕ·¶ºÀ¿Æ¿¾Å«ª³ŽŽ—¢©²áëóåöùéúþåýûáúøâÿúÞý÷ãÿùãýøâû÷âû÷áúöáúöáúöáúößù÷ßù÷ßù÷ßù÷ÞøöÞøöÞøöÞøöÝ÷ôÝ÷ôÝ÷ôÝ÷ôÜöóÜöóÜöóÛôòÚóñÚóñÚóñÚóñÙòðÙòðÙòð×ñïllj––”ÏÏÍ¿¿½¸¸¶~~{……‚¿¿½¡¡žžžœ££¥±°´©¨±«©¶HFTOM]XWjXWjSQb\\ittww‚{{…fhmomt–•œ¯­·¾»È½ºË²¯Â[WmVWpBIcQ[vISmBIe=D_>A^?B_>A^?D]?D]?D]?D]?B_BG^MSasx„xz‡zz‡Œ––£{{‡šš£……Ž‚‚Žzx…˜–£œ¥—–Ÿ—–Ÿ–•žª©°ÇÆÍ°¯³³³¶««­±±³²²´««­¿¿ÁÆÆȳ³¶ÁÁÄÇÇÉÁÁĹ¹»½½¿ÈÈËÈÈ˽½¿ÇÇɸ·»ÁÀŹ¸¿ÉÈϹ¸Á‹‹”Œ›ÆÐÙíúÿèùýåùùåÿýßûöáÿùãÿùãýøâû÷âû÷áúöáúöáúöáúößù÷ßù÷ßù÷ßù÷ÞøöÞøöÞøöÞøöÝ÷ôÝ÷ôÝ÷ôÝ÷ôÜöóÜöóÜöóÛôòÚóñÚóñÚóñÚóñÙòðÙòðÙòð×ñïaa^yywÙÙÖËËÈÈÈÆ……‚wwt¡¡žŸ¡œ´´²ŸŸ¢¦¥¬œ›¤VTaLIVNN[UUbPP\EEPaalMMVMNThiokjož¢½»Â£¢«ÄÁÏ»¹Éws‡QPeFJdMTpNUqHLiEHeAEb>A^=A[?D[?D[?D]?D]?B_DHbBHXqvsv‚qq~wv†——¤……Ž‹Œ‘˜””Ÿqo}Œ‰–¥¤­¨¦°›¨›š£–»º¿¸¸º¸¸º»»¾ÄÄÆ»»¾´´·²²´íí𸸺ÅÅÇÂÂÅÅÅǽ½¿´´···¹¹¹»¨¨ªÉÉÌÄÂǺ¹¾±°·¸·¾ÈÇОž¨‚‡‘“š£Üéíâòöæúúãúùãÿùâþøäþùãýøâû÷âû÷áúöáúöáúöáúößù÷ßù÷ßù÷ßù÷ÞøöÞøöÞøöÞøöÝ÷ôÝ÷ôÝ÷ôÝ÷ôÜöóÜöóÜöóÛôòÚóñÚóñÚóñÚóñÙòðÙòðÙòð×ñïVWSopk½¾¹½¾¹Œvwr€}”•‚„²³¯³³±„„„¡¡£Œ‹–•œkjqddmTT]TT]OOXZ[aTU[NOSdeiomrˆ‡Œ¥¤©£¢©ÂÁ˦¤±qo}edtSVk?D]OTmOTmHLiBFc;?\>B\?DX?DX>BZ>B\AEb>B\?EWzsv‚oo{ml}š––Ÿ‚„‰¦““ž›rp}Ž—±°¹°­ºž¦Œ‹‘Ž“±±³ÁÁÄÄÄƺº½ÆÆÈÆÆÈÉÉÌÌÌθ¸ºÌÌÎÇÇÉÅÅÇÀÀÂÀÀºº½²²´ºº½èèêÜÛß¿¾Â½»Â¸·¾ÍÌÕÈÈÒ‡‹•y€‰©³¹íúÿä÷÷åýûäþùáý÷åÿúäþùãýøãýøâû÷âû÷âû÷âû÷ßù÷ßù÷ßù÷ßù÷ÞøöÞøöÞøöÞøöÜöóÜöóÜöóÜöóÜöóÜöóÜöóÛôòÚóñÚóñÚóñÚóñÙòðÙòðÙòð×ñïTUPbc^}~y«¬¨¢£žbc^‡ˆ„stpklh‹Œ‡‹‹ˆ€€~€€€‡‡‰°°²°¯³ijm]^bXZ]deiZ[^\]aTUXefjooqwwy¹¹»œ›Ÿ¹¸¿Œ‹”°¯¸††“cewLOdPTiPSkOQlIMj?B_>B\?DX@EZ?D[?D]?B_?D]BH[jo}€‚{{ˆddqxx…œœ¨††‘‘›˜˜¤£¡­“xw€Ž—°¯¸±°¹˜—ž†…Œ«ª¯»»¾ÄÄÆÉÉ̾¾ÀÌÌÎÈÈËââäÍÍϸ¸ºËËÍÉÉÌÇÇÉÂÂÅÁÁÄÂÂÅ»»¾ÀÀÂÄÂÇÈÇÌÇÆͨ¦­ÒÐÚÅÅΟ£­{€‹†”Ôáååøøåùùãýøãÿùåÿúäþùãýøãýøâû÷âû÷âû÷âû÷ßù÷ßù÷ßù÷ßù÷ÞøöÞøöÞøöÞøöÜöóÜöóÜöóÜöóÜöóÜöóÜöóÛôòÚóñÚóñÚóñÚóñÙòðÙòðÙòð×ñïUVOef_lmf©ª£‰‹„WXQ„…~mohde^stpjkfddbaa^eeeŸŸŸŽŽŽijljkm^_b]^aefi„…‡LMOijlrrtkkkžžž‹‹——šjimfel…„}}ˆfivUWiPQfPSkOTmDGd;B\@EZAGZ@E\?D]?B_@E^BH[SWey}‡yy‚mmwww‚……‘Ž……‘šš¥Œ•Ÿž¥Ÿž¨‚‹”“œ³²»š—¤Œ‹”¤£¨»»¾ÅÅÇÕÕ×ÏÏÒÆÆÈÔÔÖÈÈËßßâ»»¾ÍÍÏÇÇÉÈÈËÌÌÎËËÍÆÆÈÂÂÅÎÎÐÇÆˬ«°¶´»«ª±º¹ÂÎÎ×¾ÁÌ{€‹‚‰Ÿ¬±ãóôæúúæþúåÿúåÿúäþùãýøãýøâû÷âû÷âû÷âû÷ßù÷ßù÷ßù÷ßù÷ÞøöÞøöÞøöÞøöÜöóÜöóÜöóÜöóÜöóÜöóÜöóÛôòÚóñÚóñÚóñÚóñÙòðÙòðÙòð×ñïUVQ[\Wfhclmffha^_Xef_cd][\U^_[^_[Z[ViifccaŽŽŒttrceddfe]_^TVUehf{}bcekmlsssiiilll‘‘‘}}}vvxxxz{z‰ˆ€‡ddpVXhTUjTVoINh@E^AGZAGZ@EZ?D[?B_@E^>BWBFWkmz€€‰llvxx„‡‡”jiytt‚‚Ž‰ˆ–•œŸž¨¨¦°zy‚ˆ†“ŽŒš…‚”“—¤¤¦··¹ÄÄÆÎÎÐÎÎÐÐÐÓ××ÚÔÔÖÛÛÝÏÏÒÎÎÐÏÏÒÌÌÎËËÍÍÍÏÅÅÇÈÈËÂÁƾ½Ä´³º·¶½²±ºÒÐÚÒÒÝŒš„‰~ˆŽÞïðêýýêÿþãýøåÿúäþùãýøãýøâû÷âû÷âû÷âû÷ßù÷áø÷áø÷áø÷ß÷öß÷öß÷öß÷öÝôóÝôóÝôóÝôóÝôóÝôóÝôóÜóòÛòñÛòñÛòñÛòñÚñðÚñðÚñðÙðïOOM[[Xiif…†klhefbcd]cd]NOJTTQUUSQQOppmppmXXVddbjjhbb_[[XWWUffdjjjjjjffdhheddbaa^^^\iifxxxqqqttrmmmomr__iPO_LMbGIbAD\AEVLOaNQf?AZAD\?AZ?BWBFZacr††‘}}ˆkkx‰‰–ˆˆ•ddq‹ŽŽ—‡‡˜˜˜¢ªª¶‹‹—˜˜¥˜Œžž¡°°²ÀÀÂËËÍÀÀÂÏÏÒÔÔÖÈÈËÛÛÝÅÅÇÒÒÔÆÆÈÇÇÉÆÆÈÍÍÏÆÆÆËËÍÉÈϾ½Ä­¬±¥¤©³²»ÆÄÐÒÐÚ·¶¿‡‹“‘šê÷ùéûùéþúäý÷æÿùåþøäý÷äý÷ãûöãûöãûöãú÷áøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óáöòáöòáöòáöòßôñßôñßôñÞóðÞóðÝòïÝòïÝòïÝòïÜñíÜñíÜñíSSSNNNkkissqqrm]^Zbc\ijeQQOLLIZZWMMJbb_ŽŽŒ^^\ZZWiifbb_\\Z[[Xbb_hheaa^ddbeecVVTddbaa^__]eeceecmmksrojieiii…„ˆ__kTScTVhQUfLP\UZeUXjEH\AEZ?AZ?BWBDXIHXlly††“}}‰‚‚Ž©©´¤¤°„„__kppyˆ””Ÿ••¢””¡¡¡­ªª³”žž¡´´···¹ËËÍÉÉÌÅÅÇÎÎÐÇÇÉÛÛÝÍÍÏÓÓÕÄÄÆÉÉÌÓÓÕÝÝßÚÚÚÆÆÈÆÅÌÄÂÉËÉÎœ¡¯­·¿½ÉËÇÒÖÕÞœ£•šßíìëþûéþùæÿùæÿùåþøäý÷äý÷ãûöãûöãûöãûöãøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óáöòáöòáöòáöòßôñßôñßôñÞóðÞóðÝòïÝòïÝòïÝòïÜñíÜñíÜñíJJJMMM]][hhefhcbc^_aZfhcTTQOOM__]TTQUUS‚‚€~~{SSPbc^]^Z[\W\]Xbc^efb^_[efbiifPPN]][eechhemmkjjhddbppmbb____Ž{}‚^^hZZeX\dU[_\biZ^jFI[@DW@DXBF[HI^TSeiivzz‡ww‚–£¤ª²³¹ÅÆ̉‰•bboZZfŽ““žŽŽ—““œ¶¶¿¶´¹œœž¸¸º¸¸ºÂÂÅÒÒÔÂÂÅÐÐÓÔÔÖÔÔÖÓÓÕÐÐÓÇÇÉÆÆÈÈÈË¥¥¨···»»¾ÄÂÇÉÈÍ¿¾ÂÇÆË›š£²±ºÍÉÔ¾½ÆÀÁÇŽ”˜Üêéåøöéþùäý÷æÿùåþøäý÷äý÷ãûöãûöãûöãûöãøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óáöòáöòáöòáöòßôñßôñßôñÞóðÞóðÞóðÝòïÝòïÝòïÝòïÜñíÜñíAAALLLUUSccabc^Z[V^_Xab]WWUXXVUUSNNLXXVeec““LLI[\WWXTWXTZ[V_a\\]X\]X_a\^^\ZZW]][eeceecmmkjjhZZWffd[]\^a_vxwˆ‰Œklo]^bZ[]X]\]bcX\dDFS@BTDEZLMbTVhLJ[aam~~‰€€‰…†Œ¡¢¥¶·¹ÆÇËÆÆÒ……‘XWhbbo‹‹”„…‹——¡¤¥«ž¢¥¥¨¨¨ªÀÀ¶¶¸»»¾ËËÍÌÌÎÀÀÂÌÌÎÆÆÈÆÆÈÎÎÐÉÉÌŽŽyy{‹‹‹¨¨ªÂÂÅÀ¿Ä¿¾ÂÕÔÛ«ª±“‘›¹¶ÀÏÎ×Ö×Ý•›ŸÍÛÚèúøêÿúèÿúæÿùåþøäý÷äý÷ãûöãûöãûöãûöãøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óáöòáöòáöòáöòßôñßôñßôñÞóðÞóðÞóðÝòïÝòïÝòïÝòïÜñíÜñíHHHNNNVVTffd]^ZNOJQSL_a\WWU\\ZPPNPPN^^\cca}}zVVTXZU_aZWXQ_aZab[\]VZ[T_a\bb_]][ZZW^^\eeceecddbUUSX[ZX[Z^a_ceddddiiihheTVSTVQ[]Z^_cQQ[IIVEDTML\^]m]]jaaliir‚ˆ}~‰‹¯±°¾¿ÁÉÉÓÎÎÛ‡†–QQ^qqz˜šŸ˜˜¢–~}ÅÅǬ¬¯¿¿ÁËËÍÀÀž¾ÀÍÍÏÆÆȸ¸º½½¿ÎÎÐÍÍÏÓÓÕÎÎÐÌÌί¯±¾¾ÀÉÈ͸·¾½»ÂÐÏÖ“‘˜¹¶ÀÍÌÕÜÝãÍÓ×Õãâéûùæû÷ãûöæÿùåþøäý÷äý÷ãûöãûöãûöãûöäùöäùöäùöäùöãøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óßôñßôñßôñÞóðßôñßôñÞóðÞóðÝòïÝòïÝòïÝòïOOOGGGQQO]][VWSMNIUVOab]]][__]__][[XVVTaa^aa^]][TUPhibUVObc\bc\]^WWXQ^_[[[X]][VVT]][eecddbddbVXWSWXX]^[\^bdcbbbccalljWXTZ[Vbd_abdTU[JJTFFQJJVWWcaajijp\]c€„z{~}~¥¨¦±²´ÁÁËÐÐÝÍÍÚss€^^j››¤››¤¢¢«š˜¿¿Á³³¶ÅÅdz³¶ÈÈËÂÂÅËËÍÓÓÕÒÒÔªª¬ŸŸ¢¹¹»ËËÍÓÓÕÔÔÖããåééë··¹ÄÂÇËÉв±ºÂÁȯ­´¯«¶ÁÀÉÎÏÕÙÞãÛéèèúøæû÷äý÷æÿùåþøäý÷äý÷ãûöãûöãûöãûöäùöäùöäùöäùöãøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óßôñßôñßôñÞóðßôñßôñÞóðÞóðÝòïÝòïÝòïÝòïZZZPPPQQOOOMPQMNOJWXQ^_[[[X^^\__]\\ZVVTcca^^\ZZW_a\de^XZSde^ab[_aZbc\TUPZZW]][\\Z__]cca__]aa^VXWUZ[PUWNSUcdfiik]]]cab[ZWVWSccaddd\[_WV]TSZSQVTSW]^bvwycdfqrttwvwyx›œ˜šœ©ª°ÉÉÓ××á¾¾É[[hxx…ˆˆ•””‰ˆ½½¿ÝÝߢ¢¤°°²¾¾ÀÌÌÎÂÂÅËËÍÒÒÔ¦¦©––˜½½¿ÆÆÈÕÕ×ÚÚÜææéææéÛÛÛ¿¿ÁÍÌÕ¿¾ÇÍÌÓÈÇΣŸª·¶¿ÀÁÇÝãèáïíèúøèýøåþøæÿùåþøäý÷äý÷ãûöãûöãûöãûöäùöäùöäùöäùöãøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óßôñßôñßôñÞóðßôñßôñÞóðÞóðÝòïÝòïÝòïÝòïXXXaa^XXVTTQOPLOPLWXQZ[V[\Weec__]bb_[[X__]XXVUVQbc\de^STMXZSde^cd]]^WUVOWXTSSP]][XXV]][XXV[[XTVSNSTGLMEIJ_acaac]]]b_a_^\VVTcca^^^VVXTTVWWZZZ\WWWZ\[fih_ba_bafihqsrŽ‚…‹Œ‘ÅÆÌÖ×ÝÒÓÙ¥¥±vveeq‡‡“‡†Ž“âá囚ž´´·ÅÅÇÍÍÏÈÈËÈÈËÒÒÔÍÍÏææéÒÒÔÍÍÏÌÌÎßßâååèññóäääÇÇÉÆÅÌÐÏÖÈÇÎÄÂǽ¹Á­¬³ÅÆÉÎÔÖßëëé÷ôêûøêýùéþùåþøäý÷äý÷ãûöãûöãûöåúöäùöäùöäùöäùöãøôãøôãøôãøôâ÷óâ÷óâ÷óâ÷óßôñßóóßóóÞòòßôñßôñÞóðÞóðÝòïÝññÝññÝññUUS\]X_a\UVQQSNIJFOPL\]XZ[V]^Z^_[]^Z]^ZWXTZ[VXZUab[de^[\UMNG^_XWXQZ[TZ[TVWSWXT_a\XZUab]QSNXZU\\ZNPMVXWGIHXXXeee^^\aa^ccaUUSeecddbZZZSSS___[[[OOO[[[hhhXXVddbjjhyyw‡‡‡€€‚Œ‹¿¾ÅÒÒÔÈÈ˶´¹£¢¦~}„^]fvs€ˆ†“Ÿž¨“‘˜ž¢ÞÞáÒÒÔÌÌÌÇÇÉÅÅÇßßâÉÉÌÖÖÙÐÐÓÒÒÔÙÙÛÞÞÞêêêêêêÕÕÕÅÅÇÈÈË××ÚÀÀÂÀÀ··¹½¾ÀÉÎÏËÒÒÙßÝìöòìøôêýùéþùèýöåúóéþ÷åúóäùòäùôãööä÷÷ä÷ôåøöãöòåøôåøôâôñâôñâôñâôòáóñáóóáòöáòöáòöáóñáóðáóñáóñßòòßñôßñôßñôOPLUVQ]^ZZ[VHIEEFAMNIXZUTUP]^Z^_[WXT^_[XZUTUP]^Z\]V]^WXZSEF?WXQUVOZ[TZ[TXZU]^Z[\WZ[V^_[STOQSN]^ZSSP\\ZPPNVVTZZWQQOWWU\\ZPPNXXViif^^\LLIUUSWWUSSP^^^cca_a\cd_rsowxsttrqqs{z—–›¤¤¦‚‚‚ŸŸŸ¹¹»˜—œ€‰dbp}zˆ‡…‘Œ•–•œ©¨¬ÂÂÅÀÀÀÇÇÉÐÐÓÖÖÙºº½ÏÏÒÛÛÝÈÈËÉÉÌÝÝÝ×××ßßßÖÖÖÄÄÄÍÍÍÌÌÌÅÅÅÁÁÁÇÇÇ°²±ÅÇÆÅÉÈÂÇÆìñðïøôìþúêÿúéþ÷éþ÷åúöèýøåúóâ÷òæù÷åøøãöóâôòæùöãöòâöïåøôâôñâôòáóñßòòáóóáòöáòøáòöáóñáóñáóñáóóßòòßñôßñ÷ßñ÷IJFQSN^_[^_[JLGBD?GHDTUPSTO\]X]^ZVWS^_[XZUTUP]^ZZ[T[\U]^WGHAVWPVWP[\UXZSXZS^_XZ[TXZS\]VNOHOPI^_[]^ZZ[VQSNSTO^_[QSNSTOXZUQSNWXTjkfXZUMNIQSNZ[V[[X__]eec_a\de^fhadeappmlllihl~}rrp€€~¥¥¥‰ˆ£¢©ecpb_lljw´³½´³ºœ¡±±³––˜´´·ÕÕ×ÛÛÝÜÜÞÍÍÏÖÖÙÈÈËÐÐÓÓÓÓÐÐÐÜÜÜÓÓÓÍÍÍÔÔÔÆÆÆÈÈÈÆÆƾ¾¾‹Œ¹»ºÎÓÒÁÆÅ×ÜÛôþúìþøèûôåøôåøôéûùåøöä÷ôæù÷âôòãöóåøôæùöãöòåøôåøôâôñä÷ôãöóâôôâôôáóóáòöáòöáòöáóñáóñáóóáóóßòòßñôßñôßñôHIETUPbc^^_[MNI>?:EFA[\WXZU\]X]^Z\]X]^ZWXTZ[VXZU^_X^_Xbc\STM[\U[\U]^WVWPZ[T]^WZ[TUVO[\UHIBQSL_aZUVQWXTWXTQSN\]XOPLSTO]^ZPQM\]XijeXZUVWSUVQbc^^_[ccaab]fhacd]bc\de^efb___aacqqsmmmhheqqo{{~ÂÁÆ{z„\[d[Zcdcjjimˆ‡Œ¨¨ª••—««­ËËÍÇÇÉßßâÔÔÖÕÕ×ÕÕ×ÓÓÕÙÙÙÙÙÙßßßáááÔÔÔÍÍÍÕÕÕÌÌ̹¹¹ÉÉÌœŸ²³¶³¸¹ÐÕÖÌÐÒéððíûùëûúìýûéùúéùýéøÿè÷ÿåôûå÷úä÷÷ä÷÷ãöóä÷ôâôòâôñä÷ôä÷ôãööãööâôôáóóáóóáóóáóóáóóáóóáóóáóóßòòßòòßòòßñôIJFIJFZ[V\]XLMH9:6BD?]^ZVWSUVQXZU\]X[\WZ[V^_[WXTab[\]V]^WXZSNOHTUNXZSXZSZ[Q]^UbcZ\]T\]TTULWXOZ[TSTMXZS]^WLMFZ[T[\U_aZbc\OPI]^Wde^bc\^_XWXQab[]^Z[\W^_[hibde\abX_aZ]^Zbb_VVXjjljjh_a\jkfccahhj¦¥ªÌËÏŽ”•”›zy~~‚ªª¬¥¥¨bbd­­°¾¾À¤¤¦¾¾ÀÀÀÂÍÍÏÓÓÕÒÒÔÜÜÜåååßßßâââÜÜÜÔÔÔÈÈÈÁÁÁÆÆÈÅÄÈž¢°±´­²´ÂÇÉÛßââèêêôøéöúÕâé·ÂÌ—£±—¢´š£¹¡«¾·ÅÓ°À˺ÌÓÍÞäâó÷áóóÝðíä÷ôÝððáóóáóóßòòáóóáóóáóóáóóáóóáóóáóóáóóáóóáóóáóóáóóLMHLMH\]X^_[QSN?@;EFA[\WOPLQSNZ[VVWSZ[VZ[VZ[VUVQ\]V[\U]^W\]VJLEPQJUVOUVOWXO\]TabXZ[QQSITULXZP[\SOPIWXQbc\UVOTUNWXQ[\U[\UNOHde^ab[[\U\]VUVO]^WXZS\]Xcd]Z[Q]^Ucd[]^UZ[T__]ZZZfffbb_Z[V_a\bb____‹‹žž¡¶´¹²±¶‰ˆ~~€œœž¸¸ºkkm‚‚…‘œœž¨¨ª´´·²²´½½¿ÍÍÏÐÐÐÚÚÚßßßéééæææÛÛÛÌÌ̸¸ºÎÍÒ¿¾Â¡¢¥©ª­«°²´¹»ÎÓÕáæëÏÖÝÇÎ×­´¿Ÿ¥¶¬±Æ¢»„‡¤„‹¦„¥€Ÿ‹›¨—¨²¨¹ÀÆ×ÝÜíñÞðóäöùâó÷ßñôÞññáóóáóóáóñáóñáòöáòöáòöáóóáóóáóóáóñáóñVWSQSN[\WZ[V[\WGHDHIEXZUNOJSTOZ[VXZUZ[VVWSXZUOPLWXQXZSWXQXZSGHAMNGPQJQSLSTJ[\S_aWUVMMNEQSIUVMZ[Q\]VQSLXZSXZSVWPZ[TXZSUVOOPIde^^_XWXQ\]VTUN[\UUVOZ[VZ[T]^U_bU^aTbcZUVOaa^\\\bbb\\ZXZUbc^iif^^^iiikkk´´·¡¡£‡‡‰œœž¥¥¨jjl‡‡‰ÄÄÆ””–††ˆ••—¹¹»¹¹»„‘‘‘ÒÒÒðððÔÔÔÙÙÙåååÙÙÙÆÆÈÂÁÆÎÍÔš›¡¬­³°³¹¥©¯»¿ÅÞâèëñóÖÜáÇÌÖ¸½Ëßãø±³ÎŽ­„‹¨~‹¢z‰›}ŒŽŸŽž­¡­¢²¿¾ÎÙÙêñãôúáòöÝððáóóáóñáóñáóñáòöáòøáòöáóóáóóáóñáóñáóðWXTTUP]^Z\]Xab]MNIJLGWXTIJFPQMNOJ[\W[\WPQMZ[VIJFUVOVWPOPIPQMDE@IJFNOJNOJPQJZ[Q^_VSTJOPGOPGNOFXZP[\UNOHUVOVWPIJDSTMWXQUVOPQJ\]V_aZZ[T^_XUVO[\UTUP\]XZ[V_aWcd[WXO\]Tab]^^\]][aa^\]X^_[dealmieecbbbTTQddb———¢¢¢}}}«««›››SSUyy{»»¾……‡ppr€€‚¾¾À˜˜›†††ppp¶¶¶äääíííæææâââÝÝÝÏÏÏÄÂÇÄÂÇÁÂÆŽ“±²¶—˜œ¨©¬ÒÖÙèìïÓ×Ú»¿Ç½Á͸»Ïœž·€‚Ÿ…¢}†ž{ˆ{ˆy†›x…š}‰žˆ•ª•£´¡¯½ËÜãáòøáòöáóóáóñáóðáóðáóóáòöáòöáóóáóóáóñáóñáóñSTOVWSWXTUVQUVQVWSPQMXZUGHDJLGOPLab]LMH[\WPQMIJFQSNMNISTOTTQIIGNNLLLLMMJSTOSTMUVOUVOQSLWXQSTMVWPVWPPQJOPISTMGHAQSLPQJSTMUVMUVM\]V^_XXZUUVQUVQMMJTTQZ[V]^W_aZab[[\UXZU^^\[[X\\Zdeade^ab[lmiffd__]UVQZ[Tjkf}~yool‚‚€iifXXXlll¡¡¡ŒŒŒ•••žžž~~~hhhddb““¸¸¶ÎÎÌååãÕÕÓÖÖÔ¯¯¬ÇÇǺº½ÐÐÓ±±³©©«ŸŸ¢Ÿ¥¦©ÍÎÒæèí¯¯¸©«¸›¯Ž¥†‡Ÿ„†¡ˆ¤”˜­Ÿ¤»¤©À“—¯‰Ž¨„t{•…¢¤²ÂÕåðáòøÞòòßôðßôíãøñâôñãóòãóòãóôâòóâòöâòöâòöJLGPQMVWSVWS[\WXZUNOJSTOGHDIJFUVQ_a\LMHWXTNOJEFAQSNLMHNNLUUSLLLLLLGGIJJJOPLPQJTUNTUNSTMMNGZ[T[\UVWPPQJOPISTMNOHLMFSTMOPIUVMUVMXZS]^WVWSTUPOOMHHFPPNXXV]^Zab[cd]^_[XXV]][^^\__]^_[^_XUVO^_[XXVTUPQSLVWNcd]mohbc^xytffd\\Z___qqq‡‡‡†††vvvmmm\\\^^\qrm¦¨£‰‹†×ÙÔ«¬¨ÄÅÀ‹ÌÌÌ···ÎÎÎÐÐÐÛÛÛ½½½ºººªª¬ÝÜãÒÐÚ¾¾É¬«»”–¨‡ˆˆ‰¢‰‹£…‡Ÿ†ˆ¡“«›¶¢¤½–˜±Ž©„ˆŸy‚˜‡•¦£±¿ÕæíÞðóÛðìáöïßôíâôñãóòãóòãóôâòóâòöâñøâñøFGBNOJTUPVWSVWSTUPJLGOPLPQMLMHZ[VTUPJLGVWSVWSNOJOPLMNIMMJSSPPPPGGG@@BGGGIJFQSLMNGUVONOHWXQ]^W^_XVWPPQJOPISTMUVOHIBOPINOHUVMUVMVWN[\UQSLUVQQSNPQMOOMVVTWXTZ[Tef_deaZZW^^\[[Xaa^XZU^_X[\U]^ZPPNJLGUVO\]Tab[bc\TUPefb[[XQQO\\Z__]eeeqqqxxxiiiqqsVVV\\Zffdlljyyw¶¶³{{y——•rrp´´´³³³ÆÆÆÁÁÁÈÈȬ¬¬½½½»»¾âáèÇÅÒÍÌÜ–•¨‘“©€˜{{—„„¢€‚Ÿwy–~€›‘ª£¦»²¶ÉŸ£´–©€ˆœ{†˜‚¡¬»ÆÚëñæùùãøôáöñâôòãóòãóôãóôâòóâòöâòöâòö@@>FFDJJHJJHVVTPPNBB@DE@QSNJLG[\WTUPJLGTUPUVQIJFIJFPQMNNLOOMSSSEEE::=EEEHIEHIEQSNQSNNOJQSNTUPZ[VVWSPQMOPLSTOXZUIJFJLGNOHJLBTULXZP]^WNOHSTOMNIJLGPPNPPNOPLPQJ]^Wbc^XXVVVT\\ZccaPQMVWPWXQWXTJJHGHDVWP]^U^_XXZSPQMcd_bb_]][TTQ\\Z___hhh[[[TTV^^aLLNNNNbb_ddbiif‚‚€eecmmk]][ŸŸŸ³³³ººº¾¾¾………{{{žžžÂÂÅÙ×ÜÆÅÎÆÆÒ°¯¿Ö×ì¿ÀÙ••±††¤wx—xy˜}œ€‚›‹Ž£”—©¢°šŸ­•©t‘w“Œ›¥ÏÞæÜíóßñôä÷÷ãóôãóôãóôãóôâòóâòóâòóâòö>>>AAAMMMFFFHHHJJJAAA@@>PQMPQMXZUMNI@A=HIENOJEFAGHDFGBFFDGGENNNAAA99;>>>DDA@@>LLIMMJLLIJJHNNLOOMUUSMMJIIGPPN]][SSPJJHMNISTJWXO^_X^_XPQMEFAHHFIIGLLIPPNVWSSTM^_X]^ZSSPTTQUUS]][UVQUVOZ[TUVQHHFMNIWXQ_aWab[]^WUVQ\]XZZWPPNUVQXXVQQO[[[UUUMMOONSGGIPPPZZZZZZ\\\TTT[[[\\\iii‹‹‹Â–––°°°sss€€€ˆˆˆžžž½½ºÉÉÇÀÁÅ••žÅÇÖÐÒ昚²‡‡¥{}œxy˜xz•}—‚†š˜œ­šžª¨­»¢ª½‹“¦r}ŽsŽ¨·ÆÐÜíôÛìòãó÷äôöãóôäôöãóôâòóâòóâòó666;;;GGG>>>DDDAAA>>>AAAMMJJLGPQMNOJBD?HIELMHDE@DE@EFAEEBDDASSSFFF88:::=;;;@@>??=IIGGGELLIGGEFFDOOMLLIFFDQQOXXVSSPNNLHIELMFSTJ\]V^_XWXTGHDFFDDDAGGEJJHQSNMNG[\U]^ZSSPOOMVVTXXVUVQPQJVWPLMHIIGSTO^_Xfh^fhabc\VWSQSNSSPXXVNOJTUPWWUPPPQQTGGIHGLA@ENNP[[[UUU___WWWSSS]]]ZZZbbbœœœ~~~jjjlllooo‚‚‚‹‹‹±²­ÇÈĪ¬«xy¦ª´}Ž‚—xy‘rty{–{~–wz…˜¢šž¬£¨¶¢¨º˜¬rzlwˆr}ŽŒšª²ÀÎãóþâñøãó÷äôøâòóãóôãóôâòñâòñ>>@::=FFHFFHJJMHHJBBE999MMJIJFGHDDE@BD?FGBLMHGHDBD?FGBFFDBB@TTTJJJ88:99;888777>>>BBBLLLEEEGGGGGGJJJFFFGGGQQQQQQUUUOOODDAMNGPQHVWPVWPWXTIJFLLILLINNLLLIMNIHIB^_Xfhc\\ZTTQWWU[[XZ[VUVOWXQOPLHHFTUPbc\ijahibab[XZUFGBJJHXXVOPLXZUUUSNNNSSUPPSQPUDBGJJMUUWPPS^^aJJMHHJPPSbbd^^acceXX[VVX[[]ddf~~€‚‚…¯¯¯–––£¤¦mot˜z~ˆoq~qs‚ps‡{”{”rv‹tx„‡œ‚†›Ž‘¦—œ±‘¦iq…fo‚s~ˆ“¥—¥·ÄÒâÜëóâñøâòöâòóãóôãóòãóòâóð???>>>IIIGGI??A;;>AADAAAEEBHIEEFA?@;?@;BD?LMHMNIDE@IJFIIGDDAQQQNNN:::;;;777666===AAAJJJNNNMMMNNNGGG>>>JJJPPPMMMVVVLLLFFDGHDMNGUVOVWP]^ZOPLQQOQQOJJHEEBHIEFGBUVQbc^VVTJJHOOMZ[VVWSXZUQSNXZULLI]][^_Xde\cd]\]Vab]NOJNNLSSP\]XXZUXXVJJHQQQPPSUTXLJOFEIIHMNMQZZ\PPSMMOOOQ[[][[]]]___bWWZTTViikŽŽooq‚‚…yy{ˆ‰fhkz~„kotfjrilwoq~vx‡rt„fizwx„…›~•„†žˆ‹£…‰¡vz‰‘¤qypyˆ‘ª˜¥ºÅÔÞÛêñßðóßðñâòóãóòãóòãóò480794BEALNM>?A236687FHE@@>FFDFFD>>;GGEAA?FFDHHFDDALLIJJHJJHVVT]][TTQFFD442997;;9@@>DDALLIJJHBB@BEAEGFILJEFHFGINPO@BAGIFDDAIIGUVQ[\WOPLLMH997???GGEBB@FFDEEB]][[[XQQONNLLMHSTONOJWWUSSPMMMIIIUUSef_de\ab[ef_cd_TUPMMJNNLWWU\\Z[[XTUPMMJNNLUUUSSUDEJEFLFGMVW[MNQIJNIJMUVX[[[QQQUUUVVVOOO]]]eeeeeeefi^_bijlabdcdhopshilefjdekqqzssjjwrq‹‰œ˜—¬‡ˆž„„ŸoqŒcfzw}{”s{‘t{˜~‡¢›¬ÌÙßßìïâðïäôöáñòãööáóóAE:AE=EGBDFE9:=013687ILHEEBLLIGGE886663@@>GGEEEB??=MMJPPNQQOaa^bb_XXVTTQ??=@@>;;9DDAFFDLLIJJHAA?JMIEGFGHJFGIDEGIJMJMLFHEFFFGGGVVTXZUQSNTTQ???;;;FFD@@>FFDNNLiif__]SSPSSPMNIOPLOOMJJHQQQFFFDDFBBBVWPab[ab[TUP\]XVVTMMJMMJSSSWWWPPNXZUIJFNNLNNNOOQFGMDDMGHNTU[NOSEFIEFHVWZSSSMMMTTTXXXQQQVVV[[[WWW^_bUVX^_b]^a]^abcebce]^abcfdei{}‚ffpvv‚Œœ«ª½Œ‰¡‰‰¥ij‚advsx†£¦º{€—tx–t{—€ˆ›¤ÛèêäòñãóôäôöÛííä÷÷BF;=@8>@;>@?78:-/1243BEAMMJOOMFFD220220??=EEBGGE@@>IIGJJHLLIUUSbb_ccaaa^OOMEEB997BB@DDALLIJJHBB@DFB>@??@B?@B:;>@ADNPOILHLLLNNNZZW\]XUVQOOMPPP@@@LLIMMJIIGJJHbb___]TTQLLIUVQMNIOOMNNLNNN===::=???PQMXZS[\WGHD\\ZLLIFFFIIIQQQWWWLLIXZUJLGOOMOOOJJMGHL@AGEFLNOSOPTFGIFGIWZXMMMHHHNNNTTTVVVUUUSSSWWWTUWUVX\]_VWZbce]^a]^abcebcfdeibci^^hhhsllyzy‰‹‰žˆ‰¢qrˆikzšœ©¬°Á–š¯qsrwr{‹v€ˆÅÒÔâðïáñôãó÷åö÷ßðñTWMNQI?A=@BA@AD347243?A>NNLIIG??=774>>;;;9==:JJHGGEHHFHHFQQOJJHQQOSSPXXV]][HHF774AA???=IIGMMJGGE:=9;>=@AD=>@;=?;=?EGFDFBGGGOOOOOMXZUWXTJJHJJJ???LLIHHFAA?GGEZZWTTQJJHJJHHIEHIEHHFGGE@@@;;;88:AAA\]XXZUXZUUUSLLI???IIIGGGJJJQQQQQO_a\QSNQQOSSSFFH@AE;=BBDGGHLPQTMNPMONX[ZJJJEEEIIINNNIIITTTTTTVVVOPSNOQTUWVWZXZ\_acXZ\[\^^_cefjfhmQSXeeoddpxx…†…•‘“¨z}Ž_bomq{ž—˜­~—txqw…w‰Ÿª­Üéëäñøâñøãó÷áñò[^TOSJ8:68:9@AD124364>@=LLIJJHAA?::8HHF;;9??=QQOBB@??=QQOSSPNNLOOMOOMNNLZZWEEB::8EEBEEBFFDLLIPPN9;80219:=46801389;>@?@B?FFFQQQSSPNOJXZUSSP>>>BBBOOMLLIGGEFFDOOMHHFBB@BB@EFA?@;AA?DDADDD???::=EEEPPNPQM[[XAA?>>>:::FFHPPSFFFMMMNNLXZUSTOMMJSSSIIL?@D:;?GHLSTVIJMMONNPOUWTOOONNNFFFMMMHHHQQQOOOQQQLMONOQOPSMNPXZ\]^aVWZPQTVWZVW[^_c]^b[\b_afffpmmyz}‰acp[^feiqmp}‰ˆ˜{zoq‚lq{ipw‡“ÅÏÕáëóÞëòßìñéöúTWMLOGDFA;>=@AD679132@B?LLIQQOGGE774MMJEEBAA?NNLEEBAA?PPNLLIWWULLIFFDIIGVVTAA?442??=BB@IIGJJHTTQ>@=79889;/02124>?A?A@GIFGGGEEEHHFQSN[\W^^\LLLLLLLLIIIGJJHEEBIIGIIGAA?GGE@A=DE@HHF@@>BBBHHHEEGBBBJJHMMJZZWBBB@@@NNPGGIMMODDDAAA>>;NOJXZUMMJPPPIIIBDFBDGNOQZ[]LNMLNMJMIQTPVVVQQQEEELLLHHHNNNSSSVVVPQTOPSPQTFGITUW[\^UVXTUWQSUTUW\]_^_cOPTVW[cdhklrdhpSV^W\^efjss}€€vt…oo{eiqekpv~¶½ÄÜãì¸ÁÌâìòâïóMPFMPHNPL=?>=>@78:8:9LNJGGENNLHHF>>;PPNNNL>>;JJHBB@@@>MMJFFDUUSTTQNNLHHFWWU@@>331;;9DDAQQOIIGUUSFHE;>=89;34789;@AD:=;>@=HHH>>>HHF]^Zab]\\ZZZZLLLLLIMMJHHF@@>DDAEEB774IIG@A=;=8FFDBB@DDDJJJNNPGGGGGELLI[[[EEENNPQQT@?DBBE;;;>>>??=QSN^_[LLIJJJIIIGHJHILMNPUWVNPOHJGEGDMOLSSSVVVLLLOOOMMMJJJWWWWWWVWZMNPIJMIJMPQTPQTZ[]WX[LMONOQ[\^_acUVXUVX^_bbceX]_TX[dehdehdcjvt~wtjirbfibhjjpt£©°¿ÆДžÌÖÜÙãæIMBSVNPSN=?>=>@1249;:HJGMMJFFD??=@@>AA?UUS>>;TTQFFDGGEUUSMMJLLIOOMOOMLLI\\ZEEB663>>;FFD[[XFFDNNLBEA8:92364682369;:HJGILHDDDFFDIJFJLG[\WPQMJJH??=GGETTQJJH886>>;MMJ;;9HHFFGB?@;NNLIIGFFFSSSUUU???GGGMMM^^^JJMIILEDHDBG;:?88:>>>==:HIE^_[GGEFFFHHJBDFFGIGHJSUTOQPGIF@B?ILHGGEXXXWWWVVVSSSHHHXXXUUUQTSQSUGHJMNPMNPNOQXZ\\]_QSUPQTVXWX[Z[]\UWV^a_abd^cdPUVacbbdcbaehfmmlsbah^cdejkilrv{‚‚‡“}„Ž»ÂÉÙãæGH?PQJWXTMMM@@B//1BBBBB@JMH:=8362798>@?TVSFHDTVQDE@MNIVWSOPLNOJJLGMNIHIEQQOOOM9:6FGBVWSab]GHDLMHJJJ>>@224224DDDIII??=DDALLIHHFMNINOJVWP^_XSTMHIEJJHMMJDDA442::8886886EEBNNL@@>EEBTTQAA?LLIXXVIIIOOOEEETTVPPSVUZFEIBAH:9>88:???@@>JJH]][AA????JJMABFFGJHIMFGIXZ\MONILJMOLIIGTTQ^^\MMJTTQPPNNNLTTQSUTQTSNPOLNMILJILJQTS\^][\^UVXUVXVWZ^_b[\^[\^]^a\]__ac\]_^_babd^_c^_c_ac^_bijlhioeiq_dp^co€‡Ž•œ£@A8MNGOPLIIIDDF113:::;;9PSNAD?3644768:9NPO@B>OSJNOJLMHOPLLMHPQMFGBLMHAB>UUS[[XGHD?@;HIBZ[THIBJLGFFH327224BBELLLPPPAA???=??=??=HHFNOJPQM\]VUVONOHJLGPPNNNL;;9442663774GGEPPNBB@AA?QQOIIGEEBPPNSSPWWWIIIGGI??AFEI@?D=;B98=779??ADDDZZWaa^LLL@@BJJM9:>?@DDEHFGJOPSGHJGIHJMLJJHOPLZ[VUVQXZUVWSQSNVVTPSQX[ZWZXLNMHJIFHGJMLUWV\]_TUWQSUTUWZ[]WX[STVXZ\[\^XZ\[\^Z[]^_bQSUVWZ\]_bbbcce_afadlX\fX]hsy€}„‹GH?LMFTUPFFFQQT113111;;9MOJAD@/10/02468JML=?;JMHNOJIJFOPLMNIGHD?@;IJFEFAFFDUUSWXTPQMNOHWXQJLEQSNLLL99;,,/;;;UUUUUSNNL@@>@@>>>>EEBGGELMHVWSNOHGHABD?MMJPPNHHF886220997@@>SSPDDA==:NNLJJHFFDPPNTTQWWUJJJNNNHHJ@@B;:??>BIHM@@B??AMMMZZWZZWQQQ;;>GGI:;?;=@?@DBDGMNPHILGIHHJIMMJNNLUUSZZWVVTUUSPPNTTQQTSWZXVXWOQPHJIGIHGIHOQPXZ\QSUNOQVWZXZ\Z[]PQTWX[XZ\VWZXZ\WX[]^aPQTQSU]^a_acWX[TU[[^fSV^LOW_ej_ejLMDQSLNOJ@@@SSU>>@777;;9LNJFHE236347679LMO>@=MOLPPNIIGOOMEEBBB@AA?FFDDDAMMJVVTVWSFGBFG@VWPQSLVWSFFF447;;;777LLITTQHIEEFADDDAAAGGGIIGFFDTUPQSNMNIMMJUUSMMJPPN==:++)997??=TTQDDA>>;LLILLIIIGNNLPPN\\ZIIGUUULLLWWZMMOFEI87;668==?HHHQQO\\ZJJJMMOHHJ89=9:>@AEHIMIJMEFHADB?A@OOOQQQSSSVVVNNNQQQNNNPPPSUTLNMMONSUTNPOILJHJIMONWX[TUWJLNMNPTUWTUWIJMTUWTUWWX[TUWVWZUVXSTVJLNXZ\WX[OTVIMSPTZQU]OSXZ^aW\^VWNUVOMNIDDDOOQTTVHHH::8>@==?>*+-&(+67:@AD@BAEGFFFF>>>FFFFFFMMMPPPPPPMMJAA?QQOWXTHIEIJDNOHTUNPQMJJHGGGTTTFFDIIGVWSSTO>?:888668>>>AAA>>;HHFPPNSSPSSPMMJNNLQQOIIG774442??=VVTOOMEEBFFDUUSMMJIIGMMJXZUXXVWWULLLTTTLLN--0336113>>@HHHUUS\\ZOOOLLN??A67::;?=>AGHLDEGFGI=?>EGFLLLTTVLLNOOQLLNNNPGGIQQQSUTOQPQTSOQPWZXPSQOQPZ\[VWZUVXGHJLMOPQTXZ\FGIHILPQTQSUTUWWX[STVZ[]MNPPQTMQSPUWJNTBFLLOUVZ_TXZTUWWXOLMFHIE???DDFGGI>>>11/79878:)*-*+/237469468:=;DDD======AAADDD@@@@@@DDDEEBUUSVWS?@;@A:FG@VWP[\WQQO[[[SSPEEBNOJQSNOPI894AAA>>@>>@======JJHPPNJJHIIGMMJHHFNNLOOM@@>AA?BB@UUSVVTNNLHHFSSPIIGMMJJJHUVQSTOLLIQQONNNOOO;;>IIL88:;;>QQQOOM[[X\\\BBEDDF?@D?@D;=@>?BDEGDEG9;:;>=EEGPPSJJMGGIGGIJJMFFHLLNJMLMONQTSPSQSUTSUTUWVTVUOPSNOQEFHIJMIJMPQTBDFFGILMOPQTSTVTUWMNPVWZTUWOTUFMMPVXPTZEHNIMSTUXQTSQTSUVMPQJEFABBB??AEEGBBB886243236(),/0634:67:78:=?>FFH::=::=??AAAD::=::=AAATTQVVTWXTMNIJLEFG@NOHOPLTTQ^^\]][GHDMNIQSLEF?9:6IILGFJ??A::=999HHHMMJGGEGGEJJHGGENNLSSPGGE??=;;9OOMWWUTTQGGEIIGJJHNNLFFDQSNLMHMNILLINNLNNNFFF@@@GGIMMOUUUGGEXXVNNNAAD88:78;9:>?@D@AE:;>>?A?A@@BAEEGNNPLLNFFHEEGGGIEEGEEGFHGMONOQPSUTTVUQTSVXWOQPTUWNOQEFHEFHBDFMNPHILNOQHILJLNPQTQSUHILPQTWX[MQSAGIMSUQW\IMSMQTTUWTTQVVTJLEIJDHIE??=BBBQQQIII444-/1236+,0/03-/29:>;=??A@JJM447@@B@@B>>@::=::=>>@@@@UUS[\WGHD?@;BD?OPLWXTPPN\\Z\\ZLMHGHDLMHDE@==:LLNMMOAAD==?777AAAJJHLLIHHFBB@>>;@@>@@>BB@>>>999HHHPPPMMJFFDJJHFFDFFDLLIMNINOJJJHIIGMMJ[[[XXXUUULLNPPSQQQDDAUUSPPP99;44778;=>AIJNIJM9:=?@BDEGBDFBBEEEGFFHBBBBBBEEGFFHAADEGFNPONPOSUTPSQILJVXWVXWUVXOPSJLNJLNEFHJLNFGIFGIFGIHILLMOPQTHILMNPWX[GLM=BEJPSOUWJOQLPQPSQNPMTTQNOJOPLPQMGHDDE@GGEBBE87;:;A01778;013124468:;>>?AEEG779779AADIIL99;336::=HHHZZWUUSEEB>>;FFDLLI[[XPPNZZZ\\\PPNBB@MMJBB@BBBDFEILJ;>=FHG=?>8:9MONFHGLNM@B?9;8=?;?A>;>=78:348=>AGHJHJIILHLNIJMIHJGFHGHJINPOFHGFHGFHGLMO?@B:;>ABEIJMEGF?A>TVSOQP@AD89;/039:>FGIUWV=?>;=?:;>?@D=>AEFHSUTOQNEGD=?>@AD?@BLNMNPOPSQQTSQTSJMLNPOX[ZTUWPQTIJMNOQJLNGHJGHJIJMDFEGIHGIHMONFHGLNMVXWMNPINOHMNMQSLPQHMNINOMQPQTSPPNMMJLMHDE>;=8AA?>>@32911:/06;=@6796879;:9:=:;>>>@224779??A==?224//1668===IIGVVTNNL>>;EEBPPNTTQZZZXXX\\\IIIAAAGGGFFF@@@?A@BEDDFEBED:=;8:9JMLEGFILJ>@?362362:=;89;46923967=@AEDFEEGDGIEFHEEGFDFEJLNNOQDEGABEFGIQSUDEG9:=BDFABEDFE@B?OQNTVUIJMABE2379:>EFHVXWEGF;=?78;:;?>?BIJMTVSTVQJMHBEADEG?@DGHJHJILNMQTSMONHJILNMTVUWX[OPSIJMMNPPQTJLNEFHABEGIHHJINPOLNMJMLSUTTVUMONFJLEIJINOHMNEIJGLMINOLPQIIGQQOTUPFG@9:6??===?329,,6-/4?@D?@B243=?>;=?>?A?@D12667:78;-/2+,0126;=?>>>HHFUUSQQOAA?AA?JJHUUSUUUZZZWWWPPP@@@JJJEEEEEEADB@BAHJIADB9;:9;:HJIEGFMONDFE9;8796=?>9:=46912889??@D=?>;>:?A=BEAFHGILJGHJJLN?@B?@B?@BQSUNOQLMO>?AEFHILJ?A>NPMSUTHIL@AD:;?ABFGHJVXWSUT>?A78;89=469GHJQTPWZUOQMILHEFH>?BJLNHILFGIGHJEFHBDFFGILMONOQIJMGHJEFHJLNJLNHILEFHEGFFHGJMLEGFBEDMONQTSNPOHMNGLMLPQJOPBGHDHIGLMINOQQOUUSUVQGHA=>9BB@AAD98?//8+,2>?BEFH687ADB:;>:;>>?B126:;?:;?237014348:;>???MMJLLIDDA>>;FFDHHFQQOWWWUUUZZZPPPEEEIIINNNGGG@BA8:9=?>:=;7989;:FHGDFEHJIDFE=?;9;8DFE>?A469/0667=>?B>@?=?;FHDFHEFHGFHG>?AFGI?@BBDF;=?EFH;=?9:=78:?@B=?>=?>PSQLNM=>@67:67:ABFDEGJML\^]GHJ>?B89=:;?MNPPSOTVQOQMILHGHJABFHILGHJEFHEFH?@B?@BBDFFGIHILMNPNOQ?@BIJMJLNIJMEFHFHGNPOJMLFHGILJMONVXWLNMEIJDHIHMNGLM?DEAFGDHIFJLSSPWWUWXTPQJ=>9??=DDFA@GEEN12878;347798@BA@AD4687;>&*037=14:-17*-3*-3-/2:::NNLQQOIIG??=AA?GGELLINNNUUUWWWNNNAAAHHHQQQGGGEGF?A@9;:ADB8:99;:DFE@BAEGFBED@B?=?;GIH9:=126-/478>;=@ADB>@=BE@?A>:=;798>?A;=?67978:67989;78:3479:>:;?9:=>?AGHJPQTFGJ46989=?@DEFHEGF\^]LMO=>A12667:FGIQTPX[V^a\JMIHIL;=@?@D>?B?@D?@D;=@:;?@AEHIMGHJ?@BJLN9:=ABELMODEG=>@HJIOQPJMLFHGFHGEGFNPOHJIAFG@EFDHIAFG>BD;@ABGHGLMOOMUUSUVQOPI894886==?>=D88A/0689=6799;:ADB>?A12637=$(-,06(+1*-3(+1*-3014;;;LLINNLHHF@@>==:??=HHFJJJUUUTTTQQQ===GGGMMMIII@BA=?>9;:HJI?A@>@?DFEBEDADBBEDEGDGIFILJ;=?46912834:78;>@?>@=GIEEGDBEDADB>?A9:=12434767989;89;67:78>;=B89=89;DEGNOSDEJ12878;=>AABEDFE[]\PQTBDG9:>FGJMNPSUQWZU]_[PSOLMO?@D;=@:;??@D>?B78;9:>ABFIJNMNPGHJPQT@ADGHJIJMGHJGHJPSQOQPNPOEGFGIHEGFMONMONFJLDHIFJLDHI;@A;@ABGHEIJSSPUUSPQMGHA340997;;>218++4,-378;679364>@?>?A469-17&*2/2:,08%)1%)1*-6239PPPQQOBB@442==:??=;;9==:IIIOOOUUUSSS;;;AAAIIIDDD@BA=?>>@?JMLEGF?A@?A@?A@9;:?A@GIFLNJILJ;=?469128/060149;::=9FHDBEA=?>8:99:=67901334746878:78:46934:89?46967:HIMIJN?@F67=34889=?@BDFESUTPQTDEH>?BGHLIJMOQNSUPZ\WUWTOPS?@D9:@9:@>?E:;A78>89?=>D@AEABEABENOQEFHEFHFGIJLNLMOGIHGIHMONJMLGIHADBFHGHJIBGH?DE@EF=AB9>?;@ABGHBGHNNLQSNOPIFG@:;7::8779,+2%&,,-3469124687>?A;=?014),4#&/&*2"%-"%-#&,*-3348DFELLIFFD??=886DDALLIGGEBBBNNNPPNTTQ;;9IIG@@@>>>9;:@BAGIHPSQOQPEGFDFE?A@=?>BEDLNJQTPGIH9:=126-/467=237:=;=?;@B?=?;9;:78:89=67:01434812634834812622;33=12878;IJNNOSDEJ78>12889==>@ABESTVVWZJLNFGJNOSHILILHJMHQTOTVSMON;=?9:>67=:;A9:@12878>>?EABH>?B?@BHILABE89;?@BJLNIJMFHGJMLLNMQTSNPOADBFHGIJMDHI?DE?DE;@A7;=;@ABGH@EFPQMMNGOPISTMMNIBBB=;@43:)*0()/78;3474689:=78;/06**6%%1$$-%%/()/126236013>@?BED@BA9;:;>=ADBFHGLNMPPPHHFQSNQSNHIELMHHHFBBB78:@ADFHEMOLLNJJMIIJM@AD>?ADFEOQNNPMADB78:34:,,612812689;9;::=;89;78;78>14:14=03;/2=-1;69A26>03;009009/0678;GHJJLO@AG34:1289:@?@D=>AFGJVWZEFHEFH@@BLLNFFFIIGUUSUUSNNLGGGEFH89=34:67=11:88A66?88A?@DEFHHILBDF=>@=>@GHJEFHEFHBDFIJMNOQGHJGHJEFHHIL:;?=>A>?B:;?9:>9:>=>A:;?PQJIJDZ[TMNIDDA===76:218*+1,-3:;?236-/1348128((1))4%%2%%1&&0&(--/2468687?A@:=;798798?A@?A@BEDADB???GGGJLGOPI892>?:???;;>89=ABEFHENPLQTOGIFFGIFGJBDFABEGIHNPMJML=>@239,,634:67=9:>236?@B?@D;=B46;37?,0:+-:02?13@79F14?,08--922;017237:;>QSVFGM67=34:78>EFL=>DBDGNOSGHJ>?A??ALLNHHHFFFSSPWWUPQMEEBNOQ?@D34:239//866?11=>>G?@DDEGGHJ@AD:;>=>@DEGDEG>?A=>@HILNOQMNPFGIABEGHJDEH@AE;=@78;=>A=>A>?B=>AQSLGHAWXQOPLBB@III649107+,2128>?B013+,/126/06%%/&&2$$1%%1))2%&,*+/9:=>@?>@?9;:364243:=;BED>@?>@?GGIGGGNNLLMHAB>IIG;;;==?9:>>?A>@=DFASUP@B?;=?@AE@AD9:=:=;GIFNPO?@B017//834:89?=>A89;>?A89=34:34:26>+/9*,9/1>13@79F14?,0822>//8,-3348?@BOPT@AG23923967=DEJ;=BABFMNQHIL;=?JJMIILFFFHHHVVTTTQMNIHHFX[ZWX\89=67=34:66?11:88A=>A@AEABF:;?78;;=@?@DABF?@B>?AHILNOQMNPFGIABEGHJ?@D9:>67:469BDGEFIBDGDEHLMFQSLTUNNOJMMJ@@@327/-4()/128=>A)*,*+-/03,-3$$-%%1$$1&&2**3#$*&(+;=?BEDEGF679/02679679:;>ABE@ADDDFDDFNNLPPNOOMMMJJJMAAD>?BDEG>@=>@;NPL:=9124014@AD>?A:=;BEALNM=>@-/400967=23934812478:78;67=34:/2:-1;,/;+-:-0=68E26@03;11=11:,-3014FGISTWIJP67=-/467==>D9:@ABFQSVIJM=>@>>@@@BEEEFFFTTQVVTOPLFFDZ\[abdABF237/0612899B67=BDIEFIEFI=>A469:;?;=@@AE?@B=>@DEGHILGHJGHJEFHHILGHL=>A469126>?BBDG@AE?@DSTMIJDQSLVWSEEB@@@98=/-4()/128;=@+,/*+-)*-#$*$$-%%1##0$$0&&0&(-)*-BDFILJ236/03,-1348;=@67:78;34898===?GGGLLLAAA???336-,1+,0236AD@HJFTVQGIF124/03=>@>?AADBEGDBED89;,-3++412846;78;01378:89=89?78>,08(+6-0=02?+-:+-:+/9+/7--9,,6,-3469LMOLMPNOU:;A/0646;89?9:@@AEIJN@AD9:=AAD==?:::AAATTQ[[XLMHLLIZ\[TUWMNP=>A126/06*+19:@;=B;=B>?E46;67==>D?@F>?B;=?;=?BDFEFHIJMIJMHILFGIDEGEFH679124?@BHILHILDEG?@9@A:PQJUVQTTQFFF438(&-()/78>BDG/02)*,)*-#$*%%/##/""/$$0**3()/014GHJTUW89=/03+,0-/2/03014:;?237,+0;:?BBEHHHEEE@@B76:0/34699:=:=9?A=OQMLNJ:;>78;89;;=?>@?=?;>@?78:-/4,,646;46;469,-089;67:128-/4+/7),7,/;,/;*,9*,9*-8*-6--9,,6&(-9:>JLNJLOQSXLMS0172399:@46;BDGDEH>?A;=?HHJ99;888>>>MMJOOMIJFMNIPSOTVUUVXNOQ:;?014/0646;89?67=78>34:01789?;=B:;A9:>468=>@EFHGHJGHJEFHBDFDEGABE9:=89;=>@DEGEFH>?A:;4>?8PQJWXTMMJBBB327%$+*+1?@FJLO347,-0,-1)*0++4((3$$1**666?$%+126BDFSTV:;?-/4,-3+,2239-/4017)*00/698=HHJHHHEEE??A98=/-4:;?;=?8:79;7NPLJMI9:=67:89;@AD@BA9;88:9679/06--746;128126,-078:4699:@ABH+/7),7,/;(*7)+8)+8),7),4))4009+,278;BDFFGJFGM:;A9:@01723934:>?B@AE;=?:;>>>@::=>>>===IIGOOMSTOQSNLNJQTSNPOIJM469-/2126;=B:;A66?33=22;11:77@;;E;=B@AE9:=;=?@AD?@BDEGGHJIJMHJI=?>687798=?>ADBFHGADB>?8:;4IJDTUPIIGHHH:9>&%,+,2DEJQSV78:124237/0622;%%1""/**699B()/78;?@BQSU9:>+,2/06,-3,-39:@89?67=43::9>AADHHHBBB::=76:+*189=78:;>::=8QTOEGD-/1+,0236>?A>@?241364468017--7017,-3014/0223678;78>34:*-6*-8+-:$&3(*7(*7(+6(+3++7))2,-39:>GHJIJNOPVQSX@AG017*+146;;=@?@D89;89;??A==?777;;;FFDOOMTUPPQMLNJSUQLNMGHJ/03-/2+,0;=B??H66?22;33=33=22;33=67=78;4689:=9:=@ADEFHHILIJMDFE4763648:9@BA@BAFHGHJI \ No newline at end of file
diff --git a/include/webp/encode.h b/include/webp/encode.h
index 3c263748..b3f05b1f 100644
--- a/include/webp/encode.h
+++ b/include/webp/encode.h
@@ -419,7 +419,9 @@ WEBP_EXTERN(int) WebPPictureView(const WebPPicture* src,
WEBP_EXTERN(int) WebPPictureIsView(const WebPPicture* picture);
// Rescale a picture to new dimension width x height.
-// Now gamma correction is applied.
+// If either 'width' or 'height' (but not both) is 0 the corresponding
+// dimension will be calculated preserving the aspect ratio.
+// No gamma correction is applied.
// Returns false in case of error (invalid parameter or insufficient memory).
WEBP_EXTERN(int) WebPPictureRescale(WebPPicture* pic, int width, int height);
diff --git a/include/webp/types.h b/include/webp/types.h
index 568d1f26..9b036e0c 100644
--- a/include/webp/types.h
+++ b/include/webp/types.h
@@ -18,10 +18,11 @@
#ifndef _MSC_VER
#include <inttypes.h>
-#ifdef __STRICT_ANSI__
-#define WEBP_INLINE
-#else /* __STRICT_ANSI__ */
+#if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \
+ (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
#define WEBP_INLINE inline
+#else
+#define WEBP_INLINE
#endif
#else
typedef signed char int8_t;
diff --git a/src/Android.mk b/src/Android.mk
index 027a17b4..694e4b73 100644
--- a/src/Android.mk
+++ b/src/Android.mk
@@ -17,13 +17,27 @@ LOCAL_PATH:= $(call my-dir)
###############################################
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
+ dsp/alpha_processing.c \
+ dsp/alpha_processing_sse2.c \
+ dsp/cpu-features.c \
+ dsp/cpu.c \
+ dsp/enc.c \
+ dsp/enc_avx2.c \
+ dsp/enc_mips32.c \
+ dsp/enc_neon.c \
+ dsp/enc_sse2.c \
+ dsp/lossless.c \
+ dsp/lossless_mips32.c \
+ dsp/lossless_neon.c \
+ dsp/lossless_sse2.c \
+ dsp/yuv.c \
enc/alpha.c \
enc/analysis.c \
enc/backward_references.c \
enc/config.c \
enc/cost.c \
enc/filter.c \
- enc/frame.c\
+ enc/frame.c \
enc/histogram.c \
enc/iterator.c \
enc/picture.c \
@@ -33,25 +47,11 @@ LOCAL_SRC_FILES := \
enc/picture_tools.c \
enc/quant.c \
enc/syntax.c \
- enc/tree.c \
enc/token.c \
+ enc/tree.c \
enc/vp8l.c \
enc/webpenc.c \
- dsp/alpha_processing.c \
- dsp/alpha_processing_sse2.c \
- dsp/cpu.c \
- dsp/cpu-features.c \
- dsp/enc.c \
- dsp/enc_avx2.c \
- dsp/enc_mips32.c \
- dsp/enc_neon.c \
- dsp/enc_sse2.c \
- dsp/lossless.c \
- dsp/lossless_mips32.c \
- dsp/lossless_neon.c \
- dsp/lossless_sse2.c \
- dsp/yuv.c \
- dsp/yuv_sse2.c \
+ utils/bit_reader.c \
utils/bit_writer.c \
utils/color_cache.c \
utils/filters.c \
@@ -89,10 +89,11 @@ LOCAL_SRC_FILES := \
dec/vp8.c \
dec/vp8l.c \
dec/webp.c \
+ demux/demux.c \
dsp/alpha_processing.c \
dsp/alpha_processing_sse2.c \
- dsp/cpu.c \
dsp/cpu-features.c \
+ dsp/cpu.c \
dsp/dec.c \
dsp/dec_clip_tables.c \
dsp/dec_mips32.c \
@@ -108,7 +109,6 @@ LOCAL_SRC_FILES := \
dsp/yuv.c \
dsp/yuv_mips32.c \
dsp/yuv_sse2.c \
- demux/demux.c \
utils/bit_reader.c \
utils/color_cache.c \
utils/filters.c \
diff --git a/src/dec/alpha.c b/src/dec/alpha.c
index 24ca92dc..f23ba7d6 100644
--- a/src/dec/alpha.c
+++ b/src/dec/alpha.c
@@ -17,7 +17,7 @@
#include "./vp8li.h"
#include "../utils/quant_levels_dec.h"
#include "../utils/utils.h"
-#include "webp/format_constants.h"
+#include "../webp/format_constants.h"
//------------------------------------------------------------------------------
// ALPHDecoder object.
diff --git a/src/dec/decode_vp8.h b/src/dec/decode_vp8.h
index 2bf1bdbb..b9337bbe 100644
--- a/src/dec/decode_vp8.h
+++ b/src/dec/decode_vp8.h
@@ -14,7 +14,7 @@
#ifndef WEBP_WEBP_DECODE_VP8_H_
#define WEBP_WEBP_DECODE_VP8_H_
-#include "webp/decode.h"
+#include "../webp/decode.h"
#ifdef __cplusplus
extern "C" {
diff --git a/src/dec/idec.c b/src/dec/idec.c
index 5d8bb0c2..e003851e 100644
--- a/src/dec/idec.c
+++ b/src/dec/idec.c
@@ -357,30 +357,33 @@ static VP8StatusCode DecodeVP8FrameHeader(WebPIDecoder* const idec) {
}
// Partition #0
-static int CopyParts0Data(WebPIDecoder* const idec) {
+static VP8StatusCode CopyParts0Data(WebPIDecoder* const idec) {
VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
VP8BitReader* const br = &dec->br_;
- const size_t psize = br->buf_end_ - br->buf_;
+ const size_t part_size = br->buf_end_ - br->buf_;
MemBuffer* const mem = &idec->mem_;
assert(!idec->is_lossless_);
assert(mem->part0_buf_ == NULL);
- assert(psize > 0);
- assert(psize <= mem->part0_size_); // Format limit: no need for runtime check
+ // the following is a format limitation, no need for runtime check:
+ assert(part_size <= mem->part0_size_);
+ if (part_size == 0) { // can't have zero-size partition #0
+ return VP8_STATUS_BITSTREAM_ERROR;
+ }
if (mem->mode_ == MEM_MODE_APPEND) {
// We copy and grab ownership of the partition #0 data.
- uint8_t* const part0_buf = (uint8_t*)WebPSafeMalloc(1ULL, psize);
+ uint8_t* const part0_buf = (uint8_t*)WebPSafeMalloc(1ULL, part_size);
if (part0_buf == NULL) {
- return 0;
+ return VP8_STATUS_OUT_OF_MEMORY;
}
- memcpy(part0_buf, br->buf_, psize);
+ memcpy(part0_buf, br->buf_, part_size);
mem->part0_buf_ = part0_buf;
br->buf_ = part0_buf;
- br->buf_end_ = part0_buf + psize;
+ br->buf_end_ = part0_buf + part_size;
} else {
// Else: just keep pointers to the partition #0's data in dec_->br_.
}
- mem->start_ += psize;
- return 1;
+ mem->start_ += part_size;
+ return VP8_STATUS_OK;
}
static VP8StatusCode DecodePartition0(WebPIDecoder* const idec) {
@@ -414,8 +417,10 @@ static VP8StatusCode DecodePartition0(WebPIDecoder* const idec) {
dec->mt_method_ = VP8GetThreadMethod(params->options, NULL,
io->width, io->height);
VP8InitDithering(params->options, dec);
- if (!CopyParts0Data(idec)) {
- return IDecError(idec, VP8_STATUS_OUT_OF_MEMORY);
+
+ dec->status_ = CopyParts0Data(idec);
+ if (dec->status_ != VP8_STATUS_OK) {
+ return IDecError(idec, dec->status_);
}
// Finish setting up the decoding parameters. Will call io->setup().
diff --git a/src/dec/tree.c b/src/dec/tree.c
index 88238885..31208d9d 100644
--- a/src/dec/tree.c
+++ b/src/dec/tree.c
@@ -11,7 +11,7 @@
//
// Author: Skal (pascal.massimino@gmail.com)
-#include "vp8i.h"
+#include "./vp8i.h"
#include "../utils/bit_reader_inl.h"
#define USE_GENERIC_TREE
diff --git a/src/dec/vp8.c b/src/dec/vp8.c
index 47249d64..89d478a4 100644
--- a/src/dec/vp8.c
+++ b/src/dec/vp8.c
@@ -562,6 +562,7 @@ int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br) {
}
block->non_zero_y_ = 0;
block->non_zero_uv_ = 0;
+ block->dither_ = 0;
}
if (dec->filter_type_ > 0) { // store filter info
diff --git a/src/dec/vp8i.h b/src/dec/vp8i.h
index 29701be7..a02d9ff7 100644
--- a/src/dec/vp8i.h
+++ b/src/dec/vp8i.h
@@ -31,7 +31,7 @@ extern "C" {
// version numbers
#define DEC_MAJ_VERSION 0
#define DEC_MIN_VERSION 4
-#define DEC_REV_VERSION 2
+#define DEC_REV_VERSION 3
// intra prediction modes
enum { B_DC_PRED = 0, // 4x4 modes
diff --git a/src/dec/webp.c b/src/dec/webp.c
index c5f8f94d..59e21a9d 100644
--- a/src/dec/webp.c
+++ b/src/dec/webp.c
@@ -16,7 +16,7 @@
#include "./vp8i.h"
#include "./vp8li.h"
#include "./webpi.h"
-#include "webp/mux_types.h" // ALPHA_FLAG
+#include "../webp/mux_types.h" // ALPHA_FLAG
//------------------------------------------------------------------------------
// RIFF layout is:
diff --git a/src/demux/demux.c b/src/demux/demux.c
index 5aabdd25..55a7918f 100644
--- a/src/demux/demux.c
+++ b/src/demux/demux.c
@@ -11,7 +11,7 @@
//
#ifdef HAVE_CONFIG_H
-#include "webp/config.h"
+#include "../webp/config.h"
#endif
#include <assert.h>
@@ -19,9 +19,9 @@
#include <string.h>
#include "../utils/utils.h"
-#include "webp/decode.h" // WebPGetFeatures
-#include "webp/demux.h"
-#include "webp/format_constants.h"
+#include "../webp/decode.h" // WebPGetFeatures
+#include "../webp/demux.h"
+#include "../webp/format_constants.h"
#define DMUX_MAJ_VERSION 0
#define DMUX_MIN_VERSION 2
diff --git a/src/dsp/alpha_processing.c b/src/dsp/alpha_processing.c
index d0f7a6cc..c8e0b4bc 100644
--- a/src/dsp/alpha_processing.c
+++ b/src/dsp/alpha_processing.c
@@ -311,7 +311,12 @@ int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
extern void WebPInitAlphaProcessingSSE2(void);
+static volatile VP8CPUInfo alpha_processing_last_cpuinfo_used =
+ (VP8CPUInfo)&alpha_processing_last_cpuinfo_used;
+
void WebPInitAlphaProcessing(void) {
+ if (alpha_processing_last_cpuinfo_used == VP8GetCPUInfo) return;
+
WebPMultARGBRow = MultARGBRow;
WebPMultRow = MultRow;
WebPApplyAlphaMultiply = ApplyAlphaMultiply;
@@ -326,4 +331,5 @@ void WebPInitAlphaProcessing(void) {
}
#endif
}
+ alpha_processing_last_cpuinfo_used = VP8GetCPUInfo;
}
diff --git a/src/dsp/cpu.c b/src/dsp/cpu.c
index 70ba2ab0..45329349 100644
--- a/src/dsp/cpu.c
+++ b/src/dsp/cpu.c
@@ -29,16 +29,18 @@ static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
"cpuid\n"
"xchg %%edi, %%ebx\n"
: "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
- : "a"(info_type));
+ : "a"(info_type), "c"(0));
}
#elif defined(__i386__) || defined(__x86_64__)
static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
__asm__ volatile (
"cpuid\n"
: "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
- : "a"(info_type));
+ : "a"(info_type), "c"(0));
}
-#elif defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729 // >= VS2008 SP1
+#elif (defined(_M_X64) || defined(_M_IX86)) && \
+ defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729 // >= VS2008 SP1
+#include <intrin.h>
#define GetCPUInfo(info, type) __cpuidex(info, type, 0) // set ecx=0
#elif defined(WEBP_MSC_SSE2)
#define GetCPUInfo __cpuid
@@ -55,7 +57,9 @@ static WEBP_INLINE uint64_t xgetbv(void) {
: "=a"(eax), "=d"(edx) : "c" (ecx));
return ((uint64_t)edx << 32) | eax;
}
-#elif defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 160040219 // >= VS2010 SP1
+#elif (defined(_M_X64) || defined(_M_IX86)) && \
+ defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 160040219 // >= VS2010 SP1
+#include <immintrin.h>
#define xgetbv() _xgetbv(0)
#elif defined(_MSC_VER) && defined(_M_IX86)
static WEBP_INLINE uint64_t xgetbv(void) {
diff --git a/src/dsp/dec.c b/src/dsp/dec.c
index 65a2a885..3a8dc81f 100644
--- a/src/dsp/dec.c
+++ b/src/dsp/dec.c
@@ -688,7 +688,12 @@ extern void VP8DspInitSSE2(void);
extern void VP8DspInitNEON(void);
extern void VP8DspInitMIPS32(void);
+static volatile VP8CPUInfo dec_last_cpuinfo_used =
+ (VP8CPUInfo)&dec_last_cpuinfo_used;
+
void VP8DspInit(void) {
+ if (dec_last_cpuinfo_used == VP8GetCPUInfo) return;
+
VP8InitClipTables();
VP8TransformWHT = TransformWHT;
@@ -727,5 +732,5 @@ void VP8DspInit(void) {
}
#endif
}
+ dec_last_cpuinfo_used = VP8GetCPUInfo;
}
-
diff --git a/src/dsp/dsp.h b/src/dsp/dsp.h
index 3b31ae08..838a70a1 100644
--- a/src/dsp/dsp.h
+++ b/src/dsp/dsp.h
@@ -15,10 +15,10 @@
#define WEBP_DSP_DSP_H_
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include "../webp/config.h"
#endif
-#include "webp/types.h"
+#include "../webp/types.h"
#ifdef __cplusplus
extern "C" {
@@ -66,7 +66,10 @@ extern "C" {
#define WEBP_ANDROID_NEON // Android targets that might support NEON
#endif
-#if defined(__ARM_NEON__) || defined(__aarch64__)
+// The intrinsics currently cause compiler errors with arm-nacl-gcc and the
+// inline assembly would need to be modified for use with Native Client.
+#if (defined(__ARM_NEON__) || defined(__aarch64__)) \
+ && !defined(__native_client__)
#define WEBP_USE_NEON
#endif
diff --git a/src/dsp/enc.c b/src/dsp/enc.c
index e4ea8cb8..f4e72d45 100644
--- a/src/dsp/enc.c
+++ b/src/dsp/enc.c
@@ -692,7 +692,12 @@ extern void VP8EncDspInitAVX2(void);
extern void VP8EncDspInitNEON(void);
extern void VP8EncDspInitMIPS32(void);
+static volatile VP8CPUInfo enc_last_cpuinfo_used =
+ (VP8CPUInfo)&enc_last_cpuinfo_used;
+
void VP8EncDspInit(void) {
+ if (enc_last_cpuinfo_used == VP8GetCPUInfo) return;
+
VP8DspInit(); // common inverse transforms
InitTables();
@@ -737,5 +742,6 @@ void VP8EncDspInit(void) {
}
#endif
}
+ enc_last_cpuinfo_used = VP8GetCPUInfo;
}
diff --git a/src/dsp/enc_neon.c b/src/dsp/enc_neon.c
index 42041f73..5814fac9 100644
--- a/src/dsp/enc_neon.c
+++ b/src/dsp/enc_neon.c
@@ -1012,8 +1012,10 @@ static int QuantizeBlock(int16_t in[16], int16_t out[16],
const int16x8_t out0 = Quantize(in, mtx, 0);
const int16x8_t out1 = Quantize(in, mtx, 8);
uint8x8x4_t shuffles;
- // vtbl4_u8 is marked unavailable for iOS arm64, use wider versions there.
-#if defined(__APPLE__) && defined(__aarch64__)
+ // vtbl?_u8 are marked unavailable for iOS arm64 with Xcode < 6.3, use
+ // non-standard versions there.
+#if defined(__APPLE__) && defined(__aarch64__) && \
+ defined(__apple_build_version__) && (__apple_build_version__< 6020037)
uint8x16x2_t all_out;
INIT_VECTOR2(all_out, vreinterpretq_u8_s16(out0), vreinterpretq_u8_s16(out1));
INIT_VECTOR4(shuffles,
diff --git a/src/dsp/lossless.c b/src/dsp/lossless.c
index a1bf3584..ee334bce 100644
--- a/src/dsp/lossless.c
+++ b/src/dsp/lossless.c
@@ -1590,7 +1590,12 @@ extern void VP8LDspInitSSE2(void);
extern void VP8LDspInitNEON(void);
extern void VP8LDspInitMIPS32(void);
+static volatile VP8CPUInfo lossless_last_cpuinfo_used =
+ (VP8CPUInfo)&lossless_last_cpuinfo_used;
+
void VP8LDspInit(void) {
+ if (lossless_last_cpuinfo_used == VP8GetCPUInfo) return;
+
memcpy(VP8LPredictors, kPredictorsC, sizeof(VP8LPredictors));
VP8LSubtractGreenFromBlueAndRed = VP8LSubtractGreenFromBlueAndRed_C;
@@ -1634,6 +1639,7 @@ void VP8LDspInit(void) {
}
#endif
}
+ lossless_last_cpuinfo_used = VP8GetCPUInfo;
}
//------------------------------------------------------------------------------
diff --git a/src/dsp/lossless.h b/src/dsp/lossless.h
index 08be9375..8c7551c9 100644
--- a/src/dsp/lossless.h
+++ b/src/dsp/lossless.h
@@ -15,8 +15,8 @@
#ifndef WEBP_DSP_LOSSLESS_H_
#define WEBP_DSP_LOSSLESS_H_
-#include "webp/types.h"
-#include "webp/decode.h"
+#include "../webp/types.h"
+#include "../webp/decode.h"
#include "../enc/histogram.h"
#include "../utils/utils.h"
diff --git a/src/dsp/lossless_neon.c b/src/dsp/lossless_neon.c
index 987767b5..8c82b197 100644
--- a/src/dsp/lossless_neon.c
+++ b/src/dsp/lossless_neon.c
@@ -259,20 +259,45 @@ static uint32_t Predictor13(uint32_t left, const uint32_t* const top) {
//------------------------------------------------------------------------------
// Subtract-Green Transform
-// vtbl? are unavailable in iOS/arm64 builds.
-#if !defined(__aarch64__)
+// vtbl?_u8 are marked unavailable for iOS arm64 with Xcode < 6.3, use
+// non-standard versions there.
+#if defined(__APPLE__) && defined(__aarch64__) && \
+ defined(__apple_build_version__) && (__apple_build_version__< 6020037)
+#define USE_VTBLQ
+#endif
+
+#ifdef USE_VTBLQ
+// 255 = byte will be zeroed
+static const uint8_t kGreenShuffle[16] = {
+ 1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255
+};
-// 255 = byte will be zero'd
+static WEBP_INLINE uint8x16_t DoGreenShuffle(const uint8x16_t argb,
+ const uint8x16_t shuffle) {
+ return vcombine_u8(vtbl1q_u8(argb, vget_low_u8(shuffle)),
+ vtbl1q_u8(argb, vget_high_u8(shuffle)));
+}
+#else // !USE_VTBLQ
+// 255 = byte will be zeroed
static const uint8_t kGreenShuffle[8] = { 1, 255, 1, 255, 5, 255, 5, 255 };
+static WEBP_INLINE uint8x16_t DoGreenShuffle(const uint8x16_t argb,
+ const uint8x8_t shuffle) {
+ return vcombine_u8(vtbl1_u8(vget_low_u8(argb), shuffle),
+ vtbl1_u8(vget_high_u8(argb), shuffle));
+}
+#endif // USE_VTBLQ
+
static void SubtractGreenFromBlueAndRed(uint32_t* argb_data, int num_pixels) {
const uint32_t* const end = argb_data + (num_pixels & ~3);
+#ifdef USE_VTBLQ
+ const uint8x16_t shuffle = vld1q_u8(kGreenShuffle);
+#else
const uint8x8_t shuffle = vld1_u8(kGreenShuffle);
+#endif
for (; argb_data < end; argb_data += 4) {
const uint8x16_t argb = vld1q_u8((uint8_t*)argb_data);
- const uint8x16_t greens =
- vcombine_u8(vtbl1_u8(vget_low_u8(argb), shuffle),
- vtbl1_u8(vget_high_u8(argb), shuffle));
+ const uint8x16_t greens = DoGreenShuffle(argb, shuffle);
vst1q_u8((uint8_t*)argb_data, vsubq_u8(argb, greens));
}
// fallthrough and finish off with plain-C
@@ -281,19 +306,21 @@ static void SubtractGreenFromBlueAndRed(uint32_t* argb_data, int num_pixels) {
static void AddGreenToBlueAndRed(uint32_t* argb_data, int num_pixels) {
const uint32_t* const end = argb_data + (num_pixels & ~3);
+#ifdef USE_VTBLQ
+ const uint8x16_t shuffle = vld1q_u8(kGreenShuffle);
+#else
const uint8x8_t shuffle = vld1_u8(kGreenShuffle);
+#endif
for (; argb_data < end; argb_data += 4) {
const uint8x16_t argb = vld1q_u8((uint8_t*)argb_data);
- const uint8x16_t greens =
- vcombine_u8(vtbl1_u8(vget_low_u8(argb), shuffle),
- vtbl1_u8(vget_high_u8(argb), shuffle));
+ const uint8x16_t greens = DoGreenShuffle(argb, shuffle);
vst1q_u8((uint8_t*)argb_data, vaddq_u8(argb, greens));
}
// fallthrough and finish off with plain-C
VP8LAddGreenToBlueAndRed_C(argb_data, num_pixels & 3);
}
-#endif // !__aarch64__
+#undef USE_VTBLQ
#endif // USE_INTRINSICS
@@ -320,11 +347,9 @@ void VP8LDspInitNEON(void) {
VP8LPredictors[12] = Predictor12;
VP8LPredictors[13] = Predictor13;
-#if !defined(__aarch64__)
VP8LSubtractGreenFromBlueAndRed = SubtractGreenFromBlueAndRed;
VP8LAddGreenToBlueAndRed = AddGreenToBlueAndRed;
#endif
-#endif
#endif // WEBP_USE_NEON
}
diff --git a/src/dsp/upsampling.c b/src/dsp/upsampling.c
index 2b1656bf..53c68d5a 100644
--- a/src/dsp/upsampling.c
+++ b/src/dsp/upsampling.c
@@ -189,7 +189,12 @@ const WebPYUV444Converter WebPYUV444Converters[MODE_LAST] = {
extern void WebPInitUpsamplersSSE2(void);
extern void WebPInitUpsamplersNEON(void);
+static volatile VP8CPUInfo upsampling_last_cpuinfo_used2 =
+ (VP8CPUInfo)&upsampling_last_cpuinfo_used2;
+
void WebPInitUpsamplers(void) {
+ if (upsampling_last_cpuinfo_used2 == VP8GetCPUInfo) return;
+
#ifdef FANCY_UPSAMPLING
WebPUpsamplers[MODE_RGB] = UpsampleRgbLinePair;
WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePair;
@@ -217,6 +222,7 @@ void WebPInitUpsamplers(void) {
#endif
}
#endif // FANCY_UPSAMPLING
+ upsampling_last_cpuinfo_used2 = VP8GetCPUInfo;
}
//------------------------------------------------------------------------------
diff --git a/src/dsp/yuv.c b/src/dsp/yuv.c
index d7cb4ebc..6f422da5 100644
--- a/src/dsp/yuv.c
+++ b/src/dsp/yuv.c
@@ -123,7 +123,12 @@ WebPSamplerRowFunc WebPSamplers[MODE_LAST];
extern void WebPInitSamplersSSE2(void);
extern void WebPInitSamplersMIPS32(void);
+static volatile VP8CPUInfo yuv_last_cpuinfo_used =
+ (VP8CPUInfo)&yuv_last_cpuinfo_used;
+
void WebPInitSamplers(void) {
+ if (yuv_last_cpuinfo_used == VP8GetCPUInfo) return;
+
WebPSamplers[MODE_RGB] = YuvToRgbRow;
WebPSamplers[MODE_RGBA] = YuvToRgbaRow;
WebPSamplers[MODE_BGR] = YuvToBgrRow;
@@ -149,6 +154,7 @@ void WebPInitSamplers(void) {
}
#endif // WEBP_USE_MIPS32
}
+ yuv_last_cpuinfo_used = VP8GetCPUInfo;
}
//-----------------------------------------------------------------------------
diff --git a/src/utils/bit_reader.c b/src/utils/bit_reader.c
index bbddd42c..64503e6b 100644
--- a/src/utils/bit_reader.c
+++ b/src/utils/bit_reader.c
@@ -12,7 +12,7 @@
// Author: Skal (pascal.massimino@gmail.com)
#ifdef HAVE_CONFIG_H
-#include "webp/config.h"
+#include "../webp/config.h"
#endif
#include "./bit_reader_inl.h"
diff --git a/src/utils/bit_reader.h b/src/utils/bit_reader.h
index a6ae85e5..f569734f 100644
--- a/src/utils/bit_reader.h
+++ b/src/utils/bit_reader.h
@@ -19,7 +19,7 @@
#ifdef _MSC_VER
#include <stdlib.h> // _byteswap_ulong
#endif
-#include "webp/types.h"
+#include "../webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/src/utils/bit_reader_inl.h b/src/utils/bit_reader_inl.h
index 9f59ca3d..81427c62 100644
--- a/src/utils/bit_reader_inl.h
+++ b/src/utils/bit_reader_inl.h
@@ -17,7 +17,7 @@
#define WEBP_UTILS_BIT_READER_INL_H_
#ifdef HAVE_CONFIG_H
-#include "webp/config.h"
+#include "../webp/config.h"
#endif
#ifdef WEBP_FORCE_ALIGNED
diff --git a/src/utils/bit_writer.h b/src/utils/bit_writer.h
index 107a2b18..c80d22ae 100644
--- a/src/utils/bit_writer.h
+++ b/src/utils/bit_writer.h
@@ -14,7 +14,7 @@
#ifndef WEBP_UTILS_BIT_WRITER_H_
#define WEBP_UTILS_BIT_WRITER_H_
-#include "webp/types.h"
+#include "../webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/src/utils/color_cache.h b/src/utils/color_cache.h
index 26aac997..0f824ed4 100644
--- a/src/utils/color_cache.h
+++ b/src/utils/color_cache.h
@@ -15,7 +15,7 @@
#ifndef WEBP_UTILS_COLOR_CACHE_H_
#define WEBP_UTILS_COLOR_CACHE_H_
-#include "webp/types.h"
+#include "../webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/src/utils/endian_inl.h b/src/utils/endian_inl.h
index f362a6e8..cd56c37f 100644
--- a/src/utils/endian_inl.h
+++ b/src/utils/endian_inl.h
@@ -13,11 +13,11 @@
#define WEBP_UTILS_ENDIAN_INL_H_
#ifdef HAVE_CONFIG_H
-#include "webp/config.h"
+#include "../webp/config.h"
#endif
#include "../dsp/dsp.h"
-#include "webp/types.h"
+#include "../webp/types.h"
// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
#if !defined(WORDS_BIGENDIAN) && \
diff --git a/src/utils/filters.h b/src/utils/filters.h
index 5676279e..dde39cb5 100644
--- a/src/utils/filters.h
+++ b/src/utils/filters.h
@@ -14,7 +14,7 @@
#ifndef WEBP_UTILS_FILTERS_H_
#define WEBP_UTILS_FILTERS_H_
-#include "webp/types.h"
+#include "../webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/src/utils/huffman.c b/src/utils/huffman.c
index 1916a008..c4c16d9e 100644
--- a/src/utils/huffman.c
+++ b/src/utils/huffman.c
@@ -16,7 +16,7 @@
#include <string.h>
#include "./huffman.h"
#include "../utils/utils.h"
-#include "webp/format_constants.h"
+#include "../webp/format_constants.h"
// Uncomment the following to use look-up table for ReverseBits()
// (might be faster on some platform)
diff --git a/src/utils/huffman.h b/src/utils/huffman.h
index bf1588dd..624bc175 100644
--- a/src/utils/huffman.h
+++ b/src/utils/huffman.h
@@ -15,8 +15,8 @@
#define WEBP_UTILS_HUFFMAN_H_
#include <assert.h>
-#include "webp/format_constants.h"
-#include "webp/types.h"
+#include "../webp/format_constants.h"
+#include "../webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/src/utils/huffman_encode.c b/src/utils/huffman_encode.c
index d7aad6f5..6421c2be 100644
--- a/src/utils/huffman_encode.c
+++ b/src/utils/huffman_encode.c
@@ -16,7 +16,7 @@
#include <string.h>
#include "./huffman_encode.h"
#include "../utils/utils.h"
-#include "webp/format_constants.h"
+#include "../webp/format_constants.h"
// -----------------------------------------------------------------------------
// Util function to optimize the symbol map for RLE coding
diff --git a/src/utils/huffman_encode.h b/src/utils/huffman_encode.h
index daea39ff..91aa18f4 100644
--- a/src/utils/huffman_encode.h
+++ b/src/utils/huffman_encode.h
@@ -14,7 +14,7 @@
#ifndef WEBP_UTILS_HUFFMAN_ENCODE_H_
#define WEBP_UTILS_HUFFMAN_ENCODE_H_
-#include "webp/types.h"
+#include "../webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/src/utils/quant_levels.h b/src/utils/quant_levels.h
index 3916b977..1cb5a32c 100644
--- a/src/utils/quant_levels.h
+++ b/src/utils/quant_levels.h
@@ -16,7 +16,7 @@
#include <stdlib.h>
-#include "webp/types.h"
+#include "../webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/src/utils/quant_levels_dec.h b/src/utils/quant_levels_dec.h
index 29c7e6e2..9aab0680 100644
--- a/src/utils/quant_levels_dec.h
+++ b/src/utils/quant_levels_dec.h
@@ -14,7 +14,7 @@
#ifndef WEBP_UTILS_QUANT_LEVELS_DEC_H_
#define WEBP_UTILS_QUANT_LEVELS_DEC_H_
-#include "webp/types.h"
+#include "../webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/src/utils/random.h b/src/utils/random.h
index 745f3e2e..c392a615 100644
--- a/src/utils/random.h
+++ b/src/utils/random.h
@@ -15,7 +15,7 @@
#define WEBP_UTILS_RANDOM_H_
#include <assert.h>
-#include "webp/types.h"
+#include "../webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/src/utils/rescaler.h b/src/utils/rescaler.h
index 6699c5b4..a6f37871 100644
--- a/src/utils/rescaler.h
+++ b/src/utils/rescaler.h
@@ -18,7 +18,7 @@
extern "C" {
#endif
-#include "webp/types.h"
+#include "../webp/types.h"
// Structure used for on-the-fly rescaling
typedef struct {
diff --git a/src/utils/thread.h b/src/utils/thread.h
index eb714e1d..7bd451b1 100644
--- a/src/utils/thread.h
+++ b/src/utils/thread.h
@@ -15,10 +15,10 @@
#define WEBP_UTILS_THREAD_H_
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include "../webp/config.h"
#endif
-#include "webp/types.h"
+#include "../webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/src/utils/utils.h b/src/utils/utils.h
index a8e8c3d6..f2c498a9 100644
--- a/src/utils/utils.h
+++ b/src/utils/utils.h
@@ -17,7 +17,7 @@
#include <assert.h>
-#include "webp/types.h"
+#include "../webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/src/webp/decode.h b/src/webp/decode.h
new file mode 100644
index 00000000..8d3f7be9
--- /dev/null
+++ b/src/webp/decode.h
@@ -0,0 +1,503 @@
+// Copyright 2010 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.
+// -----------------------------------------------------------------------------
+//
+// Main decoding functions for WebP images.
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_WEBP_DECODE_H_
+#define WEBP_WEBP_DECODE_H_
+
+#include "./types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WEBP_DECODER_ABI_VERSION 0x0203 // MAJOR(8b) + MINOR(8b)
+
+// Note: forward declaring enumerations is not allowed in (strict) C and C++,
+// the types are left here for reference.
+// typedef enum VP8StatusCode VP8StatusCode;
+// typedef enum WEBP_CSP_MODE WEBP_CSP_MODE;
+typedef struct WebPRGBABuffer WebPRGBABuffer;
+typedef struct WebPYUVABuffer WebPYUVABuffer;
+typedef struct WebPDecBuffer WebPDecBuffer;
+typedef struct WebPIDecoder WebPIDecoder;
+typedef struct WebPBitstreamFeatures WebPBitstreamFeatures;
+typedef struct WebPDecoderOptions WebPDecoderOptions;
+typedef struct WebPDecoderConfig WebPDecoderConfig;
+
+// Return the decoder's version number, packed in hexadecimal using 8bits for
+// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
+WEBP_EXTERN(int) WebPGetDecoderVersion(void);
+
+// Retrieve basic header information: width, height.
+// This function will also validate the header and return 0 in
+// case of formatting error.
+// Pointers 'width' and 'height' can be passed NULL if deemed irrelevant.
+WEBP_EXTERN(int) WebPGetInfo(const uint8_t* data, size_t data_size,
+ int* width, int* height);
+
+// Decodes WebP images pointed to by 'data' and returns RGBA samples, along
+// with the dimensions in *width and *height. The ordering of samples in
+// memory is R, G, B, A, R, G, B, A... in scan order (endian-independent).
+// The returned pointer should be deleted calling free().
+// Returns NULL in case of error.
+WEBP_EXTERN(uint8_t*) WebPDecodeRGBA(const uint8_t* data, size_t data_size,
+ int* width, int* height);
+
+// Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data.
+WEBP_EXTERN(uint8_t*) WebPDecodeARGB(const uint8_t* data, size_t data_size,
+ int* width, int* height);
+
+// Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data.
+WEBP_EXTERN(uint8_t*) WebPDecodeBGRA(const uint8_t* data, size_t data_size,
+ int* width, int* height);
+
+// Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data.
+// If the bitstream contains transparency, it is ignored.
+WEBP_EXTERN(uint8_t*) WebPDecodeRGB(const uint8_t* data, size_t data_size,
+ int* width, int* height);
+
+// Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data.
+WEBP_EXTERN(uint8_t*) WebPDecodeBGR(const uint8_t* data, size_t data_size,
+ int* width, int* height);
+
+
+// Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer
+// returned is the Y samples buffer. Upon return, *u and *v will point to
+// the U and V chroma data. These U and V buffers need NOT be free()'d,
+// unlike the returned Y luma one. The dimension of the U and V planes
+// are both (*width + 1) / 2 and (*height + 1)/ 2.
+// Upon return, the Y buffer has a stride returned as '*stride', while U and V
+// have a common stride returned as '*uv_stride'.
+// Return NULL in case of error.
+// (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr
+WEBP_EXTERN(uint8_t*) WebPDecodeYUV(const uint8_t* data, size_t data_size,
+ int* width, int* height,
+ uint8_t** u, uint8_t** v,
+ int* stride, int* uv_stride);
+
+// These five functions are variants of the above ones, that decode the image
+// directly into a pre-allocated buffer 'output_buffer'. The maximum storage
+// available in this buffer is indicated by 'output_buffer_size'. If this
+// storage is not sufficient (or an error occurred), NULL is returned.
+// Otherwise, output_buffer is returned, for convenience.
+// The parameter 'output_stride' specifies the distance (in bytes)
+// between scanlines. Hence, output_buffer_size is expected to be at least
+// output_stride x picture-height.
+WEBP_EXTERN(uint8_t*) WebPDecodeRGBAInto(
+ const uint8_t* data, size_t data_size,
+ uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+WEBP_EXTERN(uint8_t*) WebPDecodeARGBInto(
+ const uint8_t* data, size_t data_size,
+ uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+WEBP_EXTERN(uint8_t*) WebPDecodeBGRAInto(
+ const uint8_t* data, size_t data_size,
+ uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+
+// RGB and BGR variants. Here too the transparency information, if present,
+// will be dropped and ignored.
+WEBP_EXTERN(uint8_t*) WebPDecodeRGBInto(
+ const uint8_t* data, size_t data_size,
+ uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+WEBP_EXTERN(uint8_t*) WebPDecodeBGRInto(
+ const uint8_t* data, size_t data_size,
+ uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+
+// WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly
+// into pre-allocated luma/chroma plane buffers. This function requires the
+// strides to be passed: one for the luma plane and one for each of the
+// chroma ones. The size of each plane buffer is passed as 'luma_size',
+// 'u_size' and 'v_size' respectively.
+// Pointer to the luma plane ('*luma') is returned or NULL if an error occurred
+// during decoding (or because some buffers were found to be too small).
+WEBP_EXTERN(uint8_t*) WebPDecodeYUVInto(
+ const uint8_t* data, size_t data_size,
+ uint8_t* luma, size_t luma_size, int luma_stride,
+ uint8_t* u, size_t u_size, int u_stride,
+ uint8_t* v, size_t v_size, int v_stride);
+
+//------------------------------------------------------------------------------
+// Output colorspaces and buffer
+
+// Colorspaces
+// Note: the naming describes the byte-ordering of packed samples in memory.
+// For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,...
+// Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels.
+// RGBA-4444 and RGB-565 colorspaces are represented by following byte-order:
+// RGBA-4444: [r3 r2 r1 r0 g3 g2 g1 g0], [b3 b2 b1 b0 a3 a2 a1 a0], ...
+// RGB-565: [r4 r3 r2 r1 r0 g5 g4 g3], [g2 g1 g0 b4 b3 b2 b1 b0], ...
+// In the case WEBP_SWAP_16BITS_CSP is defined, the bytes are swapped for
+// these two modes:
+// RGBA-4444: [b3 b2 b1 b0 a3 a2 a1 a0], [r3 r2 r1 r0 g3 g2 g1 g0], ...
+// RGB-565: [g2 g1 g0 b4 b3 b2 b1 b0], [r4 r3 r2 r1 r0 g5 g4 g3], ...
+
+typedef enum WEBP_CSP_MODE {
+ MODE_RGB = 0, MODE_RGBA = 1,
+ MODE_BGR = 2, MODE_BGRA = 3,
+ MODE_ARGB = 4, MODE_RGBA_4444 = 5,
+ MODE_RGB_565 = 6,
+ // RGB-premultiplied transparent modes (alpha value is preserved)
+ MODE_rgbA = 7,
+ MODE_bgrA = 8,
+ MODE_Argb = 9,
+ MODE_rgbA_4444 = 10,
+ // YUV modes must come after RGB ones.
+ MODE_YUV = 11, MODE_YUVA = 12, // yuv 4:2:0
+ MODE_LAST = 13
+} WEBP_CSP_MODE;
+
+// Some useful macros:
+static WEBP_INLINE int WebPIsPremultipliedMode(WEBP_CSP_MODE mode) {
+ return (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb ||
+ mode == MODE_rgbA_4444);
+}
+
+static WEBP_INLINE int WebPIsAlphaMode(WEBP_CSP_MODE mode) {
+ return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB ||
+ mode == MODE_RGBA_4444 || mode == MODE_YUVA ||
+ WebPIsPremultipliedMode(mode));
+}
+
+static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) {
+ return (mode < MODE_YUV);
+}
+
+//------------------------------------------------------------------------------
+// WebPDecBuffer: Generic structure for describing the output sample buffer.
+
+struct WebPRGBABuffer { // view as RGBA
+ uint8_t* rgba; // pointer to RGBA samples
+ int stride; // stride in bytes from one scanline to the next.
+ size_t size; // total size of the *rgba buffer.
+};
+
+struct WebPYUVABuffer { // view as YUVA
+ uint8_t* y, *u, *v, *a; // pointer to luma, chroma U/V, alpha samples
+ int y_stride; // luma stride
+ int u_stride, v_stride; // chroma strides
+ int a_stride; // alpha stride
+ size_t y_size; // luma plane size
+ size_t u_size, v_size; // chroma planes size
+ size_t a_size; // alpha-plane size
+};
+
+// Output buffer
+struct WebPDecBuffer {
+ WEBP_CSP_MODE colorspace; // Colorspace.
+ int width, height; // Dimensions.
+ int is_external_memory; // If true, 'internal_memory' pointer is not used.
+ union {
+ WebPRGBABuffer RGBA;
+ WebPYUVABuffer YUVA;
+ } u; // Nameless union of buffer parameters.
+ uint32_t pad[4]; // padding for later use
+
+ uint8_t* private_memory; // Internally allocated memory (only when
+ // is_external_memory is false). Should not be used
+ // externally, but accessed via the buffer union.
+};
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(int) WebPInitDecBufferInternal(WebPDecBuffer*, int);
+
+// Initialize the structure as empty. Must be called before any other use.
+// Returns false in case of version mismatch
+static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) {
+ return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION);
+}
+
+// Free any memory associated with the buffer. Must always be called last.
+// Note: doesn't free the 'buffer' structure itself.
+WEBP_EXTERN(void) WebPFreeDecBuffer(WebPDecBuffer* buffer);
+
+//------------------------------------------------------------------------------
+// Enumeration of the status codes
+
+typedef enum VP8StatusCode {
+ VP8_STATUS_OK = 0,
+ VP8_STATUS_OUT_OF_MEMORY,
+ VP8_STATUS_INVALID_PARAM,
+ VP8_STATUS_BITSTREAM_ERROR,
+ VP8_STATUS_UNSUPPORTED_FEATURE,
+ VP8_STATUS_SUSPENDED,
+ VP8_STATUS_USER_ABORT,
+ VP8_STATUS_NOT_ENOUGH_DATA
+} VP8StatusCode;
+
+//------------------------------------------------------------------------------
+// Incremental decoding
+//
+// This API allows streamlined decoding of partial data.
+// Picture can be incrementally decoded as data become available thanks to the
+// WebPIDecoder object. This object can be left in a SUSPENDED state if the
+// picture is only partially decoded, pending additional input.
+// Code example:
+//
+// WebPInitDecBuffer(&buffer);
+// buffer.colorspace = mode;
+// ...
+// WebPIDecoder* idec = WebPINewDecoder(&buffer);
+// while (has_more_data) {
+// // ... (get additional data)
+// status = WebPIAppend(idec, new_data, new_data_size);
+// if (status != VP8_STATUS_SUSPENDED ||
+// break;
+// }
+//
+// // The above call decodes the current available buffer.
+// // Part of the image can now be refreshed by calling to
+// // WebPIDecGetRGB()/WebPIDecGetYUVA() etc.
+// }
+// WebPIDelete(idec);
+
+// Creates a new incremental decoder with the supplied buffer parameter.
+// This output_buffer can be passed NULL, in which case a default output buffer
+// is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer'
+// is kept, which means that the lifespan of 'output_buffer' must be larger than
+// that of the returned WebPIDecoder object.
+// The supplied 'output_buffer' content MUST NOT be changed between calls to
+// WebPIAppend() or WebPIUpdate() unless 'output_buffer.is_external_memory' is
+// set to 1. In such a case, it is allowed to modify the pointers, size and
+// stride of output_buffer.u.RGBA or output_buffer.u.YUVA, provided they remain
+// within valid bounds.
+// All other fields of WebPDecBuffer MUST remain constant between calls.
+// Returns NULL if the allocation failed.
+WEBP_EXTERN(WebPIDecoder*) WebPINewDecoder(WebPDecBuffer* output_buffer);
+
+// This function allocates and initializes an incremental-decoder object, which
+// will output the RGB/A samples specified by 'csp' into a preallocated
+// buffer 'output_buffer'. The size of this buffer is at least
+// 'output_buffer_size' and the stride (distance in bytes between two scanlines)
+// is specified by 'output_stride'.
+// Additionally, output_buffer can be passed NULL in which case the output
+// buffer will be allocated automatically when the decoding starts. The
+// colorspace 'csp' is taken into account for allocating this buffer. All other
+// parameters are ignored.
+// Returns NULL if the allocation failed, or if some parameters are invalid.
+WEBP_EXTERN(WebPIDecoder*) WebPINewRGB(
+ WEBP_CSP_MODE csp,
+ uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
+
+// This function allocates and initializes an incremental-decoder object, which
+// will output the raw luma/chroma samples into a preallocated planes if
+// supplied. The luma plane is specified by its pointer 'luma', its size
+// 'luma_size' and its stride 'luma_stride'. Similarly, the chroma-u plane
+// is specified by the 'u', 'u_size' and 'u_stride' parameters, and the chroma-v
+// plane by 'v' and 'v_size'. And same for the alpha-plane. The 'a' pointer
+// can be pass NULL in case one is not interested in the transparency plane.
+// Conversely, 'luma' can be passed NULL if no preallocated planes are supplied.
+// In this case, the output buffer will be automatically allocated (using
+// MODE_YUVA) when decoding starts. All parameters are then ignored.
+// Returns NULL if the allocation failed or if a parameter is invalid.
+WEBP_EXTERN(WebPIDecoder*) WebPINewYUVA(
+ uint8_t* luma, size_t luma_size, int luma_stride,
+ uint8_t* u, size_t u_size, int u_stride,
+ uint8_t* v, size_t v_size, int v_stride,
+ uint8_t* a, size_t a_size, int a_stride);
+
+// Deprecated version of the above, without the alpha plane.
+// Kept for backward compatibility.
+WEBP_EXTERN(WebPIDecoder*) WebPINewYUV(
+ uint8_t* luma, size_t luma_size, int luma_stride,
+ uint8_t* u, size_t u_size, int u_stride,
+ uint8_t* v, size_t v_size, int v_stride);
+
+// Deletes the WebPIDecoder object and associated memory. Must always be called
+// if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded.
+WEBP_EXTERN(void) WebPIDelete(WebPIDecoder* idec);
+
+// Copies and decodes the next available data. Returns VP8_STATUS_OK when
+// the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more
+// data is expected. Returns error in other cases.
+WEBP_EXTERN(VP8StatusCode) WebPIAppend(
+ WebPIDecoder* idec, const uint8_t* data, size_t data_size);
+
+// A variant of the above function to be used when data buffer contains
+// partial data from the beginning. In this case data buffer is not copied
+// to the internal memory.
+// Note that the value of the 'data' pointer can change between calls to
+// WebPIUpdate, for instance when the data buffer is resized to fit larger data.
+WEBP_EXTERN(VP8StatusCode) WebPIUpdate(
+ WebPIDecoder* idec, const uint8_t* data, size_t data_size);
+
+// Returns the RGB/A image decoded so far. Returns NULL if output params
+// are not initialized yet. The RGB/A output type corresponds to the colorspace
+// specified during call to WebPINewDecoder() or WebPINewRGB().
+// *last_y is the index of last decoded row in raster scan order. Some pointers
+// (*last_y, *width etc.) can be NULL if corresponding information is not
+// needed.
+WEBP_EXTERN(uint8_t*) WebPIDecGetRGB(
+ const WebPIDecoder* idec, int* last_y,
+ int* width, int* height, int* stride);
+
+// Same as above function to get a YUVA image. Returns pointer to the luma
+// plane or NULL in case of error. If there is no alpha information
+// the alpha pointer '*a' will be returned NULL.
+WEBP_EXTERN(uint8_t*) WebPIDecGetYUVA(
+ const WebPIDecoder* idec, int* last_y,
+ uint8_t** u, uint8_t** v, uint8_t** a,
+ int* width, int* height, int* stride, int* uv_stride, int* a_stride);
+
+// Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the
+// alpha information (if present). Kept for backward compatibility.
+static WEBP_INLINE uint8_t* WebPIDecGetYUV(
+ const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v,
+ int* width, int* height, int* stride, int* uv_stride) {
+ return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height,
+ stride, uv_stride, NULL);
+}
+
+// Generic call to retrieve information about the displayable area.
+// If non NULL, the left/right/width/height pointers are filled with the visible
+// rectangular area so far.
+// Returns NULL in case the incremental decoder object is in an invalid state.
+// Otherwise returns the pointer to the internal representation. This structure
+// is read-only, tied to WebPIDecoder's lifespan and should not be modified.
+WEBP_EXTERN(const WebPDecBuffer*) WebPIDecodedArea(
+ const WebPIDecoder* idec, int* left, int* top, int* width, int* height);
+
+//------------------------------------------------------------------------------
+// Advanced decoding parametrization
+//
+// Code sample for using the advanced decoding API
+/*
+ // 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', if needed
+ config.no_fancy_upsampling = 1;
+ config.output.colorspace = MODE_BGRA;
+ // etc.
+
+ // Note that you can also make config.output point to an externally
+ // supplied memory buffer, provided it's big enough to store the decoded
+ // picture. Otherwise, config.output will just be used to allocate memory
+ // and store the decoded picture.
+
+ // D) Decode!
+ CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
+
+ // E) Decoded image is now in config.output (and config.output.u.RGBA)
+
+ // F) 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);
+*/
+
+// Features gathered from the bitstream
+struct WebPBitstreamFeatures {
+ int width; // Width in pixels, as read from the bitstream.
+ int height; // Height in pixels, as read from the bitstream.
+ int has_alpha; // True if the bitstream contains an alpha channel.
+ int has_animation; // True if the bitstream is an animation.
+ int format; // 0 = undefined (/mixed), 1 = lossy, 2 = lossless
+
+ // Unused for now:
+ int no_incremental_decoding; // if true, using incremental decoding is not
+ // recommended.
+ int rotate; // TODO(later)
+ int uv_sampling; // should be 0 for now. TODO(later)
+ uint32_t pad[2]; // padding for later use
+};
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(VP8StatusCode) WebPGetFeaturesInternal(
+ const uint8_t*, size_t, WebPBitstreamFeatures*, int);
+
+// Retrieve features from the bitstream. The *features structure is filled
+// with information gathered from the bitstream.
+// Returns VP8_STATUS_OK when the features are successfully retrieved. Returns
+// VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the
+// features from headers. Returns error in other cases.
+static WEBP_INLINE VP8StatusCode WebPGetFeatures(
+ const uint8_t* data, size_t data_size,
+ WebPBitstreamFeatures* features) {
+ return WebPGetFeaturesInternal(data, data_size, features,
+ WEBP_DECODER_ABI_VERSION);
+}
+
+// Decoding options
+struct WebPDecoderOptions {
+ int bypass_filtering; // if true, skip the in-loop filtering
+ int no_fancy_upsampling; // if true, use faster pointwise upsampler
+ int use_cropping; // if true, cropping is applied _first_
+ int crop_left, crop_top; // top-left position for cropping.
+ // Will be snapped to even values.
+ int crop_width, crop_height; // dimension of the cropping area
+ int use_scaling; // if true, scaling is applied _afterward_
+ int scaled_width, scaled_height; // final resolution
+ int use_threads; // if true, use multi-threaded decoding
+ int dithering_strength; // dithering strength (0=Off, 100=full)
+#if WEBP_DECODER_ABI_VERSION > 0x0203
+ int flip; // flip output vertically
+#endif
+#if WEBP_DECODER_ABI_VERSION > 0x0204
+ int alpha_dithering_strength; // alpha dithering strength in [0..100]
+#endif
+
+ // Unused for now:
+ int force_rotation; // forced rotation (to be applied _last_)
+ int no_enhancement; // if true, discard enhancement layer
+#if WEBP_DECODER_ABI_VERSION < 0x0203
+ uint32_t pad[5]; // padding for later use
+#elif WEBP_DECODER_ABI_VERSION < 0x0204
+ uint32_t pad[4]; // padding for later use
+#else
+ uint32_t pad[3]; // padding for later use
+#endif
+};
+
+// Main object storing the configuration for advanced decoding.
+struct WebPDecoderConfig {
+ WebPBitstreamFeatures input; // Immutable bitstream features (optional)
+ WebPDecBuffer output; // Output buffer (can point to external mem)
+ WebPDecoderOptions options; // Decoding options
+};
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(int) WebPInitDecoderConfigInternal(WebPDecoderConfig*, int);
+
+// Initialize the configuration as empty. This function must always be
+// called first, unless WebPGetFeatures() is to be called.
+// Returns false in case of mismatched version.
+static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) {
+ return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION);
+}
+
+// Instantiate a new incremental decoder object with the requested
+// configuration. The bitstream can be passed using 'data' and 'data_size'
+// parameter, in which case the features will be parsed and stored into
+// config->input. Otherwise, 'data' can be NULL and no parsing will occur.
+// Note that 'config' can be NULL too, in which case a default configuration
+// is used.
+// The return WebPIDecoder object must always be deleted calling WebPIDelete().
+// Returns NULL in case of error (and config->status will then reflect
+// the error condition).
+WEBP_EXTERN(WebPIDecoder*) WebPIDecode(const uint8_t* data, size_t data_size,
+ WebPDecoderConfig* config);
+
+// Non-incremental version. This version decodes the full data at once, taking
+// 'config' into account. Returns decoding status (which should be VP8_STATUS_OK
+// if the decoding was successful).
+WEBP_EXTERN(VP8StatusCode) WebPDecode(const uint8_t* data, size_t data_size,
+ WebPDecoderConfig* config);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_WEBP_DECODE_H_ */
diff --git a/src/webp/demux.h b/src/webp/demux.h
new file mode 100644
index 00000000..2da3239d
--- /dev/null
+++ b/src/webp/demux.h
@@ -0,0 +1,224 @@
+// Copyright 2012 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.
+// -----------------------------------------------------------------------------
+//
+// Demux API.
+// Enables extraction of image and extended format data from WebP files.
+
+// 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);
+*/
+
+#ifndef WEBP_WEBP_DEMUX_H_
+#define WEBP_WEBP_DEMUX_H_
+
+#include "./mux_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WEBP_DEMUX_ABI_VERSION 0x0101 // MAJOR(8b) + MINOR(8b)
+
+// Note: forward declaring enumerations is not allowed in (strict) C and C++,
+// the types are left here for reference.
+// typedef enum WebPDemuxState WebPDemuxState;
+// typedef enum WebPFormatFeature WebPFormatFeature;
+typedef struct WebPDemuxer WebPDemuxer;
+typedef struct WebPIterator WebPIterator;
+typedef struct WebPChunkIterator WebPChunkIterator;
+
+//------------------------------------------------------------------------------
+
+// Returns the version number of the demux library, packed in hexadecimal using
+// 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.
+WEBP_EXTERN(int) WebPGetDemuxVersion(void);
+
+//------------------------------------------------------------------------------
+// Life of a Demux object
+
+typedef enum WebPDemuxState {
+ WEBP_DEMUX_PARSE_ERROR = -1, // An error occurred while parsing.
+ WEBP_DEMUX_PARSING_HEADER = 0, // Not enough data to parse full header.
+ WEBP_DEMUX_PARSED_HEADER = 1, // Header parsing complete,
+ // data may be available.
+ WEBP_DEMUX_DONE = 2 // Entire file has been parsed.
+} WebPDemuxState;
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(WebPDemuxer*) WebPDemuxInternal(
+ const WebPData*, int, WebPDemuxState*, int);
+
+// Parses the full WebP file given by 'data'.
+// Returns a WebPDemuxer object on successful parse, NULL otherwise.
+static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) {
+ return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION);
+}
+
+// Parses the possibly incomplete WebP file given by 'data'.
+// If 'state' is non-NULL it will be set to indicate the status of the demuxer.
+// Returns NULL in case of error or if there isn't enough data to start parsing;
+// and a WebPDemuxer object on successful parse.
+// Note that WebPDemuxer keeps internal pointers to 'data' memory segment.
+// If this data is volatile, the demuxer object should be deleted (by calling
+// WebPDemuxDelete()) and WebPDemuxPartial() called again on the new data.
+// This is usually an inexpensive operation.
+static WEBP_INLINE WebPDemuxer* WebPDemuxPartial(
+ const WebPData* data, WebPDemuxState* state) {
+ return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION);
+}
+
+// Frees memory associated with 'dmux'.
+WEBP_EXTERN(void) WebPDemuxDelete(WebPDemuxer* dmux);
+
+//------------------------------------------------------------------------------
+// Data/information extraction.
+
+typedef enum WebPFormatFeature {
+ WEBP_FF_FORMAT_FLAGS, // Extended format flags present in the 'VP8X' chunk.
+ WEBP_FF_CANVAS_WIDTH,
+ WEBP_FF_CANVAS_HEIGHT,
+ WEBP_FF_LOOP_COUNT,
+ WEBP_FF_BACKGROUND_COLOR,
+ WEBP_FF_FRAME_COUNT // Number of frames present in the demux object.
+ // In case of a partial demux, this is the number of
+ // frames seen so far, with the last frame possibly
+ // being partial.
+} WebPFormatFeature;
+
+// Get the 'feature' value from the 'dmux'.
+// NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial()
+// returned a state > WEBP_DEMUX_PARSING_HEADER.
+WEBP_EXTERN(uint32_t) WebPDemuxGetI(
+ const WebPDemuxer* dmux, WebPFormatFeature feature);
+
+//------------------------------------------------------------------------------
+// Frame iteration.
+
+struct WebPIterator {
+ int frame_num;
+ int num_frames; // equivalent to WEBP_FF_FRAME_COUNT.
+ int fragment_num;
+ int num_fragments;
+ int x_offset, y_offset; // offset relative to the canvas.
+ int width, height; // dimensions of this frame or fragment.
+ int duration; // display duration in milliseconds.
+ WebPMuxAnimDispose dispose_method; // dispose method for the frame.
+ int complete; // true if 'fragment' contains a full frame. partial images
+ // may still be decoded with the WebP incremental decoder.
+ WebPData fragment; // The frame or fragment given by 'frame_num' and
+ // 'fragment_num'.
+ int has_alpha; // True if the frame or fragment contains transparency.
+ WebPMuxAnimBlend blend_method; // Blend operation for the frame.
+
+ uint32_t pad[2]; // padding for later use.
+ void* private_; // for internal use only.
+};
+
+// Retrieves frame 'frame_number' from 'dmux'.
+// 'iter->fragment' points to the first fragment on return from this function.
+// Individual fragments may be extracted using WebPDemuxSelectFragment().
+// Setting 'frame_number' equal to 0 will return the last frame of the image.
+// Returns false if 'dmux' is NULL or frame 'frame_number' is not present.
+// Call WebPDemuxReleaseIterator() when use of the iterator is complete.
+// NOTE: 'dmux' must persist for the lifetime of 'iter'.
+WEBP_EXTERN(int) WebPDemuxGetFrame(
+ const WebPDemuxer* dmux, int frame_number, WebPIterator* iter);
+
+// Sets 'iter->fragment' to point to the next ('iter->frame_num' + 1) or
+// previous ('iter->frame_num' - 1) frame. These functions do not loop.
+// Returns true on success, false otherwise.
+WEBP_EXTERN(int) WebPDemuxNextFrame(WebPIterator* iter);
+WEBP_EXTERN(int) WebPDemuxPrevFrame(WebPIterator* iter);
+
+// Sets 'iter->fragment' to reflect fragment number 'fragment_num'.
+// Returns true if fragment 'fragment_num' is present, false otherwise.
+WEBP_EXTERN(int) WebPDemuxSelectFragment(WebPIterator* iter, int fragment_num);
+
+// Releases any memory associated with 'iter'.
+// Must be called before any subsequent calls to WebPDemuxGetChunk() on the same
+// iter. Also, must be called before destroying the associated WebPDemuxer with
+// WebPDemuxDelete().
+WEBP_EXTERN(void) WebPDemuxReleaseIterator(WebPIterator* iter);
+
+//------------------------------------------------------------------------------
+// Chunk iteration.
+
+struct WebPChunkIterator {
+ // The current and total number of chunks with the fourcc given to
+ // WebPDemuxGetChunk().
+ int chunk_num;
+ int num_chunks;
+ WebPData chunk; // The payload of the chunk.
+
+ uint32_t pad[6]; // padding for later use
+ void* private_;
+};
+
+// Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from
+// 'dmux'.
+// 'fourcc' is a character array containing the fourcc of the chunk to return,
+// e.g., "ICCP", "XMP ", "EXIF", etc.
+// Setting 'chunk_number' equal to 0 will return the last chunk in a set.
+// Returns true if the chunk is found, false otherwise. Image related chunk
+// payloads are accessed through WebPDemuxGetFrame() and related functions.
+// Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete.
+// NOTE: 'dmux' must persist for the lifetime of the iterator.
+WEBP_EXTERN(int) WebPDemuxGetChunk(const WebPDemuxer* dmux,
+ const char fourcc[4], int chunk_number,
+ WebPChunkIterator* iter);
+
+// Sets 'iter->chunk' to point to the next ('iter->chunk_num' + 1) or previous
+// ('iter->chunk_num' - 1) chunk. These functions do not loop.
+// Returns true on success, false otherwise.
+WEBP_EXTERN(int) WebPDemuxNextChunk(WebPChunkIterator* iter);
+WEBP_EXTERN(int) WebPDemuxPrevChunk(WebPChunkIterator* iter);
+
+// Releases any memory associated with 'iter'.
+// Must be called before destroying the associated WebPDemuxer with
+// WebPDemuxDelete().
+WEBP_EXTERN(void) WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_WEBP_DEMUX_H_ */
diff --git a/src/webp/encode.h b/src/webp/encode.h
new file mode 100644
index 00000000..b3f05b1f
--- /dev/null
+++ b/src/webp/encode.h
@@ -0,0 +1,520 @@
+// Copyright 2011 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.
+// -----------------------------------------------------------------------------
+//
+// WebP encoder: main interface
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_WEBP_ENCODE_H_
+#define WEBP_WEBP_ENCODE_H_
+
+#include "./types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WEBP_ENCODER_ABI_VERSION 0x0202 // MAJOR(8b) + MINOR(8b)
+
+// Note: forward declaring enumerations is not allowed in (strict) C and C++,
+// the types are left here for reference.
+// typedef enum WebPImageHint WebPImageHint;
+// typedef enum WebPEncCSP WebPEncCSP;
+// typedef enum WebPPreset WebPPreset;
+// typedef enum WebPEncodingError WebPEncodingError;
+typedef struct WebPConfig WebPConfig;
+typedef struct WebPPicture WebPPicture; // main structure for I/O
+typedef struct WebPAuxStats WebPAuxStats;
+typedef struct WebPMemoryWriter WebPMemoryWriter;
+
+// Return the encoder's version number, packed in hexadecimal using 8bits for
+// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
+WEBP_EXTERN(int) WebPGetEncoderVersion(void);
+
+//------------------------------------------------------------------------------
+// One-stop-shop call! No questions asked:
+
+// Returns the size of the compressed data (pointed to by *output), or 0 if
+// an error occurred. The compressed data must be released by the caller
+// using the call 'free(*output)'.
+// These functions compress using the lossy format, and the quality_factor
+// can go from 0 (smaller output, lower quality) to 100 (best quality,
+// larger output).
+WEBP_EXTERN(size_t) WebPEncodeRGB(const uint8_t* rgb,
+ int width, int height, int stride,
+ float quality_factor, uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeBGR(const uint8_t* bgr,
+ int width, int height, int stride,
+ float quality_factor, uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeRGBA(const uint8_t* rgba,
+ int width, int height, int stride,
+ float quality_factor, uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeBGRA(const uint8_t* bgra,
+ int width, int height, int stride,
+ float quality_factor, uint8_t** output);
+
+// These functions are the equivalent of the above, but compressing in a
+// lossless manner. Files are usually larger than lossy format, but will
+// not suffer any compression loss.
+WEBP_EXTERN(size_t) WebPEncodeLosslessRGB(const uint8_t* rgb,
+ int width, int height, int stride,
+ uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeLosslessBGR(const uint8_t* bgr,
+ int width, int height, int stride,
+ uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeLosslessRGBA(const uint8_t* rgba,
+ int width, int height, int stride,
+ uint8_t** output);
+WEBP_EXTERN(size_t) WebPEncodeLosslessBGRA(const uint8_t* bgra,
+ int width, int height, int stride,
+ uint8_t** output);
+
+//------------------------------------------------------------------------------
+// Coding parameters
+
+// Image characteristics hint for the underlying encoder.
+typedef enum WebPImageHint {
+ WEBP_HINT_DEFAULT = 0, // default preset.
+ WEBP_HINT_PICTURE, // digital picture, like portrait, inner shot
+ WEBP_HINT_PHOTO, // outdoor photograph, with natural lighting
+ WEBP_HINT_GRAPH, // Discrete tone image (graph, map-tile etc).
+ WEBP_HINT_LAST
+} WebPImageHint;
+
+// Compression parameters.
+struct WebPConfig {
+ int lossless; // Lossless encoding (0=lossy(default), 1=lossless).
+ float quality; // between 0 (smallest file) and 100 (biggest)
+ int method; // quality/speed trade-off (0=fast, 6=slower-better)
+
+ WebPImageHint image_hint; // Hint for image type (lossless only for now).
+
+ // Parameters related to lossy compression only:
+ int target_size; // if non-zero, set the desired target size in bytes.
+ // Takes precedence over the 'compression' parameter.
+ float target_PSNR; // if non-zero, specifies the minimal distortion to
+ // try to achieve. Takes precedence over target_size.
+ int segments; // maximum number of segments to use, in [1..4]
+ int sns_strength; // Spatial Noise Shaping. 0=off, 100=maximum.
+ int filter_strength; // range: [0 = off .. 100 = strongest]
+ int filter_sharpness; // range: [0 = off .. 7 = least sharp]
+ int filter_type; // filtering type: 0 = simple, 1 = strong (only used
+ // if filter_strength > 0 or autofilter > 0)
+ int autofilter; // Auto adjust filter's strength [0 = off, 1 = on]
+ int alpha_compression; // Algorithm for encoding the alpha plane (0 = none,
+ // 1 = compressed with WebP lossless). Default is 1.
+ int alpha_filtering; // Predictive filtering method for alpha plane.
+ // 0: none, 1: fast, 2: best. Default if 1.
+ int alpha_quality; // Between 0 (smallest size) and 100 (lossless).
+ // Default is 100.
+ int pass; // number of entropy-analysis passes (in [1..10]).
+
+ int show_compressed; // if true, export the compressed picture back.
+ // In-loop filtering is not applied.
+ int preprocessing; // preprocessing filter:
+ // 0=none, 1=segment-smooth, 2=pseudo-random dithering
+ int partitions; // log2(number of token partitions) in [0..3]. Default
+ // is set to 0 for easier progressive decoding.
+ int partition_limit; // quality degradation allowed to fit the 512k limit
+ // on prediction modes coding (0: no degradation,
+ // 100: maximum possible degradation).
+ int emulate_jpeg_size; // If true, compression parameters will be remapped
+ // to better match the expected output size from
+ // JPEG compression. Generally, the output size will
+ // be similar but the degradation will be lower.
+ int thread_level; // If non-zero, try and use multi-threaded encoding.
+ int low_memory; // If set, reduce memory usage (but increase CPU use).
+
+ uint32_t pad[5]; // padding for later use
+};
+
+// Enumerate some predefined settings for WebPConfig, depending on the type
+// of source picture. These presets are used when calling WebPConfigPreset().
+typedef enum WebPPreset {
+ WEBP_PRESET_DEFAULT = 0, // default preset.
+ WEBP_PRESET_PICTURE, // digital picture, like portrait, inner shot
+ WEBP_PRESET_PHOTO, // outdoor photograph, with natural lighting
+ WEBP_PRESET_DRAWING, // hand or line drawing, with high-contrast details
+ WEBP_PRESET_ICON, // small-sized colorful images
+ WEBP_PRESET_TEXT // text-like
+} WebPPreset;
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(int) WebPConfigInitInternal(WebPConfig*, WebPPreset, float, int);
+
+// Should always be called, to initialize a fresh WebPConfig structure before
+// modification. Returns false in case of version mismatch. WebPConfigInit()
+// must have succeeded before using the 'config' object.
+// Note that the default values are lossless=0 and quality=75.
+static WEBP_INLINE int WebPConfigInit(WebPConfig* config) {
+ return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f,
+ WEBP_ENCODER_ABI_VERSION);
+}
+
+// This function will initialize the configuration according to a predefined
+// set of parameters (referred to by 'preset') and a given quality factor.
+// This function can be called as a replacement to WebPConfigInit(). Will
+// return false in case of error.
+static WEBP_INLINE int WebPConfigPreset(WebPConfig* config,
+ WebPPreset preset, float quality) {
+ return WebPConfigInitInternal(config, preset, quality,
+ WEBP_ENCODER_ABI_VERSION);
+}
+
+#if WEBP_ENCODER_ABI_VERSION > 0x0202
+// Activate the lossless compression mode with the desired efficiency level
+// between 0 (fastest, lowest compression) and 9 (slower, best compression).
+// A good default level is '6', providing a fair tradeoff between compression
+// speed and final compressed size.
+// This function will overwrite several fields from config: 'method', 'quality'
+// and 'lossless'. Returns false in case of parameter error.
+WEBP_EXTERN(int) WebPConfigLosslessPreset(WebPConfig* config, int level);
+#endif
+
+// Returns true if 'config' is non-NULL and all configuration parameters are
+// within their valid ranges.
+WEBP_EXTERN(int) WebPValidateConfig(const WebPConfig* config);
+
+//------------------------------------------------------------------------------
+// Input / Output
+// Structure for storing auxiliary statistics (mostly for lossy encoding).
+
+struct WebPAuxStats {
+ int coded_size; // final size
+
+ float PSNR[5]; // peak-signal-to-noise ratio for Y/U/V/All/Alpha
+ int block_count[3]; // number of intra4/intra16/skipped macroblocks
+ int header_bytes[2]; // approximate number of bytes spent for header
+ // and mode-partition #0
+ int residual_bytes[3][4]; // approximate number of bytes spent for
+ // DC/AC/uv coefficients for each (0..3) segments.
+ int segment_size[4]; // number of macroblocks in each segments
+ int segment_quant[4]; // quantizer values for each segments
+ int segment_level[4]; // filtering strength for each segments [0..63]
+
+ int alpha_data_size; // size of the transparency data
+ int layer_data_size; // size of the enhancement layer data
+
+ // lossless encoder statistics
+ uint32_t lossless_features; // bit0:predictor bit1:cross-color transform
+ // bit2:subtract-green bit3:color indexing
+ int histogram_bits; // number of precision bits of histogram
+ int transform_bits; // precision bits for transform
+ int cache_bits; // number of bits for color cache lookup
+ int palette_size; // number of color in palette, if used
+ int lossless_size; // final lossless size
+
+ uint32_t pad[4]; // padding for later use
+};
+
+// Signature for output function. Should return true if writing was successful.
+// data/data_size is the segment of data to write, and 'picture' is for
+// reference (and so one can make use of picture->custom_ptr).
+typedef int (*WebPWriterFunction)(const uint8_t* data, size_t data_size,
+ const WebPPicture* picture);
+
+// WebPMemoryWrite: a special WebPWriterFunction that writes to memory using
+// the following WebPMemoryWriter object (to be set as a custom_ptr).
+struct WebPMemoryWriter {
+ uint8_t* mem; // final buffer (of size 'max_size', larger than 'size').
+ size_t size; // final size
+ size_t max_size; // total capacity
+ uint32_t pad[1]; // padding for later use
+};
+
+// The following must be called first before any use.
+WEBP_EXTERN(void) WebPMemoryWriterInit(WebPMemoryWriter* writer);
+
+#if WEBP_ENCODER_ABI_VERSION > 0x0203
+// The following must be called to deallocate writer->mem memory. The 'writer'
+// object itself is not deallocated.
+WEBP_EXTERN(void) WebPMemoryWriterClear(WebPMemoryWriter* writer);
+#endif
+// The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon
+// completion, writer.mem and writer.size will hold the coded data.
+#if WEBP_ENCODER_ABI_VERSION > 0x0203
+// writer.mem must be freed by calling WebPMemoryWriterClear.
+#else
+// writer.mem must be freed by calling 'free(writer.mem)'.
+#endif
+WEBP_EXTERN(int) WebPMemoryWrite(const uint8_t* data, size_t data_size,
+ const WebPPicture* picture);
+
+// Progress hook, called from time to time to report progress. It can return
+// false to request an abort of the encoding process, or true otherwise if
+// everything is OK.
+typedef int (*WebPProgressHook)(int percent, const WebPPicture* picture);
+
+// Color spaces.
+typedef enum WebPEncCSP {
+ // chroma sampling
+ WEBP_YUV420 = 0, // 4:2:0
+ WEBP_YUV420A = 4, // alpha channel variant
+ WEBP_CSP_UV_MASK = 3, // bit-mask to get the UV sampling factors
+ WEBP_CSP_ALPHA_BIT = 4 // bit that is set if alpha is present
+} WebPEncCSP;
+
+// Encoding error conditions.
+typedef enum WebPEncodingError {
+ VP8_ENC_OK = 0,
+ VP8_ENC_ERROR_OUT_OF_MEMORY, // memory error allocating objects
+ VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY, // memory error while flushing bits
+ VP8_ENC_ERROR_NULL_PARAMETER, // a pointer parameter is NULL
+ VP8_ENC_ERROR_INVALID_CONFIGURATION, // configuration is invalid
+ VP8_ENC_ERROR_BAD_DIMENSION, // picture has invalid width/height
+ VP8_ENC_ERROR_PARTITION0_OVERFLOW, // partition is bigger than 512k
+ VP8_ENC_ERROR_PARTITION_OVERFLOW, // partition is bigger than 16M
+ VP8_ENC_ERROR_BAD_WRITE, // error while flushing bytes
+ VP8_ENC_ERROR_FILE_TOO_BIG, // file is bigger than 4G
+ VP8_ENC_ERROR_USER_ABORT, // abort request by user
+ VP8_ENC_ERROR_LAST // list terminator. always last.
+} WebPEncodingError;
+
+// maximum width/height allowed (inclusive), in pixels
+#define WEBP_MAX_DIMENSION 16383
+
+// Main exchange structure (input samples, output bytes, statistics)
+struct WebPPicture {
+ // INPUT
+ //////////////
+ // Main flag for encoder selecting between ARGB or YUV input.
+ // It is recommended to use ARGB input (*argb, argb_stride) for lossless
+ // compression, and YUV input (*y, *u, *v, etc.) for lossy compression
+ // since these are the respective native colorspace for these formats.
+ int use_argb;
+
+ // YUV input (mostly used for input to lossy compression)
+ WebPEncCSP colorspace; // colorspace: should be YUV420 for now (=Y'CbCr).
+ int width, height; // dimensions (less or equal to WEBP_MAX_DIMENSION)
+ uint8_t *y, *u, *v; // pointers to luma/chroma planes.
+ int y_stride, uv_stride; // luma/chroma strides.
+ uint8_t* a; // pointer to the alpha plane
+ int a_stride; // stride of the alpha plane
+ uint32_t pad1[2]; // padding for later use
+
+ // ARGB input (mostly used for input to lossless compression)
+ uint32_t* argb; // Pointer to argb (32 bit) plane.
+ int argb_stride; // This is stride in pixels units, not bytes.
+ uint32_t pad2[3]; // padding for later use
+
+ // OUTPUT
+ ///////////////
+ // Byte-emission hook, to store compressed bytes as they are ready.
+ WebPWriterFunction writer; // can be NULL
+ void* custom_ptr; // can be used by the writer.
+
+ // map for extra information (only for lossy compression mode)
+ int extra_info_type; // 1: intra type, 2: segment, 3: quant
+ // 4: intra-16 prediction mode,
+ // 5: chroma prediction mode,
+ // 6: bit cost, 7: distortion
+ uint8_t* extra_info; // if not NULL, points to an array of size
+ // ((width + 15) / 16) * ((height + 15) / 16) that
+ // will be filled with a macroblock map, depending
+ // on extra_info_type.
+
+ // STATS AND REPORTS
+ ///////////////////////////
+ // Pointer to side statistics (updated only if not NULL)
+ WebPAuxStats* stats;
+
+ // Error code for the latest error encountered during encoding
+ WebPEncodingError error_code;
+
+ // If not NULL, report progress during encoding.
+ WebPProgressHook progress_hook;
+
+ void* user_data; // this field is free to be set to any value and
+ // used during callbacks (like progress-report e.g.).
+
+ uint32_t pad3[3]; // padding for later use
+
+ // Unused for now
+ uint8_t *pad4, *pad5;
+ uint32_t pad6[8]; // padding for later use
+
+ // PRIVATE FIELDS
+ ////////////////////
+ void* memory_; // row chunk of memory for yuva planes
+ void* memory_argb_; // and for argb too.
+ void* pad7[2]; // padding for later use
+};
+
+// Internal, version-checked, entry point
+WEBP_EXTERN(int) WebPPictureInitInternal(WebPPicture*, int);
+
+// Should always be called, to initialize the structure. Returns false in case
+// of version mismatch. WebPPictureInit() must have succeeded before using the
+// 'picture' object.
+// Note that, by default, use_argb is false and colorspace is WEBP_YUV420.
+static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) {
+ return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION);
+}
+
+//------------------------------------------------------------------------------
+// WebPPicture utils
+
+// Convenience allocation / deallocation based on picture->width/height:
+// Allocate y/u/v buffers as per colorspace/width/height specification.
+// Note! This function will free the previous buffer if needed.
+// Returns false in case of memory error.
+WEBP_EXTERN(int) WebPPictureAlloc(WebPPicture* picture);
+
+// Release the memory allocated by WebPPictureAlloc() or WebPPictureImport*().
+// Note that this function does _not_ free the memory used by the 'picture'
+// object itself.
+// Besides memory (which is reclaimed) all other fields of 'picture' are
+// preserved.
+WEBP_EXTERN(void) WebPPictureFree(WebPPicture* picture);
+
+// Copy the pixels of *src into *dst, using WebPPictureAlloc. Upon return, *dst
+// will fully own the copied pixels (this is not a view). The 'dst' picture need
+// not be initialized as its content is overwritten.
+// Returns false in case of memory allocation error.
+WEBP_EXTERN(int) WebPPictureCopy(const WebPPicture* src, WebPPicture* dst);
+
+// Compute PSNR, SSIM or LSIM distortion metric between two pictures.
+// Result is in dB, stores in result[] in the Y/U/V/Alpha/All order.
+// Returns false in case of error (src and ref don't have same dimension, ...)
+// Warning: this function is rather CPU-intensive.
+WEBP_EXTERN(int) WebPPictureDistortion(
+ const WebPPicture* src, const WebPPicture* ref,
+ int metric_type, // 0 = PSNR, 1 = SSIM, 2 = LSIM
+ float result[5]);
+
+// self-crops a picture to the rectangle defined by top/left/width/height.
+// Returns false in case of memory allocation error, or if the rectangle is
+// outside of the source picture.
+// The rectangle for the view is defined by the top-left corner pixel
+// coordinates (left, top) as well as its width and height. This rectangle
+// must be fully be comprised inside the 'src' source picture. If the source
+// picture uses the YUV420 colorspace, the top and left coordinates will be
+// snapped to even values.
+WEBP_EXTERN(int) WebPPictureCrop(WebPPicture* picture,
+ int left, int top, int width, int height);
+
+// Extracts a view from 'src' picture into 'dst'. The rectangle for the view
+// is defined by the top-left corner pixel coordinates (left, top) as well
+// as its width and height. This rectangle must be fully be comprised inside
+// the 'src' source picture. If the source picture uses the YUV420 colorspace,
+// the top and left coordinates will be snapped to even values.
+// Picture 'src' must out-live 'dst' picture. Self-extraction of view is allowed
+// ('src' equal to 'dst') as a mean of fast-cropping (but note that doing so,
+// the original dimension will be lost). Picture 'dst' need not be initialized
+// with WebPPictureInit() if it is different from 'src', since its content will
+// be overwritten.
+// Returns false in case of memory allocation error or invalid parameters.
+WEBP_EXTERN(int) WebPPictureView(const WebPPicture* src,
+ int left, int top, int width, int height,
+ WebPPicture* dst);
+
+// Returns true if the 'picture' is actually a view and therefore does
+// not own the memory for pixels.
+WEBP_EXTERN(int) WebPPictureIsView(const WebPPicture* picture);
+
+// Rescale a picture to new dimension width x height.
+// If either 'width' or 'height' (but not both) is 0 the corresponding
+// dimension will be calculated preserving the aspect ratio.
+// No gamma correction is applied.
+// Returns false in case of error (invalid parameter or insufficient memory).
+WEBP_EXTERN(int) WebPPictureRescale(WebPPicture* pic, int width, int height);
+
+// Colorspace conversion function to import RGB samples.
+// Previous buffer will be free'd, if any.
+// *rgb buffer should have a size of at least height * rgb_stride.
+// Returns false in case of memory error.
+WEBP_EXTERN(int) WebPPictureImportRGB(
+ WebPPicture* picture, const uint8_t* rgb, int rgb_stride);
+// Same, but for RGBA buffer.
+WEBP_EXTERN(int) WebPPictureImportRGBA(
+ WebPPicture* picture, const uint8_t* rgba, int rgba_stride);
+// Same, but for RGBA buffer. Imports the RGB direct from the 32-bit format
+// input buffer ignoring the alpha channel. Avoids needing to copy the data
+// to a temporary 24-bit RGB buffer to import the RGB only.
+WEBP_EXTERN(int) WebPPictureImportRGBX(
+ WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride);
+
+// Variants of the above, but taking BGR(A|X) input.
+WEBP_EXTERN(int) WebPPictureImportBGR(
+ WebPPicture* picture, const uint8_t* bgr, int bgr_stride);
+WEBP_EXTERN(int) WebPPictureImportBGRA(
+ WebPPicture* picture, const uint8_t* bgra, int bgra_stride);
+WEBP_EXTERN(int) WebPPictureImportBGRX(
+ WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride);
+
+// Converts picture->argb data to the YUV420A format. The 'colorspace'
+// parameter is deprecated and should be equal to WEBP_YUV420.
+// Upon return, picture->use_argb is set to false. The presence of real
+// non-opaque transparent values is detected, and 'colorspace' will be
+// adjusted accordingly. Note that this method is lossy.
+// Returns false in case of error.
+WEBP_EXTERN(int) WebPPictureARGBToYUVA(WebPPicture* picture,
+ WebPEncCSP /*colorspace = WEBP_YUV420*/);
+
+// Same as WebPPictureARGBToYUVA(), but the conversion is done using
+// pseudo-random dithering with a strength 'dithering' between
+// 0.0 (no dithering) and 1.0 (maximum dithering). This is useful
+// for photographic picture.
+WEBP_EXTERN(int) WebPPictureARGBToYUVADithered(
+ WebPPicture* picture, WebPEncCSP colorspace, float dithering);
+
+#if WEBP_ENCODER_ABI_VERSION > 0x0204
+// Performs 'smart' RGBA->YUVA420 downsampling and colorspace conversion.
+// Downsampling is handled with extra care in case of color clipping. This
+// method is roughly 2x slower than WebPPictureARGBToYUVA() but produces better
+// YUV representation.
+// Returns false in case of error.
+WEBP_EXTERN(int) WebPPictureSmartARGBToYUVA(WebPPicture* picture);
+#endif
+
+// Converts picture->yuv to picture->argb and sets picture->use_argb to true.
+// The input format must be YUV_420 or YUV_420A.
+// Note that the use of this method is discouraged if one has access to the
+// raw ARGB samples, since using YUV420 is comparatively lossy. Also, the
+// conversion from YUV420 to ARGB incurs a small loss too.
+// Returns false in case of error.
+WEBP_EXTERN(int) WebPPictureYUVAToARGB(WebPPicture* picture);
+
+// Helper function: given a width x height plane of RGBA or YUV(A) samples
+// clean-up the YUV or RGB samples under fully transparent area, to help
+// compressibility (no guarantee, though).
+WEBP_EXTERN(void) WebPCleanupTransparentArea(WebPPicture* picture);
+
+// Scan the picture 'picture' for the presence of non fully opaque alpha values.
+// Returns true in such case. Otherwise returns false (indicating that the
+// alpha plane can be ignored altogether e.g.).
+WEBP_EXTERN(int) WebPPictureHasTransparency(const WebPPicture* picture);
+
+// Remove the transparency information (if present) by blending the color with
+// the background color 'background_rgb' (specified as 24bit RGB triplet).
+// After this call, all alpha values are reset to 0xff.
+WEBP_EXTERN(void) WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb);
+
+//------------------------------------------------------------------------------
+// Main call
+
+// Main encoding call, after config and picture have been initialized.
+// 'picture' must be less than 16384x16384 in dimension (cf WEBP_MAX_DIMENSION),
+// and the 'config' object must be a valid one.
+// Returns false in case of error, true otherwise.
+// In case of error, picture->error_code is updated accordingly.
+// 'picture' can hold the source samples in both YUV(A) or ARGB input, depending
+// on the value of 'picture->use_argb'. It is highly recommended to use
+// the former for lossy encoding, and the latter for lossless encoding
+// (when config.lossless is true). Automatic conversion from one format to
+// another is provided but they both incur some loss.
+WEBP_EXTERN(int) WebPEncode(const WebPConfig* config, WebPPicture* picture);
+
+//------------------------------------------------------------------------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_WEBP_ENCODE_H_ */
diff --git a/src/webp/format_constants.h b/src/webp/format_constants.h
new file mode 100644
index 00000000..4c04b50c
--- /dev/null
+++ b/src/webp/format_constants.h
@@ -0,0 +1,88 @@
+// Copyright 2012 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.
+// -----------------------------------------------------------------------------
+//
+// Internal header for constants related to WebP file format.
+//
+// Author: Urvang (urvang@google.com)
+
+#ifndef WEBP_WEBP_FORMAT_CONSTANTS_H_
+#define WEBP_WEBP_FORMAT_CONSTANTS_H_
+
+// Create fourcc of the chunk from the chunk tag characters.
+#define MKFOURCC(a, b, c, d) ((uint32_t)(a) | (b) << 8 | (c) << 16 | (d) << 24)
+
+// VP8 related constants.
+#define VP8_SIGNATURE 0x9d012a // Signature in VP8 data.
+#define VP8_MAX_PARTITION0_SIZE (1 << 19) // max size of mode partition
+#define VP8_MAX_PARTITION_SIZE (1 << 24) // max size for token partition
+#define VP8_FRAME_HEADER_SIZE 10 // Size of the frame header within VP8 data.
+
+// VP8L related constants.
+#define VP8L_SIGNATURE_SIZE 1 // VP8L signature size.
+#define VP8L_MAGIC_BYTE 0x2f // VP8L signature byte.
+#define VP8L_IMAGE_SIZE_BITS 14 // Number of bits used to store
+ // width and height.
+#define VP8L_VERSION_BITS 3 // 3 bits reserved for version.
+#define VP8L_VERSION 0 // version 0
+#define VP8L_FRAME_HEADER_SIZE 5 // Size of the VP8L frame header.
+
+#define MAX_PALETTE_SIZE 256
+#define MAX_CACHE_BITS 11
+#define HUFFMAN_CODES_PER_META_CODE 5
+#define ARGB_BLACK 0xff000000
+
+#define DEFAULT_CODE_LENGTH 8
+#define MAX_ALLOWED_CODE_LENGTH 15
+
+#define NUM_LITERAL_CODES 256
+#define NUM_LENGTH_CODES 24
+#define NUM_DISTANCE_CODES 40
+#define CODE_LENGTH_CODES 19
+
+#define MIN_HUFFMAN_BITS 2 // min number of Huffman bits
+#define MAX_HUFFMAN_BITS 9 // max number of Huffman bits
+
+#define TRANSFORM_PRESENT 1 // The bit to be written when next data
+ // to be read is a transform.
+#define NUM_TRANSFORMS 4 // Maximum number of allowed transform
+ // in a bitstream.
+typedef enum {
+ PREDICTOR_TRANSFORM = 0,
+ CROSS_COLOR_TRANSFORM = 1,
+ SUBTRACT_GREEN = 2,
+ COLOR_INDEXING_TRANSFORM = 3
+} VP8LImageTransformType;
+
+// Alpha related constants.
+#define ALPHA_HEADER_LEN 1
+#define ALPHA_NO_COMPRESSION 0
+#define ALPHA_LOSSLESS_COMPRESSION 1
+#define ALPHA_PREPROCESSED_LEVELS 1
+
+// Mux related constants.
+#define TAG_SIZE 4 // Size of a chunk tag (e.g. "VP8L").
+#define CHUNK_SIZE_BYTES 4 // Size needed to store chunk's size.
+#define CHUNK_HEADER_SIZE 8 // Size of a chunk header.
+#define RIFF_HEADER_SIZE 12 // Size of the RIFF header ("RIFFnnnnWEBP").
+#define ANMF_CHUNK_SIZE 16 // Size of an ANMF chunk.
+#define ANIM_CHUNK_SIZE 6 // Size of an ANIM chunk.
+#define FRGM_CHUNK_SIZE 6 // Size of a FRGM chunk.
+#define VP8X_CHUNK_SIZE 10 // Size of a VP8X chunk.
+
+#define MAX_CANVAS_SIZE (1 << 24) // 24-bit max for VP8X width/height.
+#define MAX_IMAGE_AREA (1ULL << 32) // 32-bit max for width x height.
+#define MAX_LOOP_COUNT (1 << 16) // maximum value for loop-count
+#define MAX_DURATION (1 << 24) // maximum duration
+#define MAX_POSITION_OFFSET (1 << 24) // maximum frame/fragment x/y offset
+
+// Maximum chunk payload is such that adding the header and padding won't
+// overflow a uint32_t.
+#define MAX_CHUNK_PAYLOAD (~0U - CHUNK_HEADER_SIZE - 1)
+
+#endif /* WEBP_WEBP_FORMAT_CONSTANTS_H_ */
diff --git a/src/webp/mux_types.h b/src/webp/mux_types.h
new file mode 100644
index 00000000..c94043a3
--- /dev/null
+++ b/src/webp/mux_types.h
@@ -0,0 +1,97 @@
+// Copyright 2012 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.
+// -----------------------------------------------------------------------------
+//
+// Data-types common to the mux and demux libraries.
+//
+// Author: Urvang (urvang@google.com)
+
+#ifndef WEBP_WEBP_MUX_TYPES_H_
+#define WEBP_WEBP_MUX_TYPES_H_
+
+#include <stdlib.h> // free()
+#include <string.h> // memset()
+#include "./types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Note: forward declaring enumerations is not allowed in (strict) C and C++,
+// the types are left here for reference.
+// typedef enum WebPFeatureFlags WebPFeatureFlags;
+// typedef enum WebPMuxAnimDispose WebPMuxAnimDispose;
+// typedef enum WebPMuxAnimBlend WebPMuxAnimBlend;
+typedef struct WebPData WebPData;
+
+// VP8X Feature Flags.
+typedef enum WebPFeatureFlags {
+ FRAGMENTS_FLAG = 0x00000001,
+ ANIMATION_FLAG = 0x00000002,
+ XMP_FLAG = 0x00000004,
+ EXIF_FLAG = 0x00000008,
+ ALPHA_FLAG = 0x00000010,
+ ICCP_FLAG = 0x00000020
+} WebPFeatureFlags;
+
+// Dispose method (animation only). Indicates how the area used by the current
+// frame is to be treated before rendering the next frame on the canvas.
+typedef enum WebPMuxAnimDispose {
+ WEBP_MUX_DISPOSE_NONE, // Do not dispose.
+ WEBP_MUX_DISPOSE_BACKGROUND // Dispose to background color.
+} WebPMuxAnimDispose;
+
+// Blend operation (animation only). Indicates how transparent pixels of the
+// current frame are blended with those of the previous canvas.
+typedef enum WebPMuxAnimBlend {
+ WEBP_MUX_BLEND, // Blend.
+ WEBP_MUX_NO_BLEND // Do not blend.
+} WebPMuxAnimBlend;
+
+// Data type used to describe 'raw' data, e.g., chunk data
+// (ICC profile, metadata) and WebP compressed image data.
+struct WebPData {
+ const uint8_t* bytes;
+ size_t size;
+};
+
+// Initializes the contents of the 'webp_data' object with default values.
+static WEBP_INLINE void WebPDataInit(WebPData* webp_data) {
+ if (webp_data != NULL) {
+ memset(webp_data, 0, sizeof(*webp_data));
+ }
+}
+
+// Clears the contents of the 'webp_data' object by calling free(). Does not
+// deallocate the object itself.
+static WEBP_INLINE void WebPDataClear(WebPData* webp_data) {
+ if (webp_data != NULL) {
+ free((void*)webp_data->bytes);
+ WebPDataInit(webp_data);
+ }
+}
+
+// Allocates necessary storage for 'dst' and copies the contents of 'src'.
+// Returns true on success.
+static WEBP_INLINE int WebPDataCopy(const WebPData* src, WebPData* dst) {
+ if (src == NULL || dst == NULL) return 0;
+ WebPDataInit(dst);
+ if (src->bytes != NULL && src->size != 0) {
+ dst->bytes = (uint8_t*)malloc(src->size);
+ if (dst->bytes == NULL) return 0;
+ memcpy((void*)dst->bytes, src->bytes, src->size);
+ dst->size = src->size;
+ }
+ return 1;
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* WEBP_WEBP_MUX_TYPES_H_ */
diff --git a/src/webp/types.h b/src/webp/types.h
new file mode 100644
index 00000000..9b036e0c
--- /dev/null
+++ b/src/webp/types.h
@@ -0,0 +1,48 @@
+// Copyright 2010 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.
+// -----------------------------------------------------------------------------
+//
+// Common types
+//
+// Author: Skal (pascal.massimino@gmail.com)
+
+#ifndef WEBP_WEBP_TYPES_H_
+#define WEBP_WEBP_TYPES_H_
+
+#include <stddef.h> // for size_t
+
+#ifndef _MSC_VER
+#include <inttypes.h>
+#if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \
+ (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
+#define WEBP_INLINE inline
+#else
+#define WEBP_INLINE
+#endif
+#else
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed short int16_t;
+typedef unsigned short uint16_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long int uint64_t;
+typedef long long int int64_t;
+#define WEBP_INLINE __forceinline
+#endif /* _MSC_VER */
+
+#ifndef WEBP_EXTERN
+// This explicitly marks library functions and allows for changing the
+// signature for e.g., Windows DLL builds.
+#define WEBP_EXTERN(type) extern type
+#endif /* WEBP_EXTERN */
+
+// Macro to check ABI compatibility (same major revision number)
+#define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8))
+
+#endif /* WEBP_WEBP_TYPES_H_ */