libnsgif-0.0.1/0000755000175000017500000000000011174063166013562 5ustar dsilversdsilverslibnsgif-0.0.1/build/0000755000175000017500000000000011174063167014662 5ustar dsilversdsilverslibnsgif-0.0.1/build/makefiles/0000755000175000017500000000000011174063170016614 5ustar dsilversdsilverslibnsgif-0.0.1/build/makefiles/Makefile.subdir0000644000175000017500000000741711165262413021555 0ustar dsilversdsilvers# Child makefile fragment # # Inputs (reset on exit) # # DIR_SOURCES List of source files in this directory # DIR_TEST_ITEMS List of test items in this directory # DIR_INSTALL_ITEMS Items to install in form :; # # Toolchain is provided by top-level makefile # # Variables provided by top-level makefile # # BUILDDIR The location of the build tree root # COMPONENT The name of the component # CURDIR The location of the source tree root # EXPORTDIR The location of the export directory # WANT_TEST Whether to build testcases # # do_include Canned command sequence to include a child makefile # # Variables provided by parent makefile: # # DIR The name of the directory we're in, relative to CURDIR # # Variables we can manipulate: # # CLEAN_ITEMS The list of items to remove for "make clean" # DISTCLEAN_ITEMS The list of items to remove for "make distclean" # TEST_ITEMS The list of items to build for "make test" # TEST_TARGETS The list of target names to run for "make test" # INSTALL_ITEMS The list of items to (un)install # # SOURCES The list of sources to build for $(COMPONENT) # # Plus anything from the toolchain # Push parent directory onto the directory stack sp := $(sp).x dirstack_$(sp) := $(d) d := $(DIR) # Sources SRCS_$(d) := $(DIR_SOURCES) TEST_ITEMS_$(d) := INSTALL_ITEMS_$(d) := # Append to sources for component SOURCES := $(SOURCES) $(addprefix $(d), $(SRCS_$(d))) # Test sources ifeq ($(WANT_TEST),yes) ifneq ($(DIR_TEST_ITEMS),) # Extract the binary name from the ITEM binary = $(subst /,_,$(addprefix $(d),$(firstword $(subst :, ,$(ITEM))))) # Extract the list of sources from the ITEM sources = $(subst ;, ,$(lastword $(subst :, ,$(ITEM)))) # We can't simply use the output of foreach here, # as it space separates its output, which kinda defeats the point. define append_test_src TEST_ITEMS_$(d) := $$(TEST_ITEMS_$(d))$1; endef define append_test TEST_ITEMS_$(d) := $$(TEST_ITEMS_$(d)) $1: $$(eval $$(foreach TSRC,$2, \ $$(call append_test_src,$$(addprefix $$(d),$$(TSRC))))) endef # Append test items, prepending $(d) to each source file $(eval $(foreach ITEM,$(DIR_TEST_ITEMS), \ $(call append_test,$(binary),$(sources)))) TEST_ITEMS := $(TEST_ITEMS) $(TEST_ITEMS_$(d)) TEST_TARGETS := $(TEST_TARGETS) test_$(d) # Extract the binary name from the TEST binary_name = $(firstword $(subst :, ,$(TEST))) # Target for tests in this directory test_$(d): $(d) $(addprefix $(BUILDDIR)/, \ $(foreach TEST,$(TEST_ITEMS_$(d)),$(binary_name))) $(Q)$(SHAREDLDPATH) $(TESTRUNNER) $(BUILDDIR) \ $(CURDIR)/$< $(subst /,_,$<) $(EXEEXT) endif endif # Install items ifneq ($(DIR_INSTALL_ITEMS),) # Extract the destination directory from the variable dest_dir = $(firstword $(subst :, ,$(ITEM))) # Extract the list of files to install files = $(subst ;, ,$(lastword $(subst :, ,$(ITEM)))) define append_install_file INSTALL_ITEMS_$(d) := $$(INSTALL_ITEMS_$(d))$1; endef define append_install_item INSTALL_ITEMS_$(d) := $$(INSTALL_ITEMS_$(d)) $1: $$(eval $$(foreach FILE,$2, \ $$(call append_install_file,$$(addprefix $$(d),$$(FILE))))) endef # Append items to install (along with install location), prepending $(d) # to each item in the file list $(eval $(foreach ITEM,$(DIR_INSTALL_ITEMS), \ $(call append_install_item,$(dest_dir),$(files)))) INSTALL_ITEMS := $(INSTALL_ITEMS) $(INSTALL_ITEMS_$(d)) endif # Reset the inputs DIR_SOURCES := DIR_TEST_ITEMS := DIR_INSTALL_ITEMS := # Now include any children we may have MAKE_INCLUDES := $(wildcard $(d)*/Makefile) $(eval $(foreach INC, $(MAKE_INCLUDES), $(call do_include,$(INC)))) # Pop off the directory stack d := $(dirstack_$(sp)) sp := $(basename $(sp)) libnsgif-0.0.1/build/makefiles/Makefile.tools0000644000175000017500000001416511173431400021414 0ustar dsilversdsilvers# Tools Makefile fragment # # Expected inputs: # # COMPONENT_TYPE Type of component: # binary - Executable binary # lib-static - Static library # lib-shared - Shared library # riscos-module - RISC OS module # # Optional inputs: # # BUILD Type of build to perform: # release - Release build (default) # debug - Debug build # OPTCFLAGS Optional compiler flags for $(BUILD) # OPTLDFLAGS Optional linker flags for $(BUILD) # TARGET Target platform (defaults to host) # ############################################################################### # Sanity checks ############################################################################### ifeq ($(COMPONENT_TYPE),) $(error COMPONENT_TYPE not set) endif # Default build to release ifeq ($(BUILD),) BUILD := release endif ############################################################################### # Host/target platform detection ############################################################################### HOST := $(shell uname -s) ifeq ($(HOST),) # Don't ask HOST := riscos else ifeq ($(HOST),RISC OS) HOST := riscos endif ifeq ($(HOST),BeOS) HOST := beos endif ifeq ($(HOST),Haiku) HOST := haiku endif endif ifeq ($(TARGET),) # Default target to host. Please add exceptions as required. TARGET := $(HOST) ifeq ($(HOST),haiku) # This isn't necessarily correct -- they have differences. However, in the # general case, this will work. If there are differences that are actually # important wrt the target platform (as opposed to the build host) then # we'll just have to introduce a haiku target, too. TARGET := beos endif endif # Now setup our tooling ifeq ($(TARGET),riscos) ifeq ($(HOST),riscos) # Building on native RISC OS GCCSDK_INSTALL_ENV ?= CC := gcc CMHG := cmunge GENHTML := echo INSTALL := echo LCOV := echo PKGCONFIG := # This is nasty, but needed because $(CURDIR) will # contain colons, and thus confuse make mightily $(shell SetMacro Alias$$$(COMPONENT)pwd Set %0 :|$$CSD>|mUnset Alias$$$(COMPONENT)pwd) $(shell $(COMPONENT)pwd $(COMPONENT)$$Dir) CURDIR := <$(COMPONENT)$$Dir> else # Cross compiling for RISC OS GCCSDK_INSTALL_ENV ?= /home/riscos/env GCCSDK_INSTALL_CROSSBIN ?= /home/riscos/cross/bin AR := $(wildcard $(GCCSDK_INSTALL_CROSSBIN)/*ar) CC := $(wildcard $(GCCSDK_INSTALL_CROSSBIN)/*gcc) CMHG := PATH="$(GCCSDK_INSTALL_CROSSBIN):$(PATH)" $(GCCSDK_INSTALL_CROSSBIN)/cmunge GENHTML := echo HOST_CC := cc LCOV := echo PKGCONFIG := $(GCCSDK_INSTALL_ENV)/ro-pkg-config ifneq ($(COMPONENT_TYPE),riscos-module) ifneq ($(findstring arm-unknown-riscos-gcc,$(CC)),) EXEEXT := ,e1f else EXEEXT := ,ff8 endif else EXEEXT := ,ffa endif endif CFLAGS := $(CFLAGS) -mpoke-function-name -I$(GCCSDK_INSTALL_ENV)/include LDFLAGS := $(LDFLAGS) -L$(GCCSDK_INSTALL_ENV)/lib CMHGFLAGS := -p -tgcc -32bit -apcs 3/32/nonreent/fpe2/noswst/nofpr/nofp # Default prefix PREFIX ?= $(GCCSDK_INSTALL_ENV) endif # BeOS-like targets ifeq ($(TARGET),beos) ifeq ($(HOST),beos) # Building on BeOS CC := gcc # No pkg-config PKGCONFIG := GCCVER := 2 # Default prefix PREFIX ?= /boot/home/config else ifeq ($(HOST),haiku) # Building on Haiku GCCVER := 2 # Default prefix PREFIX ?= /boot/common else $(error Cross-compiling for BeOS is not supported) endif endif endif ############################################################################## # Tool defaults ############################################################################## CP ?= cp DOXYGEN ?= doxygen ECHO ?= echo GENHTML ?= genhtml HOST_CC ?= $(CC) INSTALL ?= install LCOV ?= lcov LN ?= ln MAKE ?= make MKDIR ?= mkdir MKDIRFLAGS ?= -p MV ?= mv PERL ?= perl PKGCONFIG ?= pkg-config SED ?= sed TOUCH ?= touch XSLTPROC ?= xsltproc ############################################################################### # Default compiler/linker/archiver flags ############################################################################### ifeq ($(BUILD),release) OPTCFLAGS ?= -DNDEBUG -O2 else OPTCFLAGS ?= -g -O0 OPTLDFLAGS ?= -g endif ifeq ($(origin ARFLAGS),default) ARFLAGS := cru endif CFLAGS := $(CFLAGS) $(OPTCFLAGS) LDFLAGS := $(LDFLAGS) $(OPTLDFLAGS) # Extensions for coverage target ifeq ($(MAKECMDGOALS),coverage) COVCFLAGS ?= -fprofile-arcs -ftest-coverage COVLDFLAGS ?= -lgcov CFLAGS := $(CFLAGS) $(COVCFLAGS) LDFLAGS := $(LDFLAGS) $(COVLDFLAGS) endif # Extensions for profile target ifeq ($(MAKECMDGOALS),profile) PROFCFLAGS ?= -pg PROFLDFLAGS ?= -pg CFLAGS := $(CFLAGS) $(PROFCFLAGS) LDFLAGS := $(LDFLAGS) $(PROFLDFLAGS) endif ############################################################################### # lib-shared defaults ############################################################################### # Default library extension ifeq ($(COMPONENT_TYPE),lib-static) LIBEXT ?= .a else LIBEXT ?= .so endif # If we're building a shared library, modify the flags appropriately ifeq ($(COMPONENT_TYPE),lib-shared) # Default CFLAGS/LDFLAGS for shared libraries SHAREDCFLAGS ?= -fPIC -DPIC SHAREDLDFLAGS ?= -shared \ -Wl,-soname,$(SONAME) SHAREDLDPATH ?= LD_LIBRARY_PATH="$(BUILDDIR):$(LD_LIBRARY_PATH)" endif ############################################################################### # RISC OS module extensions ############################################################################### ifeq ($(COMPONENT_TYPE),riscos-module) ifneq ($(TARGET),riscos) $(error Attempting to build a RISC OS module for a non-RISC OS target) endif CFLAGS := $(CFLAGS) -mmodule LDFLAGS := $(LDFLAGS) -mmodule endif ############################################################################### # Other settings ############################################################################### # If GCC can cope with simultaneous build & dep, do that as it's faster ifneq ($(GCCVER),2) CC_CAN_BUILD_AND_DEP ?= yes endif libnsgif-0.0.1/build/makefiles/Makefile.top0000644000175000017500000003376311173446165021101 0ustar dsilversdsilvers# Top-level Makefile fragment # # Expected inputs: # # BUILD Type of build to perform: # release - Release build # debug - Debug build # COMPONENT Name of the component (sans leading "lib" iff a library) # COMPONENT_VERSION Component version number (x.y.z) # COMPONENT_TYPE Type of component: # binary - Executable binary # lib-static - Static library # lib-shared - Shared library # riscos-module - RISC OS module # TARGET Target platform identifier # # Optional inputs: # # BUILDDIR Directory to build into (defaults to # build-$(HOST)-$(TARGET)-$(BUILD)-$(COMPONENT_TYPE)) # CC_CAN_BUILD_AND_DEP Flag whether $(CC) is capable of calculating dependency # information at the same time as compiling sources. # Set to "yes" if it can. # DESTDIR Sandboxed FS root (e.g. for packaging) # HOST Host platform identifier # PREFIX Absolute installation path prefix # (defaults to /usr/local) # REQUIRED_PKGS List of required pkg-config packages # # The client may also override all toolchain settings, including: # # ARFLAGS Archiver flags for the current compilation # CFLAGS C compiler flags for the current compilation # LDFLAGS Linker flags for the current compilation # # TESTCFLAGS Any test-specific CFLAGS # TESTLDFLAGS Any test-specific LDFLAGS # # TESTRUNNER Test runner invocation command # The test runner takes a command line in the form # # # Targets provided: # # all Default target. Builds component using current settings # test Build and run test suite, using current settings. # coverage Determine test suite coverage (requires lcov) # profile Build with profiling support enabled (requires gprof) # docs Produce documentation (requires doxygen) # clean Clean the build # distclean Remove distribution files, too # install Install component into prefix. # uninstall Remove component from prefix. # # Variables provided: # # major-version Extracts the major version (x) from COMPONENT_VERSION # minor-version Extracts the minor version (y) from COMPONENT_VERSION # patch-version Extracts the patch version (z) from COMPONENT_VERSION # OUTPUT Path + filename of build target ############################################################################### # Sanity checks ############################################################################### # Name of component must be defined by client ifeq ($(COMPONENT),) $(error COMPONENT not defined) endif # As must the version ifeq ($(COMPONENT_VERSION),) $(error COMPONENT_VERSION not defined) endif # As must the component type ifeq ($(COMPONENT_TYPE),) $(error COMPONENT_TYPE not defined) endif # Target platform must be defined by the client ifeq ($(TARGET),) $(error TARGET not defined) endif # Build type, too ifeq ($(BUILD),) $(error BUILD not defined) endif ############################################################################## # Makefile variables ############################################################################## Q ?= @ VQ ?= @ ############################################################################## # Exported variables (also OUTPUT, further down) ############################################################################## major-version := $(word 1,$(subst ., ,$(COMPONENT_VERSION))) minor-version := $(word 2,$(subst ., ,$(COMPONENT_VERSION))) patch-version := $(word 3,$(subst ., ,$(COMPONENT_VERSION))) ############################################################################## # Build environment ############################################################################## # Build directory BUILDDIR ?= build-$(HOST)-$(TARGET)-$(BUILD)-$(COMPONENT_TYPE) # Build tree subdirs COVERAGEDIR := $(BUILDDIR)/coverage DOCDIR := $(BUILDDIR)/docs # Default prefix PREFIX ?= /usr/local # Determine if we want to build testcases ifeq ($(MAKECMDGOALS),test) WANT_TEST := yes else ifeq ($(MAKECMDGOALS),profile) WANT_TEST := yes else ifeq ($(MAKECMDGOALS),coverage) WANT_TEST := yes else WANT_TEST := no endif # List of items to delete on clean CLEAN_ITEMS := # List of items to delete on distclean DISTCLEAN_ITEMS := # List of items to build for testing TEST_ITEMS := # List of targets to run for testing TEST_TARGETS := # List of items to (un)install INSTALL_ITEMS := # List of targets to run before building $(OBJECT) PRE_TARGETS := # List of targets to run after building $(OBJECT) POST_TARGETS := # Source files SOURCES := # Include configuration Makefile fragment -include Makefile.config # Set the default target (before including any children) __default: all # Include Makefile fragments in subdirectories define do_include DIR := $$(dir $(1)) include $(1) endef MAKE_INCLUDES := $(wildcard */Makefile) $(eval $(foreach INC, $(MAKE_INCLUDES), $(call do_include,$(INC)))) # Calculate objects to build OBJECTS := $(addprefix $(BUILDDIR)/,$(filter %.o, \ $(subst /,_,$(subst .c,.o,$(SOURCES))) \ $(subst /,_,$(subst .cmhg,.o,$(SOURCES))))) bin_for_test = $(addprefix $(BUILDDIR)/,$(firstword $(subst :, ,$(ITEM)))) TEST_BINARIES := $(foreach ITEM,$(TEST_ITEMS),$(bin_for_test)) # Determine the output filename ifeq ($(findstring lib,$(COMPONENT_TYPE)),lib) ifeq ($(findstring lib-shared,$(COMPONENT_TYPE)),lib-shared) SHAREDLIBNAME := lib$(COMPONENT)$(LIBEXT) SONAME := $(SHAREDLIBNAME).$(major-version) OUTPUT := $(BUILDDIR)/$(SHAREDLIBNAME).$(COMPONENT_VERSION) else OUTPUT := $(BUILDDIR)/lib$(COMPONENT)$(LIBEXT) endif else OUTPUT := $(BUILDDIR)/$(COMPONENT)$(EXEEXT) endif ############################################################################### # Build targets ############################################################################### .PHONY: all test coverage profile docs clean distclean install uninstall \ __default __precov __partial_clean __postshared ifeq ($(COMPONENT_TYPE),lib-shared) POST_TARGETS := __postshared $(POST_TARGETS) __postshared: $(Q)$(LN) $(LNFLAGS) -fs $(notdir $(OUTPUT)) $(BUILDDIR)/$(SONAME) $(Q)$(LN) $(LNFLAGS) -fs $(notdir $(OUTPUT)) $(BUILDDIR)/$(SHAREDLIBNAME) endif # Default target all: $(PRE_TARGETS) $(OUTPUT) $(POST_TARGETS) # Build and execute testsuite test: all $(TEST_BINARIES) $(TEST_TARGETS) $(VQ)$(ECHO) $(ECHOFLAGS) " TEST: Testing complete" # Compute coverage __precov: __partial_clean $(Q)$(LCOV) --directory . --zerocounters coverage: __precov test $(Q)$(LCOV) --directory $(BUILDDIR) --base-directory $(CURDIR) \ --capture --output-file $(COVERAGEDIR)/$(COMPONENT)_tmp.info $(Q)$(LCOV) --extract $(COVERAGEDIR)/$(COMPONENT)_tmp.info \ "$(CURDIR)/src*" -o $(COVERAGEDIR)/$(COMPONENT).info $(Q)$(RM) $(RMFLAGS) $(COVERAGEDIR)/$(COMPONENT)_tmp.info $(Q)$(GENHTML) -o $(COVERAGEDIR) --num-spaces 2 \ $(COVERAGEDIR)/$(COMPONENT).info # Build for profiling profile: __partial_clean test # Compile documentation docs: $(BUILDDIR)/stamp $(Q)$(DOXYGEN) build/Doxyfile # Clean build tree __partial_clean: -$(Q)$(RM) $(RMFLAGS) $(CLEAN_ITEMS) -$(Q)$(RM) $(RMFLAGS) gmon.out -$(Q)$(RM) $(RMFLAGS) $(wildcard $(BUILDDIR)/*.d) -$(Q)$(RM) $(RMFLAGS) $(wildcard $(BUILDDIR)/*.gcda) -$(Q)$(RM) $(RMFLAGS) $(wildcard $(BUILDDIR)/*.gcno) -$(Q)$(RM) $(RMFLAGS) $(wildcard $(BUILDDIR)/*.o) clean: __partial_clean -$(Q)$(RM) $(RMFLAGS) -r build/docs -$(Q)$(RM) $(RMFLAGS) -r $(BUILDDIR) # Remove auto-generated non-build-tree items distclean: clean -$(Q)$(RM) $(RMFLAGS) $(DISTCLEAN_ITEMS) # The installation target, and associated canned command sequences. # For reference, the syntax of INSTALL_ITEMS is: # # :[';']* # # We also permit a trailing ';' in the file list. __comma := , __empty := __space := $(empty) $(empty) __required = $(subst $(__space),$(__comma) ,$(strip $(REQUIRED_PKGS))) # Install a pkg-config control file ($1) to the specified location ($2) define install_pkgconfig $(Q)$(SED) -e 's#PREFIX#$(PREFIX)#' $1 >$(BUILDDIR)/$(1:.in=) $(Q)$(SED) -i -e 's#MAJOR#$(major-version)#' $(BUILDDIR)/$(1:.in=) $(Q)$(SED) -i -e 's#MINOR#$(minor-version)#' $(BUILDDIR)/$(1:.in=) $(Q)$(SED) -i -e 's#PATCH#$(patch-version)#' $(BUILDDIR)/$(1:.in=) $(Q)$(SED) -i -e 's#VERSION#$(COMPONENT_VERSION)#' $(BUILDDIR)/$(1:.in=) $(if $(REQUIRED_PKGS), \ $(Q)$(SED) -i -e 's#REQUIRED#Requires: $(__required)#' \ $(BUILDDIR)/$(1:.in=), \ $(Q)$(SED) -i -e 's#REQUIRED##' $(BUILDDIR)/$(1:.in=)) $(INSTALL) $(INSTALLFLAGS) -m 644 $(BUILDDIR)/$(1:.in=) \ $2/$(1:.in=) endef # TODO: Is this scheme portable? define install_shared_lib $(INSTALL) $(INSTALLFLAGS) -m 755 $1 $2/$(notdir $1) $(LN) $(LNFLAGS) -fs $(notdir $1) $2/$(SONAME) $(LN) $(LNFLAGS) -fs $(notdir $1) $2/$(SHAREDLIBNAME) endef # Install a file ($1) to the specified location ($2) define install_file $(if $1, \ $(if $(findstring .pc.in,$1), \ $(call install_pkgconfig,$1,$2), \ $(if $(and $(filter lib-shared,$(COMPONENT_TYPE)), \ $(filter $(OUTPUT),$1)), \ $(call install_shared_lib,$1,$2), \ $(INSTALL) $(INSTALLFLAGS) -m 644 $1 $2))) endef # Install a list of files ($2) to the specified location ($1) # We create the installation location if it doesn't already exist define install_to_dest $(Q)$(MKDIR) $(MKDIRFLAGS) $(DESTDIR)$(PREFIX)$1 $(foreach FILE,$(strip $(subst ;, ,$2)), \ $(call install_file,$(FILE),$(DESTDIR)$(PREFIX)$1)) endef install: all $(foreach ITEM,$(INSTALL_ITEMS), \ $(call install_to_dest,$(firstword $(subst :, ,$(ITEM))), \ $(lastword $(subst :, ,$(ITEM))))) # Uninstallation # TODO: Work out how to safely remove symlinks define uninstall_shared_lib $(RM) $(RMFLAGS) $2/$(notdir $1).$(COMPONENT_VERSION) endef # Uninstall a file ($1) from the specified location ($2) define uninstall_file $(if $1, \ $(if $(findstring .pc.in,$1), \ $(RM) $(RMFLAGS) $2/$(1:.pc.in=)-$(major-version).pc, \ $(if $(and $(filter lib-shared,$(COMPONENT_TYPE)), \ $(filter $(OUTPUT),$1)), \ $(call uninstall_shared_lib,$1,$2), \ $(RM) $(RMFLAGS) $2/$(notdir $1)))) endef # Uninstall a list of files ($2) from the specified location ($1) # TODO: Come up with a safe way of removing directories, too define uninstall_from_dest $(foreach FILE,$(strip $(subst ;, ,$2)), \ $(call uninstall_file,$(FILE),$(DESTDIR)$(PREFIX)$1)) endef uninstall: $(foreach ITEM,$(INSTALL_ITEMS), \ $(call uninstall_from_dest,$(firstword $(subst :, ,$(ITEM))), \ $(lastword $(subst :, ,$(ITEM))))) ############################################################################### # Actual rules ############################################################################### $(BUILDDIR)/stamp: $(Q)$(MKDIR) $(MKDIRFLAGS) $(BUILDDIR) $(Q)$(MKDIR) $(MKDIRFLAGS) $(COVERAGEDIR) $(Q)$(MKDIR) $(MKDIRFLAGS) $(DOCDIR) $(Q)$(TOUCH) $(TOUCHFLAGS) $(BUILDDIR)/stamp $(OUTPUT): $(BUILDDIR)/stamp $(OBJECTS) ifeq ($(COMPONENT_TYPE),lib-static) $(VQ)$(ECHO) $(ECHOFLAGS) " AR: $@" $(Q)$(AR) $(ARFLAGS) $@ $(OBJECTS) else $(VQ)$(ECHO) $(ECHOFLAGS) " LINK: $@" $(Q)$(CC) -o $@ $(OBJECTS) $(LDFLAGS) $(SHAREDLDFLAGS) endif ############################################################################### # Autogenerated, implied rules ############################################################################### DEPFILES := BUILDFILES := ifeq ($(CC_CAN_BUILD_AND_DEP),yes) # C compiler can compile and dep simultaneously define dep_c ifeq ($$(findstring $$(BUILDDIR)/$2,$$(DEPFILES)),) $$(BUILDDIR)/$2: $$(BUILDDIR)/stamp $1 DEPFILES += $$(BUILDDIR)/$2 endif endef define build_c ifeq ($$(findstring $$(BUILDDIR)/$2,$$(BUILDFILES)),) $$(BUILDDIR)/$2: $$(BUILDDIR)/stamp $1 $$(VQ)$$(ECHO) $$(ECHOFLAGS) " COMPILE: $1" $$(Q)$$(CC) -MMD -MP $$($3) -o $$@ -c $1 BUILDFILES += $$(BUILDDIR)/$2 endif endef else # C compiler must calculate dependencies first, then compile (default) define dep_c ifeq ($$(findstring $$(BUILDDIR)/$2,$$(DEPFILES)),) $$(BUILDDIR)/$2: $$(BUILDDIR)/stamp $1 $$(VQ)$$(ECHO) $$(ECHOFLAGS) " DEP: $1" $$(Q)$$(RM) $$(RMFLAGS) $($@) $$(Q)$$(CC) $$($3) -MM $1 > $$@ $$(Q)$$(SED) $$(SEDFLAGS) -i 's,^.*:,$$@ $$(@:.d=.o):,' $$@ DEPFILES += $$(BUILDDIR)/$2 endif endef define build_c ifeq ($$(findstring $$(BUILDDIR)/$2,$$(BUILDFILES)),) $$(BUILDDIR)/$2: $$(BUILDDIR)/stamp $1 $$(VQ)$$(ECHO) $$(ECHOFLAGS) " COMPILE: $1" $$(Q)$$(CC) $$($3) -o $$@ -c $1 BUILDFILES += $$(BUILDDIR)/$2 endif endef endif define build_cmhg ifeq ($$(findstring $$(BUILDDIR)/$2,$$(BUILDFILES)),) $$(BUILDDIR)/$2: $$(BUILDDIR)/stamp $1 $$(VQ)$$(ECHO) $$(ECHOFLAGS) " CMHG: $1" $$(Q)$$(CMHG) $$(CMHGFLAGS) $1 -o $$@ BUILDFILES += $$(BUILDDIR)/$2 endif endef BUILDCFLAGS = $(CFLAGS) $(SHAREDCFLAGS) # Generate dependency rules $(eval $(foreach SOURCE,$(filter %.c,$(SOURCES)), \ $(call dep_c,$(SOURCE),$(subst /,_,$(SOURCE:.c=.d)),BUILDCFLAGS))) # Generate compilation rules $(eval $(foreach SOURCE,$(filter %.c,$(SOURCES)), \ $(call build_c,$(SOURCE),$(subst /,_,$(SOURCE:.c=.o)),BUILDCFLAGS))) $(eval $(foreach SOURCE,$(filter %.cmhg,$(SOURCES)), \ $(call build_cmhg,$(SOURCE),$(subst /,_,$(SOURCE:.cmhg=.o))))) # Similarly for test sources ifeq ($(WANT_TEST),yes) ifeq ($(findstring lib,$(COMPONENT_TYPE)),lib) TESTLIB := $(OUTPUT) TESTLDFLAGS += -L$(BUILDDIR)/ -l$(COMPONENT) endif TESTCFLAGS += $(CFLAGS) TESTLDFLAGS += $(LDFLAGS) define link_test $2: $($3) $1 $$(VQ)$$(ECHO) $$(ECHOFLAGS) " LINK: $2" $$(Q)$$(CC) -o $$@ $1 $$($4) endef srcs_for_test = $(subst ;, ,$(lastword $(subst :, ,$(ITEM)))) objs_for_test = $(addprefix $(BUILDDIR)/, \ $(subst /,_,$(addsuffix .o,$(basename $(srcs_for_test))))) $(eval $(foreach ITEM,$(TEST_ITEMS), \ $(foreach SOURCE,$(filter %.c,$(srcs_for_test)), \ $(call dep_c,$(SOURCE),$(subst /,_,$(SOURCE:.c=.d)),TESTCFLAGS)))) $(eval $(foreach ITEM,$(TEST_ITEMS), \ $(foreach SOURCE,$(filter %.c,$(srcs_for_test)), \ $(call build_c,$(SOURCE),$(subst /,_,$(SOURCE:.c=.o)),TESTCFLAGS)))) $(eval $(foreach ITEM,$(TEST_ITEMS), \ $(call link_test,$(objs_for_test),$(bin_for_test),TESTLIB,TESTLDFLAGS))) endif # Include dependency makefiles ifneq ($(findstring clean,$(MAKECMDGOALS)),clean) -include $(sort $(DEPFILES)) endif libnsgif-0.0.1/include/0000755000175000017500000000000011174063166015205 5ustar dsilversdsilverslibnsgif-0.0.1/include/libnsgif.h0000644000175000017500000001114611163550400017144 0ustar dsilversdsilvers/* * Copyright 2004 Richard Wilson * Copyright 2008 Sean Fox * * This file is part of NetSurf's libnsgif, http://www.netsurf-browser.org/ * Licenced under the MIT License, * http://www.opensource.org/licenses/mit-license.php */ /** \file * Progressive animated GIF file decoding (interface). */ #ifndef _LIBNSGIF_H_ #define _LIBNSGIF_H_ #include /* Error return values */ typedef enum { GIF_WORKING = 1, GIF_OK = 0, GIF_INSUFFICIENT_FRAME_DATA = -1, GIF_FRAME_DATA_ERROR = -2, GIF_INSUFFICIENT_DATA = -3, GIF_DATA_ERROR = -4, GIF_INSUFFICIENT_MEMORY = -5, GIF_FRAME_NO_DISPLAY = -6, GIF_END_OF_FRAME = -7 } gif_result; /* The GIF frame data */ typedef struct gif_frame { bool display; /**< whether the frame should be displayed/animated */ unsigned int frame_delay; /**< delay (in cs) before animating the frame */ /** Internal members are listed below */ unsigned int frame_pointer; /**< offset (in bytes) to the GIF frame data */ bool virgin; /**< whether the frame has previously been used */ bool opaque; /**< whether the frame is totally opaque */ bool redraw_required; /**< whether a forcable screen redraw is required */ unsigned char disposal_method; /**< how the previous frame should be disposed; affects plotting */ bool transparency; /**< whether we acknoledge transparency */ unsigned char transparency_index; /**< the index designating a transparent pixel */ unsigned int redraw_x; /**< x co-ordinate of redraw rectangle */ unsigned int redraw_y; /**< y co-ordinate of redraw rectangle */ unsigned int redraw_width; /**< width of redraw rectangle */ unsigned int redraw_height; /**< height of redraw rectangle */ } gif_frame; /* API for Bitmap callbacks */ typedef void* (*gif_bitmap_cb_create)(int width, int height); typedef void (*gif_bitmap_cb_destroy)(void *bitmap); typedef unsigned char* (*gif_bitmap_cb_get_buffer)(void *bitmap); typedef void (*gif_bitmap_cb_set_opaque)(void *bitmap, bool opaque); typedef bool (*gif_bitmap_cb_test_opaque)(void *bitmap); typedef void (*gif_bitmap_cb_modified)(void *bitmap); /* The Bitmap callbacks function table */ typedef struct gif_bitmap_callback_vt { gif_bitmap_cb_create bitmap_create; /**< Create a bitmap. */ gif_bitmap_cb_destroy bitmap_destroy; /**< Free a bitmap. */ gif_bitmap_cb_get_buffer bitmap_get_buffer; /**< Return a pointer to the pixel data in a bitmap. */ /** Members below are optional */ gif_bitmap_cb_set_opaque bitmap_set_opaque; /**< Sets whether a bitmap should be plotted opaque. */ gif_bitmap_cb_test_opaque bitmap_test_opaque; /**< Tests whether a bitmap has an opaque alpha channel. */ gif_bitmap_cb_modified bitmap_modified; /**< The bitmap image has changed, so flush any persistant cache. */ } gif_bitmap_callback_vt; /* The GIF animation data */ typedef struct gif_animation { gif_bitmap_callback_vt bitmap_callbacks; /**< callbacks for bitmap functions */ unsigned char *gif_data; /**< pointer to GIF data */ unsigned int width; /**< width of GIF (may increase during decoding) */ unsigned int height; /**< heigth of GIF (may increase during decoding) */ unsigned int frame_count; /**< number of frames decoded */ unsigned int frame_count_partial; /**< number of frames partially decoded */ gif_frame *frames; /**< decoded frames */ int decoded_frame; /**< current frame decoded to bitmap */ void *frame_image; /**< currently decoded image; stored as bitmap from bitmap_create callback */ int loop_count; /**< number of times to loop animation */ gif_result current_error; /**< current error type, or 0 for none*/ /** Internal members are listed below */ unsigned int buffer_position; /**< current index into GIF data */ unsigned int buffer_size; /**< total number of bytes of GIF data available */ unsigned int frame_holders; /**< current number of frame holders */ unsigned int background_index; /**< index in the colour table for the background colour */ unsigned int aspect_ratio; /**< image aspect ratio (ignored) */ unsigned int colour_table_size; /**< size of colour table (in entries) */ bool global_colours; /**< whether the GIF has a global colour table */ unsigned int *global_colour_table; /**< global colour table */ unsigned int *local_colour_table; /**< local colour table */ } gif_animation; void gif_create(gif_animation *gif, gif_bitmap_callback_vt *bitmap_callbacks); gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data); gif_result gif_decode_frame(gif_animation *gif, unsigned int frame); void gif_finalise(gif_animation *gif); #endif libnsgif-0.0.1/libnsgif.pc.in0000644000175000017500000000033711173445650016314 0ustar dsilversdsilversprefix=PREFIX exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include Name: libnsgif Description: Provides gif loading and conversion Version: VERSION Libs: -L${libdir} -lnsgif Cflags: -I${includedir} libnsgif-0.0.1/src/0000755000175000017500000000000011174063166014351 5ustar dsilversdsilverslibnsgif-0.0.1/src/utils/0000755000175000017500000000000011174063166015511 5ustar dsilversdsilverslibnsgif-0.0.1/src/utils/log.h0000644000175000017500000000103211060174716016435 0ustar dsilversdsilvers/* * Copyright 2003 James Bursa * Copyright 2004 John Tytgat * * This file is part of NetSurf, http://www.netsurf-browser.org/ * Licenced under the MIT License, * http://www.opensource.org/licenses/mit-license.php */ #include #ifndef _LIBNSGIF_LOG_H_ #define _LIBNSGIF_LOG_H_ #ifdef NDEBUG # define LOG(x) ((void) 0) #else # define LOG(x) do { fprintf(stderr, x), fputc('\n', stderr); } while (0) #endif /* NDEBUG */ #endif /* _LIBNSGIF_LOG_H_ */ libnsgif-0.0.1/src/Makefile0000644000175000017500000000011511163550400015774 0ustar dsilversdsilvers# Sources DIR_SOURCES := libnsgif.c include build/makefiles/Makefile.subdir libnsgif-0.0.1/src/libnsgif.c0000644000175000017500000011324411163551077016320 0ustar dsilversdsilvers/* * Copyright 2004 Richard Wilson * Copyright 2008 Sean Fox * * This file is part of NetSurf's libnsgif, http://www.netsurf-browser.org/ * Licenced under the MIT License, * http://www.opensource.org/licenses/mit-license.php */ #include #include #include #include #include #include "libnsgif.h" #include "utils/log.h" /* READING GIF FILES ================= The functions provided by this file allow for efficient progressive GIF decoding. Whilst the initialisation does not ensure that there is sufficient image data to complete the entire frame, it does ensure that the information provided is valid. Any subsequent attempts to decode an initialised GIF are guaranteed to succeed, and any bytes of the image not present are assumed to be totally transparent. To begin decoding a GIF, the 'gif' structure must be initialised with the 'gif_data' and 'buffer_size' set to their initial values. The 'buffer_position' should initially be 0, and will be internally updated as the decoding commences. The caller should then repeatedly call gif_initialise() with the structure until the function returns 1, or no more data is avaliable. Once the initialisation has begun, the decoder completes the variables 'frame_count' and 'frame_count_partial'. The former being the total number of frames that have been successfully initialised, and the latter being the number of frames that a partial amount of data is available for. This assists the caller in managing the animation whilst decoding is continuing. To decode a frame, the caller must use gif_decode_frame() which updates the current 'frame_image' to reflect the desired frame. The required 'disposal_method' is also updated to reflect how the frame should be plotted. The caller must not assume that the current 'frame_image' will be valid between calls if initialisation is still occuring, and should either always request that the frame is decoded (no processing will occur if the 'decoded_frame' has not been invalidated by initialisation) or perform the check itself. It should be noted that gif_finalise() should always be called, even if no frames were initialised. Additionally, it is the responsibility of the caller to free 'gif_data'. [rjw] - Fri 2nd April 2004 */ /* TO-DO LIST ================= + Plain text and comment extensions could be implemented if there is any interest in doing so. */ /* Maximum colour table size */ #define GIF_MAX_COLOURS 256 /* Internal flag that the colour table needs to be processed */ #define GIF_PROCESS_COLOURS 0xaa000000 /* Internal flag that a frame is invalid/unprocessed */ #define GIF_INVALID_FRAME -1 /* Maximum LZW bits available */ #define GIF_MAX_LZW 12 /* Transparent colour */ #define GIF_TRANSPARENT_COLOUR 0x00 /* GIF Flags */ #define GIF_FRAME_COMBINE 1 #define GIF_FRAME_CLEAR 2 #define GIF_FRAME_RESTORE 3 #define GIF_FRAME_QUIRKS_RESTORE 4 #define GIF_IMAGE_SEPARATOR 0x2c #define GIF_INTERLACE_MASK 0x40 #define GIF_COLOUR_TABLE_MASK 0x80 #define GIF_COLOUR_TABLE_SIZE_MASK 0x07 #define GIF_EXTENSION_INTRODUCER 0x21 #define GIF_EXTENSION_GRAPHIC_CONTROL 0xf9 #define GIF_DISPOSAL_MASK 0x1c #define GIF_TRANSPARENCY_MASK 0x01 #define GIF_EXTENSION_COMMENT 0xfe #define GIF_EXTENSION_PLAIN_TEXT 0x01 #define GIF_EXTENSION_APPLICATION 0xff #define GIF_BLOCK_TERMINATOR 0x00 #define GIF_TRAILER 0x3b /* Internal GIF routines */ static gif_result gif_initialise_sprite(gif_animation *gif, unsigned int width, unsigned int height); static gif_result gif_initialise_frame(gif_animation *gif); static gif_result gif_initialise_frame_extensions(gif_animation *gif, const int frame); static gif_result gif_skip_frame_extensions(gif_animation *gif); static unsigned int gif_interlaced_line(int height, int y); /* Internal LZW routines */ static void gif_init_LZW(gif_animation *gif); static bool gif_next_LZW(gif_animation *gif); static int gif_next_code(gif_animation *gif, int code_size); /* General LZW values. They are shared for all GIFs being decoded, and thus we can't handle progressive decoding efficiently without having the data for each image which would use an extra 10Kb or so per GIF. */ static unsigned char buf[4]; static unsigned char *direct; static int maskTbl[16] = {0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff}; static int table[2][(1 << GIF_MAX_LZW)]; static unsigned char stack[(1 << GIF_MAX_LZW) * 2]; static unsigned char *stack_pointer; static int code_size, set_code_size; static int max_code, max_code_size; static int clear_code, end_code; static int curbit, lastbit, last_byte; static int firstcode, oldcode; static bool zero_data_block = false; static bool get_done; /* Whether to clear the decoded image rather than plot */ static bool clear_image = false; /** Initialises necessary gif_animation members. */ void gif_create(gif_animation *gif, gif_bitmap_callback_vt *bitmap_callbacks) { memset(gif, 0, sizeof(gif_animation)); gif->bitmap_callbacks = *bitmap_callbacks; gif->decoded_frame = GIF_INVALID_FRAME; } /** Initialises any workspace held by the animation and attempts to decode any information that hasn't already been decoded. If an error occurs, all previously decoded frames are retained. @return GIF_FRAME_DATA_ERROR for GIF frame data error GIF_INSUFFICIENT_FRAME_DATA for insufficient data to process any more frames GIF_INSUFFICIENT_MEMORY for memory error GIF_DATA_ERROR for GIF error GIF_INSUFFICIENT_DATA for insufficient data to do anything GIF_OK for successful decoding GIF_WORKING for successful decoding if more frames are expected */ gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data) { unsigned char *gif_data; unsigned int index; gif_result return_value; /* The GIF format is thoroughly documented; a full description * can be found at http://www.w3.org/Graphics/GIF/spec-gif89a.txt */ /* Initialize values */ gif->buffer_size = size; gif->gif_data = data; /* Check for sufficient data to be a GIF (6-byte header + 7-byte logical screen descriptor) */ if (gif->buffer_size < 13) return GIF_INSUFFICIENT_DATA; /* Get our current processing position */ gif_data = gif->gif_data + gif->buffer_position; /* See if we should initialise the GIF */ if (gif->buffer_position == 0) { /* We want everything to be NULL before we start so we've no chance of freeing bad pointers (paranoia) */ gif->frame_image = NULL; gif->frames = NULL; gif->local_colour_table = NULL; gif->global_colour_table = NULL; /* The caller may have been lazy and not reset any values */ gif->frame_count = 0; gif->frame_count_partial = 0; gif->decoded_frame = GIF_INVALID_FRAME; /* 6-byte GIF file header is: * * +0 3CHARS Signature ('GIF') * +3 3CHARS Version ('87a' or '89a') */ if (strncmp((const char *) gif_data, "GIF", 3) != 0) return GIF_DATA_ERROR; gif_data += 3; /* Ensure GIF reports version 87a or 89a */ /* if ((strncmp(gif_data, "87a", 3) != 0) && (strncmp(gif_data, "89a", 3) != 0)) LOG(("Unknown GIF format - proceeding anyway")); */ gif_data += 3; /* 7-byte Logical Screen Descriptor is: * * +0 SHORT Logical Screen Width * +2 SHORT Logical Screen Height * +4 CHAR __Packed Fields__ * 1BIT Global Colour Table Flag * 3BITS Colour Resolution * 1BIT Sort Flag * 3BITS Size of Global Colour Table * +5 CHAR Background Colour Index * +6 CHAR Pixel Aspect Ratio */ gif->width = gif_data[0] | (gif_data[1] << 8); gif->height = gif_data[2] | (gif_data[3] << 8); gif->global_colours = (gif_data[4] & GIF_COLOUR_TABLE_MASK); gif->colour_table_size = (2 << (gif_data[4] & GIF_COLOUR_TABLE_SIZE_MASK)); gif->background_index = gif_data[5]; gif->aspect_ratio = gif_data[6]; gif->loop_count = 1; gif_data += 7; /* Some broken GIFs report the size as the screen size they were created in. As such, we detect for the common cases and set the sizes as 0 if they are found which results in the GIF being the maximum size of the frames. */ if (((gif->width == 640) && (gif->height == 480)) || ((gif->width == 640) && (gif->height == 512)) || ((gif->width == 800) && (gif->height == 600)) || ((gif->width == 1024) && (gif->height == 768)) || ((gif->width == 1280) && (gif->height == 1024)) || ((gif->width == 1600) && (gif->height == 1200)) || ((gif->width == 0) || (gif->height == 0)) || ((gif->width > 2048) || (gif->height > 2048))) { gif->width = 1; gif->height = 1; } /* Allocate some data irrespective of whether we've got any colour tables. We always get the maximum size in case a GIF is lying to us. It's far better to give the wrong colours than to trample over some memory somewhere. */ gif->global_colour_table = (unsigned int *)calloc(GIF_MAX_COLOURS, sizeof(int)); gif->local_colour_table = (unsigned int *)calloc(GIF_MAX_COLOURS, sizeof(int)); if ((gif->global_colour_table == NULL) || (gif->local_colour_table == NULL)) { gif_finalise(gif); return GIF_INSUFFICIENT_MEMORY; } /* Set the first colour to a value that will never occur in reality so we know if we've processed it */ gif->global_colour_table[0] = GIF_PROCESS_COLOURS; /* Check if the GIF has no frame data (13-byte header + 1-byte termination block) * Although generally useless, the GIF specification does not expressly prohibit this */ if (gif->buffer_size == 14) { if (gif_data[0] == GIF_TRAILER) return GIF_OK; else return GIF_INSUFFICIENT_DATA; } /* Initialise enough workspace for 4 frames initially */ if ((gif->frames = (gif_frame *)malloc(sizeof(gif_frame))) == NULL) { gif_finalise(gif); return GIF_INSUFFICIENT_MEMORY; } gif->frame_holders = 1; /* Initialise the sprite header */ assert(gif->bitmap_callbacks.bitmap_create); if ((gif->frame_image = gif->bitmap_callbacks.bitmap_create(gif->width, gif->height)) == NULL) { gif_finalise(gif); return GIF_INSUFFICIENT_MEMORY; } /* Remember we've done this now */ gif->buffer_position = gif_data - gif->gif_data; } /* Do the colour map if we haven't already. As the top byte is always 0xff or 0x00 depending on the transparency we know if it's been filled in. */ if (gif->global_colour_table[0] == GIF_PROCESS_COLOURS) { /* Check for a global colour map signified by bit 7 */ if (gif->global_colours) { if (gif->buffer_size < (gif->colour_table_size * 3 + 12)) { return GIF_INSUFFICIENT_DATA; } for (index = 0; index < gif->colour_table_size; index++) { char colour[] = {0, 0, 0, (char)0xff}; colour[0] = gif_data[0]; colour[1] = gif_data[1]; colour[2] = gif_data[2]; gif->global_colour_table[index] = *((int *) (void *) colour); gif_data += 3; } gif->buffer_position = (gif_data - gif->gif_data); } else { /* Create a default colour table with the first two colours as black and white */ gif->global_colour_table[0] = 0xff000000; gif->global_colour_table[1] = 0xffffffff; } } /* Repeatedly try to initialise frames */ while ((return_value = gif_initialise_frame(gif)) == GIF_WORKING); /* If there was a memory error tell the caller */ if ((return_value == GIF_INSUFFICIENT_MEMORY) || (return_value == GIF_DATA_ERROR)) return return_value; /* If we didn't have some frames then a GIF_INSUFFICIENT_DATA becomes a GIF_INSUFFICIENT_FRAME_DATA */ if ((return_value == GIF_INSUFFICIENT_DATA) && (gif->frame_count_partial > 0)) return GIF_INSUFFICIENT_FRAME_DATA; /* Return how many we got */ return return_value; } /** Updates the sprite memory size @return GIF_INSUFFICIENT_MEMORY for a memory error GIF_OK for success */ static gif_result gif_initialise_sprite(gif_animation *gif, unsigned int width, unsigned int height) { unsigned int max_width; unsigned int max_height; struct bitmap *buffer; /* Check if we've changed */ if ((width <= gif->width) && (height <= gif->height)) return GIF_OK; /* Get our maximum values */ max_width = (width > gif->width) ? width : gif->width; max_height = (height > gif->height) ? height : gif->height; /* Allocate some more memory */ assert(gif->bitmap_callbacks.bitmap_create); if ((buffer = gif->bitmap_callbacks.bitmap_create(max_width, max_height)) == NULL) return GIF_INSUFFICIENT_MEMORY; assert(gif->bitmap_callbacks.bitmap_destroy); gif->bitmap_callbacks.bitmap_destroy(gif->frame_image); gif->frame_image = buffer; gif->width = max_width; gif->height = max_height; /* Invalidate our currently decoded image */ gif->decoded_frame = GIF_INVALID_FRAME; return GIF_OK; } /** Attempts to initialise the next frame @return GIF_INSUFFICIENT_DATA for insufficient data to do anything GIF_FRAME_DATA_ERROR for GIF frame data error GIF_INSUFFICIENT_MEMORY for insufficient memory to process GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame GIF_DATA_ERROR for GIF error (invalid frame header) GIF_OK for successful decoding GIF_WORKING for successful decoding if more frames are expected */ static gif_result gif_initialise_frame(gif_animation *gif) { int frame; gif_frame *temp_buf; unsigned char *gif_data, *gif_end; int gif_bytes; unsigned int flags = 0; unsigned int width, height, offset_x, offset_y; unsigned int block_size, colour_table_size; bool first_image = true; gif_result return_value; /* Get the frame to decode and our data position */ frame = gif->frame_count; /* Get our buffer position etc. */ gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position); gif_end = (unsigned char *)(gif->gif_data + gif->buffer_size); gif_bytes = (gif_end - gif_data); /* Check if we've finished */ if ((gif_bytes > 0) && (gif_data[0] == GIF_TRAILER)) return GIF_OK; /* Check if we have enough data * The shortest block of data is a 4-byte comment extension + 1-byte block terminator + 1-byte gif trailer */ if (gif_bytes < 6) return GIF_INSUFFICIENT_DATA; /* We could theoretically get some junk data that gives us millions of frames, so we ensure that we don't have a silly number */ if (frame > 4096) return GIF_FRAME_DATA_ERROR; /* Get some memory to store our pointers in etc. */ if ((int)gif->frame_holders <= frame) { /* Allocate more memory */ if ((temp_buf = (gif_frame *)realloc(gif->frames, (frame + 1) * sizeof(gif_frame))) == NULL) return GIF_INSUFFICIENT_MEMORY; gif->frames = temp_buf; gif->frame_holders = frame + 1; } /* Store our frame pointer. We would do it when allocating except we start off with one frame allocated so we can always use realloc. */ gif->frames[frame].frame_pointer = gif->buffer_position; gif->frames[frame].display = false; gif->frames[frame].virgin = true; gif->frames[frame].disposal_method = 0; gif->frames[frame].transparency = false; gif->frames[frame].frame_delay = 100; gif->frames[frame].redraw_required = false; /* Invalidate any previous decoding we have of this frame */ if (gif->decoded_frame == frame) gif->decoded_frame = GIF_INVALID_FRAME; /* We pretend to initialise the frames, but really we just skip over all the data contained within. This is all basically a cut down version of gif_decode_frame that doesn't have any of the LZW bits in it. */ /* Initialise any extensions */ gif->buffer_position = gif_data - gif->gif_data; if ((return_value = gif_initialise_frame_extensions(gif, frame)) != GIF_OK) return return_value; gif_data = (gif->gif_data + gif->buffer_position); gif_bytes = (gif_end - gif_data); /* Check if we've finished */ if ((gif_bytes = (gif_end - gif_data)) < 1) return GIF_INSUFFICIENT_FRAME_DATA; else if (gif_data[0] == GIF_TRAILER) { gif->buffer_position = (gif_data - gif->gif_data); gif->frame_count = frame + 1; return GIF_OK; } /* If we're not done, there should be an image descriptor */ if (gif_data[0] != GIF_IMAGE_SEPARATOR) return GIF_FRAME_DATA_ERROR; /* Do some simple boundary checking */ offset_x = gif_data[1] | (gif_data[2] << 8); offset_y = gif_data[3] | (gif_data[4] << 8); width = gif_data[5] | (gif_data[6] << 8); height = gif_data[7] | (gif_data[8] << 8); /* Set up the redraw characteristics. We have to check for extending the area due to multi-image frames. */ if (!first_image) { if (gif->frames[frame].redraw_x > offset_x) { gif->frames[frame].redraw_width += (gif->frames[frame].redraw_x - offset_x); gif->frames[frame].redraw_x = offset_x; } if (gif->frames[frame].redraw_y > offset_y) { gif->frames[frame].redraw_height += (gif->frames[frame].redraw_y - offset_y); gif->frames[frame].redraw_y = offset_y; } if ((offset_x + width) > (gif->frames[frame].redraw_x + gif->frames[frame].redraw_width)) gif->frames[frame].redraw_width = (offset_x + width) - gif->frames[frame].redraw_x; if ((offset_y + height) > (gif->frames[frame].redraw_y + gif->frames[frame].redraw_height)) gif->frames[frame].redraw_height = (offset_y + height) - gif->frames[frame].redraw_y; } else { first_image = false; gif->frames[frame].redraw_x = offset_x; gif->frames[frame].redraw_y = offset_y; gif->frames[frame].redraw_width = width; gif->frames[frame].redraw_height = height; } /* if we are clearing the background then we need to redraw enough to cover the previous frame too */ gif->frames[frame].redraw_required = ((gif->frames[frame].disposal_method == GIF_FRAME_CLEAR) || (gif->frames[frame].disposal_method == GIF_FRAME_RESTORE)); /* Boundary checking - shouldn't ever happen except with junk data */ if (gif_initialise_sprite(gif, (offset_x + width), (offset_y + height))) return GIF_INSUFFICIENT_MEMORY; /* Decode the flags */ flags = gif_data[9]; colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK); /* Move our data onwards and remember we've got a bit of this frame */ gif_data += 10; gif_bytes = (gif_end - gif_data); gif->frame_count_partial = frame + 1; /* Skip the local colour table */ if (flags & GIF_COLOUR_TABLE_MASK) { gif_data += 3 * colour_table_size; if ((gif_bytes = (gif_end - gif_data)) < 0) return GIF_INSUFFICIENT_FRAME_DATA; } /* Ensure we have a correct code size */ if (gif_data[0] > GIF_MAX_LZW) return GIF_DATA_ERROR; /* Move our pointer to the actual image data */ gif_data++; if (--gif_bytes < 0) return GIF_INSUFFICIENT_FRAME_DATA; /* Repeatedly skip blocks until we get a zero block or run out of data * These blocks of image data are processed later by gif_decode_frame() */ block_size = 0; while (block_size != 1) { block_size = gif_data[0] + 1; /* Check if the frame data runs off the end of the file */ if ((int)(gif_bytes - block_size) < 0) { /* Try to recover by signaling the end of the gif. * Once we get garbage data, there is no logical * way to determine where the next frame is. * It's probably better to partially load the gif * than not at all. */ if (gif_bytes >= 2) { gif_data[0] = 0; gif_data[1] = GIF_TRAILER; gif_bytes = 1; ++gif_data; break; } else return GIF_INSUFFICIENT_FRAME_DATA; } else { gif_bytes -= block_size; gif_data += block_size; } } /* Add the frame and set the display flag */ gif->buffer_position = gif_data - gif->gif_data; gif->frame_count = frame + 1; gif->frames[frame].display = true; /* Check if we've finished */ if (gif_bytes < 1) return GIF_INSUFFICIENT_FRAME_DATA; else if (gif_data[0] == GIF_TRAILER) return GIF_OK; return GIF_WORKING; } /** Attempts to initialise the frame's extensions @return GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame GIF_OK for successful initialisation */ static gif_result gif_initialise_frame_extensions(gif_animation *gif, const int frame) { unsigned char *gif_data, *gif_end; int gif_bytes; unsigned int block_size; /* Get our buffer position etc. */ gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position); gif_end = (unsigned char *)(gif->gif_data + gif->buffer_size); /* Initialise the extensions */ while (gif_data[0] == GIF_EXTENSION_INTRODUCER) { ++gif_data; gif_bytes = (gif_end - gif_data); /* Switch on extension label */ switch(gif_data[0]) { /* 6-byte Graphic Control Extension is: * * +0 CHAR Graphic Control Label * +1 CHAR Block Size * +2 CHAR __Packed Fields__ * 3BITS Reserved * 3BITS Disposal Method * 1BIT User Input Flag * 1BIT Transparent Color Flag * +3 SHORT Delay Time * +5 CHAR Transparent Color Index */ case GIF_EXTENSION_GRAPHIC_CONTROL: if (gif_bytes < 6) return GIF_INSUFFICIENT_FRAME_DATA; gif->frames[frame].frame_delay = gif_data[3] | (gif_data[4] << 8); if (gif_data[2] & GIF_TRANSPARENCY_MASK) { gif->frames[frame].transparency = true; gif->frames[frame].transparency_index = gif_data[5]; } gif->frames[frame].disposal_method = ((gif_data[2] & GIF_DISPOSAL_MASK) >> 2); /* I have encountered documentation and GIFs in the wild that use * 0x04 to restore the previous frame, rather than the officially * documented 0x03. I believe some (older?) software may even actually * export this way. We handle this as a type of "quirks" mode. */ if (gif->frames[frame].disposal_method == GIF_FRAME_QUIRKS_RESTORE) gif->frames[frame].disposal_method = GIF_FRAME_RESTORE; gif_data += (2 + gif_data[1]); break; /* 14-byte+ Application Extension is: * * +0 CHAR Application Extension Label * +1 CHAR Block Size * +2 8CHARS Application Identifier * +10 3CHARS Appl. Authentication Code * +13 1-256 Application Data (Data sub-blocks) */ case GIF_EXTENSION_APPLICATION: if (gif_bytes < 17) return GIF_INSUFFICIENT_FRAME_DATA; if ((gif_data[1] == 0x0b) && (strncmp((const char *) gif_data + 2, "NETSCAPE2.0", 11) == 0) && (gif_data[13] == 0x03) && (gif_data[14] == 0x01)) { gif->loop_count = gif_data[15] | (gif_data[16] << 8); } gif_data += (2 + gif_data[1]); break; /* Move the pointer to the first data sub-block * Skip 1 byte for the extension label */ case GIF_EXTENSION_COMMENT: ++gif_data; break; /* Move the pointer to the first data sub-block * Skip 2 bytes for the extension label and size fields * Skip the extension size itself */ default: gif_data += (2 + gif_data[1]); } /* Repeatedly skip blocks until we get a zero block or run out of data * This data is ignored by this gif decoder */ gif_bytes = (gif_end - gif_data); block_size = 0; while (gif_data[0] != GIF_BLOCK_TERMINATOR) { block_size = gif_data[0] + 1; if ((gif_bytes -= block_size) < 0) return GIF_INSUFFICIENT_FRAME_DATA; gif_data += block_size; } ++gif_data; } /* Set buffer position and return */ gif->buffer_position = (gif_data - gif->gif_data); return GIF_OK; } /** Decodes a GIF frame. @return GIF_FRAME_DATA_ERROR for GIF frame data error GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame GIF_DATA_ERROR for GIF error (invalid frame header) GIF_INSUFFICIENT_DATA for insufficient data to do anything GIF_INSUFFICIENT_MEMORY for insufficient memory to process GIF_OK for successful decoding If a frame does not contain any image data, GIF_OK is returned and gif->current_error is set to GIF_FRAME_NO_DISPLAY */ gif_result gif_decode_frame(gif_animation *gif, unsigned int frame) { unsigned int index = 0; unsigned char *gif_data, *gif_end; int gif_bytes; unsigned int width, height, offset_x, offset_y; unsigned int flags, colour_table_size, interlace; unsigned int *colour_table; unsigned int *frame_data = 0; // Set to 0 for no warnings unsigned int *frame_scanline; unsigned int save_buffer_position; unsigned int return_value = 0; unsigned int x, y, decode_y, burst_bytes; int last_undisposed_frame = (frame - 1); register unsigned char colour; /* Ensure this frame is supposed to be decoded */ if (gif->frames[frame].display == false) { gif->current_error = GIF_FRAME_NO_DISPLAY; return GIF_OK; } /* Ensure we have a frame to decode */ if (frame > gif->frame_count_partial) return GIF_INSUFFICIENT_DATA; if ((!clear_image) && ((int)frame == gif->decoded_frame)) return GIF_OK; /* Get the start of our frame data and the end of the GIF data */ gif_data = gif->gif_data + gif->frames[frame].frame_pointer; gif_end = gif->gif_data + gif->buffer_size; gif_bytes = (gif_end - gif_data); /* Check if we have enough data * The shortest block of data is a 10-byte image descriptor + 1-byte gif trailer */ if (gif_bytes < 12) return GIF_INSUFFICIENT_FRAME_DATA; /* Save the buffer position */ save_buffer_position = gif->buffer_position; gif->buffer_position = gif_data - gif->gif_data; /* Skip any extensions because we all ready processed them */ if ((return_value = gif_skip_frame_extensions(gif)) != GIF_OK) goto gif_decode_frame_exit; gif_data = (gif->gif_data + gif->buffer_position); gif_bytes = (gif_end - gif_data); /* Ensure we have enough data for the 10-byte image descriptor + 1-byte gif trailer */ if (gif_bytes < 12) { return_value = GIF_INSUFFICIENT_FRAME_DATA; goto gif_decode_frame_exit; } /* 10-byte Image Descriptor is: * * +0 CHAR Image Separator (0x2c) * +1 SHORT Image Left Position * +3 SHORT Image Top Position * +5 SHORT Width * +7 SHORT Height * +9 CHAR __Packed Fields__ * 1BIT Local Colour Table Flag * 1BIT Interlace Flag * 1BIT Sort Flag * 2BITS Reserved * 3BITS Size of Local Colour Table */ if (gif_data[0] != GIF_IMAGE_SEPARATOR) { return_value = GIF_DATA_ERROR; goto gif_decode_frame_exit; } offset_x = gif_data[1] | (gif_data[2] << 8); offset_y = gif_data[3] | (gif_data[4] << 8); width = gif_data[5] | (gif_data[6] << 8); height = gif_data[7] | (gif_data[8] << 8); /* Boundary checking - shouldn't ever happen except unless the data has been modified since initialisation. */ if ((offset_x + width > gif->width) || (offset_y + height > gif->height)) { return_value = GIF_DATA_ERROR; goto gif_decode_frame_exit; } /* Decode the flags */ flags = gif_data[9]; colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK); interlace = flags & GIF_INTERLACE_MASK; /* Move our pointer to the colour table or image data (if no colour table is given) */ gif_data += 10; gif_bytes = (gif_end - gif_data); /* Set up the colour table */ if (flags & GIF_COLOUR_TABLE_MASK) { if (gif_bytes < (int)(3 * colour_table_size)) { return_value = GIF_INSUFFICIENT_FRAME_DATA; goto gif_decode_frame_exit; } colour_table = gif->local_colour_table; if (!clear_image) { for (index = 0; index < colour_table_size; index++) { char colour[] = {0, 0, 0, (char)0xff}; colour[0] = gif_data[0]; colour[1] = gif_data[1]; colour[2] = gif_data[2]; colour_table[index] = *((int *) (void *) colour); gif_data += 3; } } else { gif_data += 3 * colour_table_size; } gif_bytes = (gif_end - gif_data); } else { colour_table = gif->global_colour_table; } /* Check if we've finished */ if (gif_bytes < 1) { return_value = GIF_INSUFFICIENT_FRAME_DATA; goto gif_decode_frame_exit; } else if (gif_data[0] == GIF_TRAILER) { return_value = GIF_OK; goto gif_decode_frame_exit; } /* Get the frame data */ assert(gif->bitmap_callbacks.bitmap_get_buffer); frame_data = (void *)gif->bitmap_callbacks.bitmap_get_buffer(gif->frame_image); if (!frame_data) return GIF_INSUFFICIENT_MEMORY; /* If we are clearing the image we just clear, if not decode */ if (!clear_image) { /* Ensure we have enough data for a 1-byte LZW code size + 1-byte gif trailer */ if (gif_bytes < 2) { return_value = GIF_INSUFFICIENT_FRAME_DATA; goto gif_decode_frame_exit; /* If we only have a 1-byte LZW code size + 1-byte gif trailer, we're finished */ } else if ((gif_bytes == 2) && (gif_data[1] == GIF_TRAILER)) { return_value = GIF_OK; goto gif_decode_frame_exit; } /* If the previous frame's disposal method requires we restore the background * colour or this is the first frame, clear the frame data */ if ((frame == 0) || (gif->decoded_frame == GIF_INVALID_FRAME)) { memset((char*)frame_data, GIF_TRANSPARENT_COLOUR, gif->width * gif->height * sizeof(int)); gif->decoded_frame = frame; /* The line below would fill the image with its background color, but because GIFs support * transparency we likely wouldn't want to do that. */ /* memset((char*)frame_data, colour_table[gif->background_index], gif->width * gif->height * sizeof(int)); */ } else if ((frame != 0) && (gif->frames[frame - 1].disposal_method == GIF_FRAME_CLEAR)) { clear_image = true; if ((return_value = gif_decode_frame(gif, (frame - 1))) != GIF_OK) goto gif_decode_frame_exit; clear_image = false; /* If the previous frame's disposal method requires we restore the previous * image, find the last image set to "do not dispose" and get that frame data */ } else if ((frame != 0) && (gif->frames[frame - 1].disposal_method == GIF_FRAME_RESTORE)) { while ((last_undisposed_frame != -1) && (gif->frames[--last_undisposed_frame].disposal_method == GIF_FRAME_RESTORE)); /* If we don't find one, clear the frame data */ if (last_undisposed_frame == -1) { /* see notes above on transparency vs. background color */ memset((char*)frame_data, GIF_TRANSPARENT_COLOUR, gif->width * gif->height * sizeof(int)); } else { if ((return_value = gif_decode_frame(gif, last_undisposed_frame)) != GIF_OK) goto gif_decode_frame_exit; /* Get this frame's data */ assert(gif->bitmap_callbacks.bitmap_get_buffer); frame_data = (void *)gif->bitmap_callbacks.bitmap_get_buffer(gif->frame_image); if (!frame_data) return GIF_INSUFFICIENT_MEMORY; } } gif->decoded_frame = frame; /* Initialise the LZW decoding */ set_code_size = gif_data[0]; gif->buffer_position = (gif_data - gif->gif_data) + 1; /* Set our code variables */ code_size = set_code_size + 1; clear_code = (1 << set_code_size); end_code = clear_code + 1; max_code_size = clear_code << 1; max_code = clear_code + 2; curbit = lastbit = 0; last_byte = 2; get_done = false; direct = buf; gif_init_LZW(gif); /* Decompress the data */ for (y = 0; y < height; y++) { if (interlace) decode_y = gif_interlaced_line(height, y) + offset_y; else decode_y = y + offset_y; frame_scanline = frame_data + offset_x + (decode_y * gif->width); /* Rather than decoding pixel by pixel, we try to burst out streams of data to remove the need for end-of data checks every pixel. */ x = width; while (x > 0) { burst_bytes = (stack_pointer - stack); if (burst_bytes > 0) { if (burst_bytes > x) burst_bytes = x; x -= burst_bytes; while (burst_bytes-- > 0) { colour = *--stack_pointer; if (((gif->frames[frame].transparency) && (colour != gif->frames[frame].transparency_index)) || (!gif->frames[frame].transparency)) *frame_scanline = colour_table[colour]; frame_scanline++; } } else { if (!gif_next_LZW(gif)) { /* Unexpected end of frame, try to recover */ if (gif->current_error == GIF_END_OF_FRAME) return_value = GIF_OK; else return_value = gif->current_error; goto gif_decode_frame_exit; } } } } } else { /* Clear our frame */ if (gif->frames[frame].disposal_method == GIF_FRAME_CLEAR) { for (y = 0; y < height; y++) { frame_scanline = frame_data + offset_x + ((offset_y + y) * gif->width); if (gif->frames[frame].transparency) memset(frame_scanline, GIF_TRANSPARENT_COLOUR, width * 4); else memset(frame_scanline, colour_table[gif->background_index], width * 4); } } } gif_decode_frame_exit: /* Check if we should test for optimisation */ if (gif->frames[frame].virgin) { if (gif->bitmap_callbacks.bitmap_test_opaque) gif->frames[frame].opaque = gif->bitmap_callbacks.bitmap_test_opaque(gif->frame_image); else gif->frames[frame].opaque = false; gif->frames[frame].virgin = false; } if (gif->bitmap_callbacks.bitmap_set_opaque) gif->bitmap_callbacks.bitmap_set_opaque(gif->frame_image, gif->frames[frame].opaque); if (gif->bitmap_callbacks.bitmap_modified) gif->bitmap_callbacks.bitmap_modified(gif->frame_image); /* Restore the buffer position */ gif->buffer_position = save_buffer_position; /* Success! */ return return_value; } /** Skips the frame's extensions (which have been previously initialised) @return GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame GIF_OK for successful decoding */ static gif_result gif_skip_frame_extensions(gif_animation *gif) { unsigned char *gif_data, *gif_end; int gif_bytes; unsigned int block_size; /* Get our buffer position etc. */ gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position); gif_end = (unsigned char *)(gif->gif_data + gif->buffer_size); gif_bytes = (gif_end - gif_data); /* Skip the extensions */ while (gif_data[0] == GIF_EXTENSION_INTRODUCER) { ++gif_data; /* Switch on extension label */ switch(gif_data[0]) { /* Move the pointer to the first data sub-block * 1 byte for the extension label */ case GIF_EXTENSION_COMMENT: ++gif_data; break; /* Move the pointer to the first data sub-block * 2 bytes for the extension label and size fields * Skip the extension size itself */ default: gif_data += (2 + gif_data[1]); } /* Repeatedly skip blocks until we get a zero block or run out of data * This data is ignored by this gif decoder */ gif_bytes = (gif_end - gif_data); block_size = 0; while (gif_data[0] != GIF_BLOCK_TERMINATOR) { block_size = gif_data[0] + 1; if ((gif_bytes -= block_size) < 0) return GIF_INSUFFICIENT_FRAME_DATA; gif_data += block_size; } ++gif_data; } /* Set buffer position and return */ gif->buffer_position = (gif_data - gif->gif_data); return GIF_OK; } static unsigned int gif_interlaced_line(int height, int y) { if ((y << 3) < height) return (y << 3); y -= ((height + 7) >> 3); if ((y << 3) < (height - 4)) return (y << 3) + 4; y -= ((height + 3) >> 3); if ((y << 2) < (height - 2)) return (y << 2) + 2; y -= ((height + 1) >> 2); return (y << 1) + 1; } /* Releases any workspace held by the animation */ void gif_finalise(gif_animation *gif) { /* Release all our memory blocks */ if (gif->frame_image) { assert(gif->bitmap_callbacks.bitmap_destroy); gif->bitmap_callbacks.bitmap_destroy(gif->frame_image); } gif->frame_image = NULL; free(gif->frames); gif->frames = NULL; free(gif->local_colour_table); gif->local_colour_table = NULL; free(gif->global_colour_table); gif->global_colour_table = NULL; } /** * Initialise LZW decoding */ void gif_init_LZW(gif_animation *gif) { int i; gif->current_error = 0; if (clear_code >= (1 << GIF_MAX_LZW)) { stack_pointer = stack; gif->current_error = GIF_FRAME_DATA_ERROR; return; } /* initialise our table */ memset(table, 0x00, (1 << GIF_MAX_LZW) * 8); for (i = 0; i < clear_code; ++i) table[1][i] = i; /* update our LZW parameters */ code_size = set_code_size + 1; max_code_size = clear_code << 1; max_code = clear_code + 2; stack_pointer = stack; do { firstcode = oldcode = gif_next_code(gif, code_size); } while (firstcode == clear_code); *stack_pointer++ =firstcode; } static bool gif_next_LZW(gif_animation *gif) { int code, incode; int block_size; int new_code; code = gif_next_code(gif, code_size); if (code < 0) { gif->current_error = code; return false; } else if (code == clear_code) { gif_init_LZW(gif); return true; } else if (code == end_code) { /* skip to the end of our data so multi-image GIFs work */ if (zero_data_block) { gif->current_error = GIF_FRAME_DATA_ERROR; return false; } block_size = 0; while (block_size != 1) { block_size = gif->gif_data[gif->buffer_position] + 1; gif->buffer_position += block_size; } gif->current_error = GIF_FRAME_DATA_ERROR; return false; } incode = code; if (code >= max_code) { *stack_pointer++ = firstcode; code = oldcode; } /* The following loop is the most important in the GIF decoding cycle as every * single pixel passes through it. * * Note: our stack is always big enough to hold a complete decompressed chunk. */ while (code >= clear_code) { *stack_pointer++ = table[1][code]; new_code = table[0][code]; if (new_code < clear_code) { code = new_code; break; } *stack_pointer++ = table[1][new_code]; code = table[0][new_code]; if (code == new_code) { gif->current_error = GIF_FRAME_DATA_ERROR; return false; } } *stack_pointer++ = firstcode = table[1][code]; if ((code = max_code) < (1 << GIF_MAX_LZW)) { table[0][code] = oldcode; table[1][code] = firstcode; ++max_code; if ((max_code >= max_code_size) && (max_code_size < (1 << GIF_MAX_LZW))) { max_code_size = max_code_size << 1; ++code_size; } } oldcode = incode; return true; } static int gif_next_code(gif_animation *gif, int code_size) { int i, j, end, count, ret; unsigned char *b; end = curbit + code_size; if (end >= lastbit) { if (get_done) return GIF_END_OF_FRAME; buf[0] = direct[last_byte - 2]; buf[1] = direct[last_byte - 1]; /* get the next block */ direct = gif->gif_data + gif->buffer_position; zero_data_block = ((count = direct[0]) == 0); if ((gif->buffer_position + count) >= gif->buffer_size) return GIF_INSUFFICIENT_FRAME_DATA; if (count == 0) get_done = true; else { direct -= 1; buf[2] = direct[2]; buf[3] = direct[3]; } gif->buffer_position += count + 1; /* update our variables */ last_byte = 2 + count; curbit = (curbit - lastbit) + 16; lastbit = (2 + count) << 3; end = curbit + code_size; } i = curbit >> 3; if (i < 2) b = buf; else b = direct; ret = b[i]; j = (end >> 3) - 1; if (i <= j) { ret |= (b[i + 1] << 8); if (i < j) ret |= (b[i + 2] << 16); } ret = (ret >> (curbit % 8)) & maskTbl[code_size]; curbit += code_size; return ret; } libnsgif-0.0.1/COPYING0000644000175000017500000000210711060174716014613 0ustar dsilversdsilversCopyright (C) 2004 Richard Wilson Copyright (C) 2008 Sean Fox Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. libnsgif-0.0.1/bin/0000755000175000017500000000000011174063166014332 5ustar dsilversdsilverslibnsgif-0.0.1/gif_display0000755000175000017500000000005011027263070015766 0ustar dsilversdsilversset -e make bin/decode_gif $1 | display libnsgif-0.0.1/Makefile0000644000175000017500000000163311173445650015226 0ustar dsilversdsilvers# Component settings COMPONENT := nsgif COMPONENT_VERSION := 0.0.1 # Default to a static library COMPONENT_TYPE ?= lib-static # Setup the tooling include build/makefiles/Makefile.tools # Toolchain flags WARNFLAGS := -Wall -Wundef -Wpointer-arith -Wcast-align \ -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes \ -Wmissing-declarations -Wnested-externs -Werror -pedantic ifneq ($(GCCVER),2) WARNFLAGS := $(WARNFLAGS) -Wextra endif CFLAGS := $(CFLAGS) -D_BSD_SOURCE -I$(CURDIR)/include/ \ -I$(CURDIR)/src $(WARNFLAGS) ifneq ($(GCCVER),2) CFLAGS := $(CFLAGS) -std=c99 else # __inline__ is a GCCism CFLAGS := $(CFLAGS) -Dinline="__inline__" endif include build/makefiles/Makefile.top # Extra installation rules I := /include INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/libnsgif.h INSTALL_ITEMS := $(INSTALL_ITEMS) /lib/pkgconfig:lib$(COMPONENT).pc.in INSTALL_ITEMS := $(INSTALL_ITEMS) /lib:$(OUTPUT) libnsgif-0.0.1/examples/0000755000175000017500000000000011174063167015401 5ustar dsilversdsilverslibnsgif-0.0.1/examples/decode_gif.c0000644000175000017500000001026111060174716017612 0ustar dsilversdsilvers/* * Copyright 2008 Sean Fox * Copyright 2008 James Bursa * * This file is part of NetSurf's libnsgif, http://www.netsurf-browser.org/ * Licenced under the MIT License, * http://www.opensource.org/licenses/mit-license.php */ #include #include #include #include #include #include #include #include "../libnsgif.h" unsigned char *load_file(const char *path, size_t *data_size); void warning(const char *context, int code); void *bitmap_create(int width, int height); void bitmap_set_opaque(void *bitmap, bool opaque); bool bitmap_test_opaque(void *bitmap); unsigned char *bitmap_get_buffer(void *bitmap); void bitmap_destroy(void *bitmap); void bitmap_modified(void *bitmap); int main(int argc, char *argv[]) { gif_bitmap_callback_vt bitmap_callbacks = { bitmap_create, bitmap_destroy, bitmap_get_buffer, bitmap_set_opaque, bitmap_test_opaque, bitmap_modified }; gif_animation gif; size_t size; gif_result code; unsigned int i; if (argc != 2) { fprintf(stderr, "Usage: %s image.gif\n", argv[0]); return 1; } /* create our gif animation */ gif_create(&gif, &bitmap_callbacks); /* load file into memory */ unsigned char *data = load_file(argv[1], &size); /* begin decoding */ do { code = gif_initialise(&gif, size, data); if (code != GIF_OK && code != GIF_WORKING) { warning("gif_initialise", code); exit(1); } } while (code != GIF_OK); printf("P3\n"); printf("# %s\n", argv[1]); printf("# width %u \n", gif.width); printf("# height %u \n", gif.height); printf("# frame_count %u \n", gif.frame_count); printf("# frame_count_partial %u \n", gif.frame_count_partial); printf("# loop_count %u \n", gif.loop_count); printf("%u %u 256\n", gif.width, gif.height * gif.frame_count); /* decode the frames */ for (i = 0; i != gif.frame_count; i++) { unsigned int row, col; unsigned char *image; code = gif_decode_frame(&gif, i); if (code != GIF_OK) warning("gif_decode_frame", code); printf("# frame %u:\n", i); image = (unsigned char *) gif.frame_image; for (row = 0; row != gif.height; row++) { for (col = 0; col != gif.width; col++) { size_t z = (row * gif.width + col) * 4; printf("%u %u %u ", (unsigned char) image[z], (unsigned char) image[z + 1], (unsigned char) image[z + 2]); } printf("\n"); } } /* clean up */ gif_finalise(&gif); free(data); return 0; } unsigned char *load_file(const char *path, size_t *data_size) { FILE *fd; struct stat sb; unsigned char *buffer; size_t size; size_t n; fd = fopen(path, "rb"); if (!fd) { perror(path); exit(EXIT_FAILURE); } if (stat(path, &sb)) { perror(path); exit(EXIT_FAILURE); } size = sb.st_size; buffer = malloc(size); if (!buffer) { fprintf(stderr, "Unable to allocate %lld bytes\n", (long long) size); exit(EXIT_FAILURE); } n = fread(buffer, 1, size, fd); if (n != size) { perror(path); exit(EXIT_FAILURE); } fclose(fd); *data_size = size; return buffer; } void warning(const char *context, gif_result code) { fprintf(stderr, "%s failed: ", context); switch (code) { case GIF_INSUFFICIENT_FRAME_DATA: fprintf(stderr, "GIF_INSUFFICIENT_FRAME_DATA"); break; case GIF_FRAME_DATA_ERROR: fprintf(stderr, "GIF_FRAME_DATA_ERROR"); break; case GIF_INSUFFICIENT_DATA: fprintf(stderr, "GIF_INSUFFICIENT_DATA"); break; case GIF_DATA_ERROR: fprintf(stderr, "GIF_DATA_ERROR"); break; case GIF_INSUFFICIENT_MEMORY: fprintf(stderr, "GIF_INSUFFICIENT_MEMORY"); break; default: fprintf(stderr, "unknown code %i", code); break; } fprintf(stderr, "\n"); } void *bitmap_create(int width, int height) { return calloc(width * height, 4); } void bitmap_set_opaque(void *bitmap, bool opaque) { (void) opaque; /* unused */ assert(bitmap); } bool bitmap_test_opaque(void *bitmap) { assert(bitmap); return false; } unsigned char *bitmap_get_buffer(void *bitmap) { assert(bitmap); return bitmap; } void bitmap_destroy(void *bitmap) { assert(bitmap); free(bitmap); } void bitmap_modified(void *bitmap) { assert(bitmap); return; } libnsgif-0.0.1/examples/waves.gif0000644000175000017500000055504111027263036017221 0ustar dsilversdsilversGIF89a V  , &C *<*41N$)+7J9` =]%7A/6:564*2Lv"GZ>0GP?DDQPp7HZC%< M2Wh`&GNSR Wi#P&i6O,U$[sef(`y`caJksBWAn2bo-g(k#{*k7h3z-nEd=j(u/t5qAmnqoNk.z=tHr>x:z.)KvEzOu;B#F} ;[3R{U{MM~~I-)+W=84OT@^N+`P[a[GfES 7NEy &IGF44ҧ }4kO< (e,yKJ/P`d3| Λ:٨Y|P@QjӧRZd!Q>VA R/h*}D%Fn)Y:ZK mI(! )y %`bc\ȘͦH PA}HBv"4ȚDP"@ĦX$8Jƒ7ݤN!dO1ԓs %%RNH V!w}!0TvZqW%~i#_kiBI[X%{faƠcB')}Hf VG"D+v ,*C@ ue%DK2DJI"N)r!I1Uч܉'#W~UiFu#Wؾ^I׹zjv®]hc):b**dK`fj=Zj0zЉbf i#d[K&фOEN^$R<]08;G K- ol; RV̱wܖWBYE~RW_ƫa:ؠVXc LfP QB'>wXE%Hp C*ӭD=!9rLEME+STZR4WBfň|UXvb]kݵ&ŗ'`z]ڈcYm.aZ3֩3J̑j D UjBFdTqsj'G]QX2VT+ީ#ЃXPB>@Z4BAeky0rPr/dhR=d*(!0R y ":\GDD=FaI 8f8ٜCE`T#W=6dDWA$$#+xc37|N93*IO ܡKO9V7Vи,5)Q۝SC%-qQ*aJ+ksJ/K^ -`c0 7#G`bFE6!YvCdsZ\OTg9f r7LKoܳ1 u &% :&d'W92&hY5g@ޠ%<H-{T0A \aZ6(Ub V'@t@OD%J^gC8Y+,UFyӌduBΗot$<}U#gD%$ O$Ls~rS)!x֙ \c)zTz6>-@<T$֗ jІڨF5t!^X78 z5\w%aa+IK5R0Ne5qQA %N \*<妕24c屜;sϷD=eSWiH-)P}yD!9LR2`M:)Ė磑-#CAD.M49䨐F6Pe1`t0PP2}hO{ M1gjխPZ@ޖ^Sp223//a(,. R՞uVXl,\KRtt$"I)0n"+#XA- 7EU|̖:d+332_cKBNw|J%X!xG;A+yY$cb凩-\ G= 5t(sohM~2fQCwV3a8PQ@< < k6pnMilϒlxs6Z;&(/|acCC96%6m%#$'aWx#hMjFg7St p@`z i\5XL.Z`'3SdYl@4P@eAh:@'}M ߰Gp0@@5 ` OcAZ-4Z;!q|r.zH''2< !1dh("/u=sBuu0) `p REwnekgg 0 -u57E1U$Z^"_^0,GBB Qj@`% G@ @ZPxN-ikO&mlw\` Uu Ҡ @ (=>׈‡^"c{#0T @qX E X0 pPoLF^1udG-2MeѴ}ЄXq0p  ;p PH5 xPj`fvP|qakr  Q `P!m5D+0b,q)*J p  _Б@` XKtQXl @ FEjeDT<(_2 ЉKMP~K:`@pK hi8 4` ^"8^0  Nvr5n5_[(Pww9 +6DF PLtZb  p p``  AXt%JI @\ @2dT+;IFd2R9V&@;o@ ڠp0q v7XQ@``(AB+A  dU#ToV UZUCc5 y {JA  ()b!>P\ ? ` p ǰ 2D `^TDwC1Hg\Pp2ed7a+&@5Aj S0S8:NFزMˢ%<# )p  y c-b և 8Box5% 1w}1stv볽ګ à + P :pDpv')ϵ FXj@PгŻ S< `p0+*c\)} ppzoF Ġ pK`$J6MBl i tP;i@ 5w-MW& pW PPp ɐ 2X cA + p ,p@ k!Ds(P|1-IR+h `Vi H p sP P0Ol Y  Ь, Q}` 무p;9C$?? mЮ  02B` M0V;@FqM١SXY { A0@ p  ,0- 5D5Cy< VieVрI)hDĵB/ uN\ O ؉μj Ȁ 0 /  #mpggm w`{ JSk@7 3ud l9Sr%3CSk3` K@Jq Np Wx ~ 0-p{.'5/cCI `pp Pi }r- ڶ!wzFO _P ŠM\)ĉ ` 0 $k`tpvKM xl`++q0 PJڿMP n +j0{6 D%  R3:}_ X,0; d -@PQc @ a3@ x"6zX<<7/ya p;Kw` k`Ȇ<.}Q઩Po@@)-] ;~Y, n `tKvpzmƁ 0˰ l j e0{/=TFp 0P[rk 0  R Z<-BOHiQ НxO;va5lq b 3m {a0^X]2$ %^mͫ *P `/re`gxt pF8@ ␌  ?`0 }S` i R: uwwlw0q<3P5A]BP;X< Bm9'e 4 @ p yrn #C 0  >L ڠLHm`QfJ˄ S)O5$QƘg9bBg>CXǟ},dpyc %`J{j>鬒HV`C`本EyG}G[pLǁ$G`AD([^qd@ Vf'cJYG~Vq 71f$6B$gim: C3=tPM%{fJBSX" #\ןz9 XVʢ] `p(&bBg@nE3uabo;$vǝ}6#)k!*"ՠ)ؤPqyQWc}ؚhA}ÑӠ xa(LIgsz Ő7渣Cιh ~1u`LAI"AZfHP;qPh('%@RcJ0qI?α.!ZTch1!{/ъUtlGRҍ B~ʑ+$)y8Q) |H?hA|yfGZp1Y R~fᣄ+a&,yPDB!(O i3T&G T4)ZAHcGya_E5+WF9`ptƠ:AĘ,p9 .(/>?ce1*cx W3;%ZJhą2S@i(Xь(.Up, `)N̎bXGFT$] 3unG9 0>-7 ? \VeЇ8FGh|)`ꦁ-EXg@ݧ4R4V}X1/ڈM TġPF/NM`}DL#1 %7x! L5'ı–y"  ]v(挢89`A m*Vq R-6-Au@jթΔ`hk1a<BKZT[PDuZ\</X @ AwXE찇ie4S*}\ "4:XH+8d}9~8& ;QM,L*X)ӞrvЇf`l;kG2Հ@հ͛i f`mPE IXHS pNG}=! 5̐Y@sˇq^zk7ܷQSP8VJȊ~88 bUШUdQL34@" H"rmh:tkDhWT wQpb/?;/,؇=%؇`S((8tx$@< {XӞ,mW{bvS$f+;q8~k =XNY>ՀЀSs"~_V. GjiXZtI؃?H @4rɷA8~ID82#3cUUDILPQIJ< YgxX Rڄ ;3IEB50~XAxEb ꚴ0XSruH 8]3҇y؃ ň[ARr `<(wSk06AK Y=Sl^'pDh̄f1sz'wLT@ H.S2V`!%Z`xxZA4R3ۨvWUv8"c-@Նrb؇|߼iP(5\H##*rP}hh#L!= %p2TPhPM7٭Bk:+{ :Z H%%y0BpCJ\t@1;Si1R 7x0-I{{`_i8o`Rhv B{P=xZR>-@(IcV=]SDI_U[_ V ax$Z3B0;;fٍ?H5Hf:`20-~H^8Hx̄ iR~332",~x$\ OpukoH(p 8hx` 9i :a4Fxp;^ޑu^ݝJ\I7kkhD} !Fi`d2XhiST~NP䀛omc__(eP=Ze\VE9 тPh}؂9SyYGP\eHYh@#;iC$ `=H H^XUA8bІz9L9HriZX%G?>|Ӿ;>Yc1Nw˨?o'ppt ~8srІ^RRZ%~XfR>=tڡ6U]P-[J,۳usńIPP>[yCJyC(?f`GӪy}x`/AU/ {h=!؁%HD?8xMxB% /"[I i YӇd9qT8 7({y1s`z8h;f2?4pRhHTpiqs[87{50n:|&c5Pb]]`իU^LʮeQ1y ١Sx0k;1s@~X[\S3 X^kX]I@8. t{HHxh`hhW=*E_ؘ;XRGR@9iІL8m TL-UjRwWUD4"˨-y6PPxtJ}RpXIEv,`$"Ȏu/p2 PhkWe(+7HG'w\mC8oH%JP6-Ȁ:v2/sp8jWmրyup؃LE8h(TP臐G YՇ8isyD*P_>tQdGj80GF)[n`<Ą1@,~E8Ks\ k`$mڴ&;vHoM0Sgʒ#xi &M4!DM^Sv6[l}{EiPig 01$"r9bd#Hݻǯ_ItÉkK)Ӑb7FEnY(8p`2ihD(yLZ- ~#!DH Hww)RVhjذff}D5iL1Ө Ӣ"70i"30=Ҕ /#/%HANÈ9t0C=MVD6T*xLH<;O>:N (rB߄"Ud^(H*Bd<,瞢1 -+lI`ħ &+`D<|d*hZ4c68O:vOk!aE)30jeTd >H w2 s"G d"RCL(LO0,PsN !?@TS㋌p|:霐A(d`W,@_OO 1y}s 23<}<;W#;*>3(RhSjR KQa= `0"uO& |؛ @` @oJ:}XO=֌}b g80r : G>,1ĹnDQatcZ0,bN(h@)*1}0D  b^! KHcX)f p#Bl`~vc G= #3? Ђx4zq~#-hF804O 8H,00&L` o&0qIS+i Y8A4 \pAB64q0,$ [ }"e(9`aҒST#;oGp」`H JP!c+ EQL(jF "D >Q G+:DD,2w(p[CBhtkF ٘5/{# Kn3VPR 5LG7@n`1B frT͂p UhY4Xj 7HѰ& H(c"wgD( qP5Y.xi7@"!aZ#x0~#KX|c!C&Xq?%@@CDC[$9C&p@@EC;T4(BH  @C/V҈kA!JN6`T 9GABq |>LA4Lx́l :43B? U=H3 :̂UC!Q=C0̀x@$(*$A&P8d:>ă4B(P8B!!c*C>܃̂:%4@t6jɤLhC*O[(C?PE@P @ A{L)(A$ B 2*(*:kX{pAqՍBp =Lj`"%HAB4?܊8H| E(T)(c;3 [[Ta=DR@ ݂9h 0 $A*|>9B(LSX+ ?d%>B#?v@!`@W8Ѕnp@o6"]4@ +})7K.kP]X́S$+ CA%tetQ%m;Pu),C41 mK)zڶ)lC3Z:(*ALiF3@L? >ă8`CvB1 (@4\ ,/ B4hcEh42>C/h!9@C%0³ՔjՔF@^EdBT煀$h*h @`@bC/?Og @!H$C*IB.LYEݷ0'¹T<A H!{:H ?A|dԲ$ ȇ`T4+z}&XAHX&̒6,, 0֝9H7C{  4@ h\HB HB4-$A [!R@<0_>C'܈#P#X(̂8 C>C0A&D5@9C d9Y8HE|< ̀ҩH59(?K*. M 14c8D> @4 'p9\sq #xAMC,m, DGBԇBԪ0!Tߩͧ9D[69h-͝# IB@5T ?TXC& 8)wc@ 8,iOjfóh)PވR%$T0+L)>g9REʤEԵՀD6Y0d$ā A!xV($CYdE_՝AjZ'HC 8l l,@;X8l:< '0dB Ѐh, t*4=#dR h‘ h@ 0<>6<|&("d*2X8=ԃ=<94C/t¿,O&5"8,); 0B0  >4̄DC$@;/D%d, iC@+?ȃ=+Im1Xf}FhBϤ(S;0E+K*Yb YCx0|q3@O/ڦbkPՀ,̂5*09-tB'B&Zb9<7)d\;#P뉙a*v3} `N-v B%4C;lE˰0cb#N4B(zW' ;D:Bt :w 8BRAO4cE%1@06R'4醡4xRA?C3x#$k%hB'hB$1☢M:O_[#/*A8+3bˑKQ JB0C4$M>,@Դ>#eJ+-3Y-5a !܄[\ V~{*I1c =72PR"N|TGؠeArS4*(nbJwÙ| IRekxI%Oc |2A{Ab#X B2k*d0 bD4L/f 2|fDh-rG@q*Zъ7j  D ) !Pp$l 扔z^m=ɁTCxi^[7AA`S'.U * + =a 8x0ě!1 2 M2S4 ̸HE)hb5LjPD8̶)3\QaA霉 gZ5ַRΣΆF TvpjKܡ@⊟=+K"*6n/B L/,ES9LݨF4r.[E$8 *X9"H4d )Ɯo!W甉5$''ܒg7Tki.+L JDZ M <5?K[*_.P[: X˰},61WEH9 ,ViT2gPC8f-`s ZMAT4'lSCI,[ Nh9(S(5n+Z:Qi1\e!Sg4?0r,4I  VRVfw͘ UR! , V@y |@$HA8E%BhQcC( *(r "<²ʖ,埗5idN5 yTeB-,Y $GH^:L7 >nF \R謤vE!Mh;JWԒ´/1)!wg),`z 1 ]Z^b \,ݥ#}K(,EA9ap'"EKV C:GJ{2P0WI[@Kf˜n'+ҘP:SӤ&\*ҊxrNf.:'{q GD_RT x+LbBh""QE)LHG A#U9XZ aRg:cǃ,2+ MNx; TCt)S x&T V03M՛gV{ZJ"%=1"Q2lT_ѠdFbџb\J@(N8I%1lNΏg< I!B}Ұp9JjДfa 0ɝ.a BNS#r+BG? lFA^ac 2L3[*(U"XBMϼP D "K@gVut2BD@b9=szz&ϱOUnxtZ6yϸ>Y"vl!{X6xeK("`T(1MpDd$ e2B%!mz [RV7t\ Q*W`wN7 )4pKP\3Jf6" s#fF2!i3&nIx,mNXϠYL9CBH6`ad[ZWRJ̩>h=(W[Ă^?eP|[Ta~Mp@No4sr Z2lF",ͫܯBaܕ 2xAЍBN ..A0a0$`?x%GIS|ӕ\$[Ye/Kx%\KQJLj&0<[ITWQPfnޫtWkm@jTϜcGw]v&n ;<Ҁޫa G3}5FB7vbjh)Xi4 پgX$`ق/D*K-ꋂgQ vGDV&EN>@q`xCm<gӖ+:G pGHtO]HURI@%S4QA 0MppU ` `T 02N@ nSogRWC'Tdw(Sv1zR G!Tf@rS;Sc,mtUX:j E T2!(" `  `y4Cc3%` @}..ٓpjMqr10f!wA0EA `р ˔0f)gLY@61O$9&aڠ0 CC&tEWP`` h8\:qRR'<1<'9%@!j@p` 7  pr4 eWKwDeKo v/B_0pxp]` @ !9@<5`"h͖`! _@_ v  N1ȱZ 0w;#){TD47QG%KqC"P QXQ \ @oK0 `  8 @'cJhqp` ڠ p @ jR?TRKG8 ɖ`rQ@Ӵ E Ȇ">kO@  @`  l+&[Y`P e`;N,.tZZ5,1nBo`Џ  sP`JGi 6Np07 4,` p z'b(G_[Kڨ ~Ec?`f!aV98Snq;61Wp P R  " pO|g[472@kpZ54)!HeO=BNwtQBPg%\[ a0XuP1&7@|A=b  @ p Pt{ l+@ 0E y=d 0cL! p`leVLtbrp{6 p p p ps&G,$,!@K'$4p 0<ӑj @S0k@ "&} Y50@  hs Pv +P 0߀ 'rt|Q 05"LP  `pa &lut y0 00G\ P Kl R\ `  9 | p` E w@ ; 0 bR7%H ePz<+&5a5&P @P  P '@ @+ 57T(q"F6FͰ 0VV @ @ = Ob5qH[`DP\ [ ` P  p `?  >ߠ m` ѐk9.:H @mm@t@ p I@ PuV0]` H -@+ ` Z>"{S),8xL@pm0kep P@ wY3P 0. 0 P p p pf :0O kgpO @ÖU-!V0aۑ`G ` fi&W-!E^;D ` `  A Ġ  V`@  tc"r[!Q!KQ`о^kq` ` 9YP^ lP pPp ٮ . t\pvT.  ѐ}HFp S` נ j@ 00 }6CR@ @ p]q ~ 瀑 J`V @oj} Y2-t+0@}c[Y0E \y1i >S0e s9Ig;[ P,ℏ "@pL\ p ?L ^V`OqSMtPrr  h`m@Ѻa`?L@I \CP,?N -&^ {"λ9DN db)R!sĉxnmqpaWcyѧMJ:avوBqfC0]ǝLe²g]L00,oIEng#+`{ju)ȫxd h0!xx'PM*pH:ΰ~p3se B69Ggg5?ȁ4AHTe3 ~JX0A!Dp1> h;x0ՠ01 0,xa 6``ƣ =%p scU'N>(E죉JAm#KonЇ6z b#x!@{B~B> pU^OdEg{3oC(DWQ`z܃At)f`/:;Яel#ц3#1,fY?pя? @`0P  h])9!}Cj6FDBHrd \"F fP #( [P#C Fs>J-N ̪ )8$#>L!8]ܱ#c=́ R”>; ^0;pw7ZQ12=c3=aT}eC䱾@00'0]0eԃ=ґ}#0J'q>;aшF0faW*vw# X>(QCX= 0PG?zA-=!}PBvf\x5R@]р@{T" >aso#h` zYCaFaN.g02V :t6Z`1z VfU% ]Y 8NK"`X[e+AT#x  C\ GkECjŸP?`9̡FV"() 7S'":BW&{S=l<F5Ru2 _s#E E yp_0q-$J+d%q3.q9 1A];QscMm0B |"hWÙdXa l@r| DG)Q[!s b@=az1KCg>ыT xH(RQh{@#P qՏSH`*RU}@5V|GQ_]WưkcH#!L, c^  `^CtPplkGx( {+1h!lQzPF::}CX>0P? iBl706;Ax$G;q'̣$4:qCTU,^E`HB.2܄ !iMRPHu: M.*. |}j4;X bug0g[a+[;aJ}pE>`p؀"(1px|phI:0ͳXy`O I٘~ht }4+:qP#JuW0PxPx&%qx\|§WHwpryb}}~Ȅ=@q_!8^ Vqp'p7@sЇs@bІY} Pkt(Zq܇E :$xx#IWsTqARHAЊLA5w$Z_ ;_( 47 P p78H^ vË (zz?4k؇ҕtX}xd?h *rhaۇY؇W,XIYmhDIdʦ,y%er}؈YH8heTs,~0P8'3KBi~hRIȎ.xXBk@; pځC'$8o@q)+LycȻu|w\zGx$WtM7.䇾$eIS2H˱y`0{M SpY0kq`\4h%h/Sx~x@`%={?Pp'L!oPY؄zDDdJHHsxuȕh@>HExxv^H8(8EekHfHPw|P.%[Hh*H*j I8-AB7 M[AdHS_z9%:5~~(<<4pP1p4 >u #}-Lt{X`xWxi6hqMf`jY~(ɀ HXl# OtŁpwwP!(Oy|*Vt|rP2hi*ۺ%mT``@*(ՀvePm!X's 5EHS7zp C=%X B!H {GV`2GvA3@KAU`ͽydP#Y HpA4:hԄwP夃{\S BxYuoȋ5 f}hrI(h`i MP V8h#gShLvV PQj֦H^М(-ڳEwhm\}=G:+ȇH$؃`\ ^pJSC0H. Ps`V =G/`P8%м4 8S{S^Un(tPSBH7PV ["]I3\P}O}3}{x/(h+xX* ؁s (^@w88KLx |raeJamC( A( :B*`\ (v}Ѐe-^PO`.7ؒ@BۂB`eD0\LXRi8v|]h^U@dUՄEdL0?(AS7ȂXx1?xh^C559hz28O. M?)[ID؇?@B%\L8-~GOH`!V(W+q ~8Yxaav{J7LTȁ{XPPJp4 #;U Y6^3}LHdD^|dQES8AY iPP;uN_P0 r@ȇd1ӱ64~`d}%#0-V`W0ioxtJ2W"k4Zm@+HDj5gaG8 eup!b|)2 WLYp!LT\@%ttI3(@$\0cks՜cbDQnQHdGNdH>x  }8Mx-JuHmyY}pv0ı35(:*4 `!%p#OLq6LCr…g22V}ZP`JM~HQm&HX`:~pbHLAL4 E\sKHp`̏.;,.\3E9n_D=B @0XB5A(HbP#}β20H0```1 m&iځдBāe48rЂz'CfpAGهDDX@pxx"A9~PVhb{~W~Z|-GLhTm"LཹT w؇.~`s<ځ PdUpǘ={iI?wQHa~"xF'_ `H1SV xv+~8?0t A;AIQ[(PMPP+  !pTP)d'2M9^#xGhF%J`uhҚe@B8tbȅ^`|\XOXgJ.PviPy؃xJHJ_'PhDžtT-o Vx:/}s֙7s@雦޳.E>yـp~b؆xa ~0a^+ F8_ fzͣP1):+;rDI?Kt[B.)RaퟥgM$PשS1JEl]=}D‰Bҹ]~đrW:Q`jj5D?bx1D1& H:o %O)xx4VHjUDaE?6PٳϷTRu떔Ѫ\MzlL1$l>|Ѐ䏑6w*%>/l׆P855޺u~ZL:eΔ)?ʫuق$e[sĉBwO^_ܣ 0DE (?0cH8M%H##2BS3 d@AtB%H:ˆ%T5hDVduUV;^8s ԐB 5q?"FPt:]TC4 d *DT=BC?JcҊjX*4?^c(y+&*:t(-n&lxYEc m  n?H،>-XcO%B9^O_O=5TýC9{ -A"2C?7آ5G %pB , hJ(l 4P-Ђo:8˛q&284 '45 P݈AM;Q r,uPA YFqmG= SbX3XXCy`EOCQPo)aw.WN{XctXAibpT"# OD"aG,P"*ю{Dt< ̣Fzb&F Px"2!`}c_ x*@1aR1\ea47 "4'WX؀n4M| /2ɌtFx)Hct+ 5b>p;čvJV+pfC?p;AQ9bw#66 mHAZb0"m 8?ZЁ 2(0CWlTe()0"<a ,xC/ PA R~@㘫lLp3(`@0' fM9! Yp6Hx`(FA ZcC2=Pc?lH&&kc`&"a?`A   m~V\,ܜ4d n8ya?6ퟛ <@r9ȊXC>lՅ# Ї@\puh0 ZF@bD"N1}9 A AG.|`c8(H8"8()I@HB e0asq 32ׅƤD&F R}iY x1 _OјSE* [3' @ =00 Y;p*`5քÆ{؂a +a eB &D>)Ң sAsM$0(9=@NA?,4QAA($5C3P94 E L!P]|C p@!. X>,PA@@8HE? /AD=C/ATGAT 4

\AA*a*°iAô%@ މPÉ#D=)!?)>̀G8/07 _!’  ?X8R6"$"phAK4/<8)C?hf,qHX/3Bp [*C:Xr5:R?.8BFY8Aф68U&/Zx 84C=<`@B'#x3TyJ=&A$p4%H?f # qv!?hNhC2)I9 2= E*?/OC1ASe?i6i9JhSʵ9":ur'P ?E>0 ,_k-K^:|9AaA7HC2)$Ca2 H8(́ x _Xl_ÂN7LC/'TB'B4$i$($A@>PB+ Xø2Hq"Xh<|9U<<6C 0u(0 B+P`T<1|):A5WC%>CD;x:U@^CK;4X` A ^T鈎SI6)T…K<ø,&R@?D@8=>5>bd̂Dx" lD I-րϣ+lB{_+8:|bPrt<` @AhSjq>tftN تB(<& ?|uP91 x1CN?`A)?.zgX?@ :XB B3`Q澋<@? ϼLƚ/0)؃>@+T%?(C A[+C= An@C0@\x sB ,, Cm9h2b#V6b B<'$8   @AYy$<<-C~5>)XI &Tr Bb;X*Gps?C)9?h)EBKt!j(@ @ABň9̀D $B=, _+öPB"PB'|>,AA 0@ñ>TqtW(AUC(8D Ā+O F,3L OBœ|n )75aX$@0 ɡɝA\Op\*4n,A33,9HDo1`8@B$B0L`4\h1-m <BzTF5: `c6QDY'HM0 (Ad(B+o;9„M? @qh 0 oMp"i$S:'4a}S B!hC>X dC>84YԉX&xV\/4+PQ_9aj!* >OY(2HGEEɧPPB?X@;Pbh!܁!\i? BCM[ f: 90VB?319ȱC>0HC>4<-: Mp VʥP6.".3CQ`=Dz܃9$-544H=crG%/Hà8HC3B*œd]c(09:C2PB'LC=+#%/0>G³IC郌%3\zB'4CvéJ;$ā(BC.(sOr*-mhe4ц˃,7>% 8ua ef898% M|x֣7ϓ#>LnTu V'ANHW]9??Vȹ6!N})6CA%:+d+w9\irˑ%/4C3%?x%ti?*=7,^Ndڤ{!\S 2+3\ȣ(= &> #C4e А9<)H < lpb , ê5]yUUzZ4$-n$ e10$ ̰S<R0{rZXI06e\cQ-6lͶM rL;dzw } ;PH${tH3xQC $& *@% U yUF(,:9dJj],G, ڵf_uDP:DK:y&–E̓p<ٽTXk/#(9LҸ.`ČBN!}m:6o5$/w[sOt݇h3#4npN pHHG8@PuIC&ɑP9Y(dG**dW+f\e֘a\NYMqhRt/Hf̰\jήhi%KC[mȣ| :K{dh/{]'Q)*RbP"UP~ALes`Wf ܅v=KKU)&>)`Zete d X늬A Zf KlFl,!]z3œ6: )Siz6^L:q31c=!B.I<9y>8G! DGi9ʤI|@P5\ dr Q1݄Bɾ9G|tP%Y 쐎aԒOO,4IX:c%-='7I LN2 C!ΘrS]ssT;%6IH!dn$H,9aNrk觐&$ *SKqd@bJ<6*Ŋ,DYUe6'jToǘfUvU]J(h;Iey"z&s&Pn)h'59m1UFܸUBquZdԗ_чTrӼVkf} ܀#`\oV%qH` > \)IN)߉hŤtHƕqHUX&yo0#X&!SHT#51Mi9D58BX"HF%|]%DԲ#5|yjU5g?6,sW=@K%! b(//‹&0OTA(f`20+6âǝsơ\R2$P` Q"MdtH60'!PZl"I98YO@SD{.&?W"m.rI0߷>MSC\c?=2P06TƀsKW7& bq kH\NEzF0Ja^b#%aX[D R.,;RJC= CfIK {ea&rnrcD`g}qa>EY"SAH4qyc.s"X>U͞@I,x@ZetHY%p tnZUFPƆlM= C/PTB*cL #)D)RX !'JV9ta-ꞐWu$ЮixR <1\$hV ;y z[xOW!p/| `j#Xb}l_TzR QbȼphcP(Ru(ZmIۢd H؂yդ@9a!9 X蒥&X 7,iWQb%0gM<5]桗~f/AtmZ/CT`B}1J \gʤ3CSS2{N1ZŨUNNG Juø"Zb}xNo"BKJ4=q7Dvl'Ҩ ;bVb"=j''PS2`xKr0aQ|0>J17JLQb s@DoψF"JBhZG MH"ZOҌE*;dD8~Ҩת7Ǻ%E/P}ƈ^66JV&*׀{dNTb~X&NTX,?ŊLmI)da16 HT&Vݒ$4iޤOp'%'N? ,4 e0>a 2̀?aiIzX !Gm1Sn'zTL.NQA'`(䰗VB~al"^D<ȼȨ8p# ! 5` #"8`' ;fT[7$ZUa@ @ P A,2HB1B ov 0 p3Toג-C1C4v<5.2JЅ]|M`Pw&рpP`H f/i//kg!k v0E?M p 0?qP+MH 4+[[ H$O[l` ڀ 'mNuZIj @ JGIS5R'VMI/fi;^&k.w 0J`^wĠʀ{ Pa%((@ v` RT7,ku_ 3)0kc0 Ҡ L " sĐ*T{ V #O@ / /@  `TzrBdTi^ ` 1ByO*h…T<|-;% VuQ` (Ts O`F` K@ c'@ tNƆvSw^%a# @"#*" "&T"11K^$/+"@ 00 [ Ͱfs"%,zVp bP4QC[@DtaE45 p_L'(R2sX*sp`"B1o,T"F9I^Un *z P z 2@ @ [8Z@ g -qO7*3UNc|j` V`@ JVw0 0 &k2]I o J J+@@ZQqoSp;B^v>w00e0 *t8 .⡝$A @W J; 0_@"`" fG[2 ;!\K01Vj@pPaPXCllY _ÔQ j' _ Ұ`P FXq8Zp  lx[ c0R'0 @s nS,϶Bnr"p  P pP p p R0 lX%T2K:  si-`U{91j.M%@f Vv{ ?A  Ds oA @ڐ pewXap PÖZ j10e!2B!!0{ȋl2 1;ZgI0n) P P upp Ѐ p  [g T*0f. f bw `@ ;454U jk  ̠ ypW)ȫ p [| @>@(+p @ 0ey?R&1  ?  ۪>U&O0т/"PWP;t\u0P 0 P/0oH il & Mh!` Ҡ $h Y {L-ְSPS NB1"6Y _6 ߐTp 0 Yv1e7AQ8Y ` \V@} [%0P"PгƟ 㰽 P 0 p:pp _  q@ p50 h m@g`݄  , ? -#Ũ eA\DcՕt%j}` `WAh"plv;< , (4(S! YQriD ^ {HiVPx[k@` o}# j#Z Pŀ ]@@ P` ܢ 檠 °-@avk0t@pxn[m S Ê oWwQT'J0DXTj}x İ -ϐ0`(F` 8!u)F[ C  npF p-^ ِ u` 0 @ Ȑ ~g`'ok@ {L ` `V`  p `l` ` ` oM\O Ѡ ʳJq j]mJ AM @7w=צݸ -q08R* Su)| %k' ` VPF>V `PUP> _ Ő pm,` 0@^~ P `t`v&aխPb_rq`0kpJ !2S4nUsݑ#_D5wԨ@,F:Jۗ G,r(;e8¢eJdm~QrDQRGMRBڴ)BxjS'JZD韥Nd)ujPIr*jx7oZ|'1 y6AؚwWV֬9sΚ{\2-lSE)~LI45ୋR˜4'=}kO 9"6H9z! 1~2iXgG~rZb [.hCF*g~܉‰~pē4䟴,"$1%湫}|~ه0>Ŋ2{f0D~9"馜bArT@c矻GD}9ye!f+s%kqg.9v/`%BrWe5V-&`b1Bh#5*A$"&"OZI'9ZbxAĆxP1 WHi adltQpmi1~JMD$IMB ~>D'M^Ї|^Y~Y{qgSx {,Hm -'b,A5z}Qg"D .BYx$r ְÎ4gX켘d9ym uX5HX9(!&0B0 I掍 $(Kw$kx!uPwkX!.qcR@bawYa-A꟦H!v@r~h9^d䬰"BTRƮw'GeTREG-Qjt(`74U343q|05 ?za=Fw4 e! O)x;^`E: C"F"1QЪ|``CsC ~ 8 p+(.'X' 6Ԡ)/w,X +B?q<$)#V q`#b=,[D$1$?H&, q VG/HUbPFrh H68h'FEc /am#/?ԡph99G>ᏺ ߑu#9Ue [gP,!rXcʈaרAA`Q,`(H 8U+!H q|c7t\ 77Q0:uk.l2%7pYBӐksxh؆4V1uKBnq,B W[18|(i0;5IX4&8~`ba>}h9`ChA fk`x UysF FX4i^Ї;hSm!|ȁ./(s+Vf`I8X$HT8\F^0UEw {{8qbXNeP$@ \BCG9RhRP_R\-Ѕ<|2EO@~KDq;Cm&,KoBc<p7I/C1~Hh;p7ಂ.Y}(-O~Sh602XBh~Pxhb_XG`yu )H.DHx/( ('@oi7HF{XvNk8!(f{hҜG;^krP[x-qXzS !+ #+ІS_J01gnzmzK@ ۦZ8۰<:~XLĠ8I>pB3kph:(%6JH^0ą@bQz0P{h6H9muEϋ{WH(al8 HɄ`x؇hhLǴ@hD%pNЇu|I(xPPo^ok@FDk~M0%.y7EeT x8I}֫TcaJC,=]2R: ۸;uyCp~5(9;kI z:8@;hk`mhwRM\YAJ*%6 }db0IT#z}rrr0$.~'} 5UX6-`}0C`HX@uH.YShtMx ^ L DbGI8ЉkW`H$8H2p ZTKc:,]4 xODUdZLOϞlCh[(V2Mx3{$5480q&VǵhPMpM.}Ї&}pe'X(ISws@% Y%fmwE`ЀetMR*z%`[Hp 5Lh0(H(( .m)^շ.Z~kaFfC0 0C>8YAJ:QF;fö{ p5&?w=yh_ мvNCsDs kQ^W4@XSEx-DAP00R9Gy׀CM spx-{0  Zp8r@tC=IL5~ `_f_x`fav `kcU<@ZB{g~wN\;X=E,bH lB Eբ?h$E)$ 4I+ &,2Y?Ï0@DJSlc-@~r<4G'vO?kUWdUVaA:Em<%t(7MS[PGAr"!Pҋ9gYƏSLa+cO:-ϔi4q&nգ5Te Kӡ65#,J "!8rO!فKS ̳#sB&X)oB?8Q*zp%qҏ_4S2\>?BlAS_*'?ctQEeT-bR!0X| PDȓ <6l*Rjx)L3۬S>lBŏjXAs;)`XDJt1;sS';ߤ-< -D?S){h`š$0-ZN,M #?f |2M&4f=@%x=r%?cPO?D`IC?M`}SQ D I@yVr>L0ԽBx}"[H pǤq BA}g桌5 ep KBP(c;ģ)b"R0hG0JxЀŇ`4CՇQiG2t!)A $̀_8zcos̀ HNt XcR+`A (`pϰ>Td?C,Bf0QAAڀ6G&q ` b'b8䎃|~@ rPCģxc) 3Hb>K0(,HtapAX ;́(HUҸ a0A @C1~q F)̱280.EeA 94F>ML,A %P*ÿy3 ZA48 7#,(*q *LЈbM (zR> |p@|CC R"#v r^=:!aH9@2`aUA; "5?@!Đ! ; A ESdM6ǥ20~8@ яU> G4]x;[@@̱PHA< 2g}mX^!< C70)`r'uQ z= ־ñifW wpDf DYF"=(*G4!0-udX)` ~h+H\ )_8C?H Ӛ6* ԦvuT=CA;zSbܣC@=?Cpp!,iЊV^Gpq#fXq 3z5/9D KTWf?1lRXbx5#!@"rËrm C]^>SvcSD 0\Z 0C^=d|`E+cT5-m_H)ېJ-{A 0H0Lp\ S#(`(4&R,H?X ^L :X`%`X$0C !, deL"P%$".XC>؂i(D@e G&$>Ԥ[C;;@?()`"&F) )0;8?|C*A**ϋ?$E2LJ #({ H3b 62,CLC=!#I2DC4*@$B49jC?XL'>?4 ;ߔt``S ?C 8+&De]M@ [*xԃ48B'4D"\ D!OzYJp ,C+dÜvx_(dS<8 { ){EQBbȎCt$BD1WWza׈ AyU`,x<'X, H?DC!X"C4BnQeДL5C?%YZA#9ݜ-AU!D&;B`#" m" 69?0/Yx@0C/ ќ;,@$|'xdC>CZCD_E@?tgw ClT(U_/$9@1098)DC.O-OW% l{_J J{U<?.PB B!?ȃC3B*v|j(?&j0=Nh0W6TK+HȁĎCHi$,@{?4A(ؙȂ>PNQO9EW-MQB:CD>4:+<)M/)9.-R/B ? xF $;|=h-"TF"t9C@e8B?C, fud2<;jOF@8A@ohHC?­B$@ ? p/BAZ!~4M?pl  @tkey7( YVB'hXف9CXpX!1,|;>܃-Ёb?H?,8P!)9h@/pA$D@Jd*wZJ\ UF 9Ԁ?BP[B !x'|@!;Af@ GGpq j2|"-7OUX 8ރ,)V۱1;lZvXjY T.C"2B!, &>~r4U\C ,AmC X>nd@n3Í"цPe<;B/C=@|:<S>6)x>Û@$\>|"+("^DC&A EX6*+2DX6:kZ+|C<;x3҂!@D'$C;,b=Cu K@hiB,L;C' qHC4V%B0(%7T_3&P(F0H8М);>9v'p)p" D3dI\=--,|bVsnWyC>@S4sgO\Aras@+^TF)As"l@c;yF˗sGd@$ J 2t@ 2(PK.e#A\uŪSWNo?os,KRһדG8Ǝȁ!9q"#$)șwiՌWC)3D@ J)2k)A*‹ifG iuJګF L2J:J,0O:$\V)lBsz$P $L,1O0ѓQd#E2c\J.=MMwĮO%D\8y'|2.Eۯ@XQPHZw DdCJ)PBJWU/G4!F^Kgs9,EJDS13R14%4Xa\SSLrxW$=LW"2᥉&3n÷7Aݑo9Y飏BF-@F2ZTHa\? /V"AVs%*13w5aj6 23Ra x̔!͈%KcCD138.)8% }sJ~vPPFRmMBYIuzU+o(UV7AH)W d V]'Xr)CBeE`Q*1hf5cb,K@PUf)Vj Ko3p?ƵVM+E2Q&kOf/^ Lgc&0(d@+OI Ee:CQ8J#R\i>Wyꉡs\YJ@HrE3Ën'52Y(a<~xI+c@˽Vr,mRא6Gl0KR]=\8n;#=1x[{&67rRl{1aZTШH N;tJtWb!J+ (k=ʋ ߬rgH4`FQRj&8L%fNa39bmTb) n.\]s\TuxM*&k"H2TD&RtЁmP fbT{㛥 \U,qHr* BPt} d#ȂWhAJ8u]a-,L^TNMH֕ӛ+M2RhD̋iendQωj}ܥ1DMQcq[IjRCuCHNdg\RРX)+n*iO۳BR D$39Bqw i6W 01NYgeFsgpa^}_LJr# ! , VAyD("D H"JGdcD^|P C <$HpB[B6[xΛlU3 ѣr$T9Oܙ#:(P jVCaBkQ!Fpuϑ%(9қ߿;)NBIqQ?&oPFY֜gVFʿ O.9KcGr⿋i67OdyIPfNt4*jn)SI#_>w~BaU+Ű_׮}6lYPd k#$H%YbۃD蠄}uBI'x`td ffYdXdx)8+lA[dBBDEFi8Pk&FO܍AAB2MOHGSOlQ %bVQwr”{gXBXHY{gm(h\q%! ^ %h2&fa_Rabe]")aFx*2Ք\L tm+$2"$o֫&qH ܏ q.dN?yYNAqY&N[hGvaSl$R1TAEsd%'|2~#H"8WafI1!:*b>&bꃤB LF ͆mDFD=w26$eP&cdnN.\;״W:^h!Q=DEvxwI.PIT^iWWHg(\˶g;0_ Exc*<*vhex,%q;-b~.eo.9 2HiS4JҖ. vY@NtMP)T"٩]Z.Nj˞ѧ@K%. *bJ|$7N1K*N-qRB62V!zR4Jd2#rRp## &Iϔ#P 'JSCO6)CVpv {"'?KlkX-;,[[61B/#W-1/h^(!BRQePhFC* .0EV%9Mq(lf;@5n#T`C+TɌVj(dw#ײMnhI˾}~N4 HFT#*ϰ,&;Ȭ)FYOBɜ!he-ymRJډoÓ؆UUь2\hULP6)]xduݕ?`K#ƛWnDt<CQTcB- +9>IN`H|xފx( Xd 5@!kAk, LnwƈV|K!m0?: tJPb-0+W1]N'@eJ͹Qj $CB:s )#Mud#Y 'v/T[Ƽ:E%? $:  ЀFYP~KaW&EN cթ510.T ۘa4,S!UY bu Q6-lJFBЦb<쬉mi E Rӎє, u rG; 4ыScK!2p_!N ‡Arj)͚*>aaamXLgEHLSG !&F"l!ZIBfrs %UP7ivDSGL!b6x,AhAD sX=AX*L{45{e_6|A PK$ y!_y>% C S>,5*L1Akftvf`=TDU2z$+2*v`@ sHg:qA"4BC5&&\".^%` [gs BG ~Wk6{DC6uQpDDL7NFy @ RW4Y*Ҥ883zNDZ3G ap  01sbFq",41ኆ-6!;9́O|;(n'OXL  `]` |Gسc@6^}=Bv r(!LQ(~ 0 @ 3S[eesz*PlfvV`aP =2M F'% JG#;gD4543Uٱ 0\Q@`P0  [H s` @T@ ӳ'tQ 7Ѡ  puq x~!)HKXD ! '  *w"" R17`1aXsY  / {0=ёTr3t @T@>S;@aё%6OֲHx q@0}}VSqv qGG@ ~߀IѰB` @ Pc| J)@fq6{DKy}i"R Y(g"y8 Z{{6rS PP@/ 0 ۴MFb30 v@p%R]?A3Hj`   h` o0'Pv& K0g5 r  ] A5 gCP 4dPt}5RFR(җ3 ` l3e0 3 E?8R P@ pp " 쀑  1F1Wt23Tm{%ĥA":HF#4Qp0}e` S  .1I}@ gpvS ѰԸ@ 6&8 Ws 7>x(qLY/XY14[l.N truP ؠ uP`D @ "KNSZFSgvPO2R-;| &W5ar-d  0ӇV &s0X 'c XX p8 pJ(RQo4  K (t>v3!B8s c& z 1_#C<  P P P X" R / PӐ 7;:߰ @Bp ڠ  2Ah{;`` e"BqHj i ePsp 0r0pp   dhH)PDbcA(H; *#e RK R2yL !, 1ZR5rAnP P@ p` \ `/Š s1пop`0p P%  0`b&ѠTp q*6Zai0 6P~@pcL 7 ;v B B+C0#!vDy )qWy ~{ v0ؖz* JOJ P`P W "PG ` p f20 `_ V 0 p%^p`   `I0Q;?#b&pPx p &ƃ.,tVk&Y!` İi'g<ۥoZ A+T𠎠L$rwqƤA R+p VP Em0 8gY P M u\ $- )- MR`΀5@mm@m @P{a `k@` [H 6` ,&л X<K-+$]^s'\C16"^ oܬqp6 | +, K`bLX"ysA_ohk }SeP 䰅C-Ë1!Wo|u@] ȾP p P v~ @:@4nt ~Jߠt}Ā; {J P`~զsP4: VRQV5<}J'w@ _oE[k(f tۈ1Ŋ 5G$E ( 3 v[0`Ci @PiPaV` `LYα^_Pِ +"P ! 絰@f0 }Jvg`0ޯ ` y% 0 i  m`Jp#o``q eO.O. e_iv Z,/;|?o S ` q دx/qWp` x"a!Kypig  oPm X`` `pS~hNaWPP00P P oN q^ 窀 p/rupP` Spt` k-`FI5tM .ʔ S+{W\h5KHΝ@rs9$)Y(Н9}'N2>elX1c'oHo?F9Šҩ^Ҵ1cUtjF?Kj-uj-)O4QSNIՏ߾~Ǐg?+[W~mKEh/^qQNb08اbu{6bm̗ZSEoala 4V;vYҖ巰Gދ^T.:`$矶}6Hc "MyYG^ސPIIP:I)%4'!٬uPQZ1XbPVF~$+Jh} Iw@axz'J4P+N鄒F&'rtyǞx%ȱb [^fݡ<6v*mrZ `Io,~qGq1~0D4BE{-F+;5CP9g2G5Y5p9B{!$ +ĝ{`)xSq!gM9dr'brǞ`!F@!ZahKXpaϠE˗>ܲKOBNz .#7^q,sHTNYfYi{% jCrTcSzQGcA~IE5 a\RaD; %ְ5g\(ɛNDcC 6g@ˈհiAqG)"oΩ^qSC:f'baFy#9 d_٣XA^ P@)-b7 ~Tˑ)euI9Pfkl+J"R'tGX`S??e PG+VAU { `6GY PTժa c@c1fq3 Ai ?#bq{iϠ L=ucc# Xh@ p0(D WC4+ ,|ܣ +@J B4qHx܃3=VVh ( vij%L䉷bhY@HP1> b;Yiri^[ ~ ޡ$xAtcVG4ChN;4D?Fb7zcs$͙ 0B R"P N6zb`#ƊFWWW \jB}K\Ԓ2.$/?R\~W*{ 0C`.AP*\Bd?0 (>7ۀ* CPV4D4 T(X"P[<|3 q(ws\ΑsẒð6`D\/bN)<<+CI,F@AFlD><3혹@69}ؕʑ/yҀ?wMh>H}X2bf \%o{HXF= wHymTkFk@$(`px}0\r,0M(@KsXxM8Mi袦1~Ȅ[j9rp{.; #!DxW0` ~І pTpSp(ԅ:p(!Ѹʑ-LpWhD-5PLJ>p/AHX.ZiPX`JB[uxg/02؇J0}kX5`zwp4   t6^ +Ryp[H0yƔ)8- f915k'p% DHDD' b7 T7؁T2@`4^01 1! h 0%xLV qHaR0G8_X3'0U@|UcPU@Ш`D<99P(Ҩ60e y8Mȣm5KC wXiPFkȈ_Xd8({$7rPGt0%5q*RӤR,M#pvȪ* E7$8-mІ@.`@'HTT3H}ZTwԔ V7Uo[ _ x_@a:ZZ0U[ې>P<#DsHj~(~AIR,EG5SІ_8&(4чv8( ;k36]@_  wP8 q 1c+-(yp=7eE~@1M+z| wxeȄBFh;2؃.'@Nw[ zJ`^Fx)UaaEc`U8J3FDU6h#4J; T`ЇAPOh7f{3y(h 8/85x{wx(肧.;yMxw@'hQ/n>:0y>1M*XH{(}?GC8k `^9́}[8vk'/0jmt8@Sށ0 S8XIXZeeHGh Y5Kx[Nf[<4fP#~X2r\BĔRtyhWwE{x:0=.|?^!C i`` @q.8AkۃLIW mGwhۂje@{*Zw؇z}kS.i&ӊS2dڇtHe\hs Q[P0+Ru088hxH\`MXVA R؅Ga.켥flYUIF"77!6hud$Sk 6S.Aw!02p/z; *hekoهk BHh84k2ߦ4^zm4p=`㓆oІpX,|A/*XyCtbqh){8`T8RORfx\蒼~@'&i.1u^E+H Ryd]xb FMm8V # UP~kfGffeevQ>r4 P(j ofiLxy~HWIiwxEH#^( #2yxgJI0TBPWfH$!xq8FbO( K IyWH9H)+D`9kW.?z:8ꇭ89~W8qE  R(N $K"Ejժ`jՊJ5jب'⑪:U5[8keΜDM„i>hdB  H `3;CH9R<5[W?^H[FΦ}ʬ;L0k .5y \yIܵWP2 'XhC (dȐ>HA9 b{5)Th9bܹ#GWZ/,~':p4py4fKa?s '-^B%#WCJ`<@ذIdKJ( KBlL#PBJ4 JQGab$:1SQI08 V %^xA;vM24G*svO:kX`earE:H |p &#)0[ Lh=LK.0!tB D>PB0# / 3 #ѭӅAAu0pRyx9d$ QpN' 8TD- '8")?)D.CESpؔ(Na2QK&|lA= ;8H \@O@b?X*(ӆkL1sa8EJ߶s75?0B ((A/2!3ϥ#,l:C # PAs_0XΥ8 *-#xN3h`'P6 %bgO-pJ qHÏH ){ K*‰0` E#(ʼ.S Ԋ 3M2Ï7<q(rFS1E\@m  GhmcІтi%(AmfD:LHG Zx[2BXu@* Jhc) 'Cي;0-Hc X'@?J # G X@~m2pA'#\h*4vDp CPļE78/BT {C^`!~}c!i&G0w,X(C=5'I V&,! #2{CASFP`G{#!TA eN @Bz8W1>2NV*A~("O4}Ї4Lo? qCG?3e\cÉzQq"] JRb;8! 0 C(rJ#&@HE"Oz U%Yr [?16X%6P`4SCkCL2X ?%< `P,9Yp(` b4Ca7qĆm8JCfbG Bb8gЂdH+@ ؏4Ⰷ?ܑ ؠ { F"%h]P1ȣ"K{Ą=A  ܀ Ep@7Iڪ'$ m =wAȨ` tXC4 YA!XBDa;TvD6rQ Kh?fт@k`7h g!PЎsX!N@ .7 VCt@n;x0c߸>RˏhoA qP98)DԀN8?Axd]*ioJae p105!ҡ Sġ mІTXAL+BPuǁ7,Shc8BV•qS ZЩJAwfJ!TޤpB"F<1VxA}R l@- %2hC(?#.^H͘xA[@(^YA %dB;E2!9.ʀːt |ͦ@x# @"78BvmXN d#P)(Hc)Hyy@"\ ,Tܣ?@͉9?P4??ԃd<*Yܟ;P \=C/h<[` `h@U9? ,1̇p;|Ixء -Ll?ȁdU;xŠ @0AQ?p;rU#U^#>|/Yɘ$! =(_?La477 A,ڏB:8CŁvB' ,W p$D!0CG!1`\XB?B0DLs\uTB"51P4,b0;D>GRA:S/BT)8 )(B3D4 6B* &a ́*?$$<# 2 0 hA@@@.C!EX?C;C0p*N ><+34D?̂@BR- ?#B%B@X3S&\*M 1ph ., )J~8(9 e<'/ Dp)Y!%'4D? R)A +Ȣ>C<9[(C'(c6DH>Xh--3<9\$$A y>B ¡z;dL?X(P 0*hFB,P <],exB9B?AA&(l > 5<âBR:  l23M 4B|@c?8: TT "i#/.^LH9?ځ$Z3`Li:,vgB.1<`X?,fGnB/d@.¡C*́Ɲ>A < @N-* } Ee*B@=\_˹Jh2pV$;EF@ C*Px@&̂9ثAH@hB T P\bk A&Iѹ<(% :wHå1?h?x%PB**0j ŀB4@-98A<A4b;i@4P9}e@ p @@.CH:lKM6N%c610=$@ T4 @?. Y8 ʴX)=w)L;(?\Yrl؀d)@$P @t;8!$ p߶R$(^>C>hCt$*r@vB%\_"xC0A Tp0/e4C~E$A x@0vG[{?)$$ti mii)C/4D*l,& $< | j@Ac$11L^*Cp5*lB&O $C㥒67#4YRXA$؂5>C3Tj'x;AtpGB 8~S!P8 ?o;@C(. u UǓȝ@*(5%%AT+'(-ZCCr&he9 rxh@ ,84ʐbe5B -;No-KK-igq'N>j˂3Û8@ ,@8 Tgg'=(h2ĂdiIAv*ugw23d1AQw(@   @!(6+5A@ ,,)5>܃(B G?؃4J"2t#PB% 'B=9@v@9T< q"ڔ8XQ Q:b>>X+@8pY*9-T*y'x2),$Ct4B%!70L\H?/B{ЙoN]C&8ԃ!zg.hC4X‘XJj %"-=i <(C$x_l?:p,)?CG_bYC3Y'PB"Xzt:%Xot8C8C;C;ā)\)z[&==PD*$<ƚ񄨋-i;&qclBJrR\C/8ϳԼ`% B?<t/h;̩KXmC8kY /PA켑]2:&+Ln#܁ H &B .2B .$Oߺ%B.4/ӵ=ԃ(6S<| 1%Jsz'$@Np ՉS>{×Ov~RxSy`oV ,VUUlȹs ;ȊF?r7#\w,Cw4:g5o2ݪ*ݬK>u[u*UO8c5jC -Fq*TРAg- PhF mh6$4lG Q*T(Cfĵw?'-kG j*8*TNyɒ%OfF?E _FE{^uIQXi8V|Ze`)jVAJ -|Z diMˊHcR)Ô1A:9ACZcTCIC((;; 2 -bcO<-LF"ḿUl+ ( ;dN('Z'NZ:.TB9%P*JO\F!eRRi$XN=u( ©+ P(a*1f )Yq- *Zj+pDkmKHVQAX2ДҲ a$څ7/8A#4SPCӑJ줄J;K EOB!52ɼxSO S!@N]H1wZJkG 1Ŧej:٘CVejMgmY-iQ9j 3/[24R 7Gu0]F 9F(6K\pD;n;LT!L7KH!šSFԕqVMP 6LVVk6V7j+,%&RyGTr)Y,AcL-,MAD !SOG _~;pc[1e)]R CrRTPB *UJD8uL0!ZMhi lW9eEE+U|$kG Dʆ$}e {R!TlbE L`mnC `Eb U)Sml) *C27Ǖjt@?NVb06‘R唭F/@SpՔ+nʅԂX0[زժb02lьP%f01gDs,4 [.${楾axطaگ;|ߘNGmǚi(s Oh-IXA`B%q)T@RAAi u䖦\P2ˆF4QVQ*hzZT|@xaK\C|\ >m?m{EDK}7ٶF2]Fĝ&M&0 =΃ GlaǁQ@] ftd82섏,j|b:BG歖^h7\HVZT3G8.$8JG) a{XDZDR,jC$H[WhQ͙9q{MDM9iŘ~ N"_LyPU#NuUT] bJmiUZ3i򃮓zh!GGr69XNtWq%} "HߋlI{ҙT8;gK&2,?G4Op3 0hš0IhQ?[2WlIVSA[5-%**zHXXO_pI\=RH9JIWg:Xr4{clHDxݲKqM6Lf= Oyζ`rQ٩DCWĶe9pCŦ:PijWX:LЏcuV>$qWGV?xIC`XCml+e5p{aQLԮ6O]9㩧bM r`"RK$ZNё?ʃ*s"+[q~OXSjqV)TcgTBw-Gz67< f{Ol@+Ki q&Q]YLmJB]?O9*5,:-Ob`o4AqM$L"R6$4LFA8TJUr.A8! , V@"I'HHC(DŋE421GK!I#!"\ I-O`eMlm†͖jz e(Qr$'S9w/TV ںР@y5D@d۷uD]wQʷ/%Kz)Q4xPZ_(R" yTe˖O"u*g(4ieiB:bD"kF`suEKF$ț'.[jl9H:mڌ ?o/hO5رIFkh}];H%[ ?cs]ŗ%u^ &`u'Yb8vd!))() )E-n@@(F QuC4hđ@#1[o Pp!$N11r?8OZ uSD)H^TMŕV!w!V %WYo!%ׁxM(آ 6jIbya(&fɣZR'dqvb U*$s P5 .Pk9Do#V+jbqTM[MDMj%NaǗPNafvlnaew9'XfjV!%Hڵnݛ]?&_Ahj2'9fي*gF='JOCP!B%jM -9TcE&%s5\-t<݄StG eTNQ}Pr  &!z] RH0mYr`%v9"`HuI8?' 'xBi(T1&'cggZʹѬJ4䭲r+6WP&\A/ T&^IukWawTVetbVZz_YvՅ7];rp]$`f{c.d&BBDUxӳ86z+V nx5,&"Mbfy%JX S<3ٰ)}VސL%@l1D BPf۾좉-D\(] b19RVf$.$`FUFh "y`Z-sAch& 4k;ֱQ$(%\.*_y{4 {^W8bo_Ys(}z.M`"64Rr PsXE*VUF"ҫ $Uյ8I"Vl$zNHk;Ydy!eSڅ.9*Z7b-KA-aoQ_4 B-ĥ#LqQǩQbR8r/q9;1$aHhp MJV⚄%aٜiYzxCzxS(k*,SBG|PH)ԋpLHI ClyL3&ЊFAlƍf*Ӥ,C\RB y@`:4YHYITNN4qKNSZ,/9޷"𠧮LĆf;4)OY [  2' 7D4bQqЇD#NdAIN]_Fs`E#$AG$$oSȤ9IhQ)XbQַTQ$uJ%,FD` H%$<>L!ۂ,#k8'iTGeM ݒ'Ĕ$MaD2ayİDf7No@rTԴ=;%^ e+ 2)3q=L52QD/"f4S@x3bHlVXI9GeF*ozw %/B΋_zIIYwҥ)jv" V2qPG*vD(`A =Z@>b()|48|iCmJTϔ|(ʰ}RS(f1  r`>BRvQma>ms("7q UTLzl1s 0 YAL,"+{t{\hD2sQQ4HTtO4[H2V\ЂROve"G ca.P2p2/ ৎ YPfO'2u$ \bPBfE͠5isA  7 x0Y4w?8  fmM˒^ʌP0P W_   p  ` +@ J"kxI ` p Os^ "AIUvCcG ` Ю0 c5 <`ѧ &  A pz}b>8 w LUz,Ehs)fbSc6 @& ˷`""1ȅ @P / z P f`0 \ @`H נvҰ ` O}A<SI-]C .;kA yP> p p7` PL=wK^s#FG;pҭFE F,id,Y)'MBӨPْ߼hzb2`}K Sp'(9TXd?uԕd1zǡgA_jnoc#ꈠjG; :هRÛ{{pDPÐX}#g^Yg~9g\-5Z-J $A Jc}G(XHa:S`' DPǐ*SYgzǞuPVqdmNr˭:2$}pMX‹(~ŊtI*^XVRN9F/8l+@ŁbAjY#*ИaVg=,gQ$~'rǎ3bœ/(A$pDvYu e %qYuD 9֙9بr;Pqf!9᲏x~haRh|X 'lax3-aSH f kkSfQ< UMiu81%T< / I52GiZVg{q8 r#o`,j+b7#|xA| 8حg@Ïq  ?JxTF/;@؜WEax( X?hQo Q(9щ*ja[^v;Ѕ~4t!>xRT jpXi(Axh:NCkD _8xKaml{h7 t>7ueOP>pl ](Fi#V~l@*G<n@H3ح ?qE,ń(\! L_O~`>p=ksS&,#1s}#9?q04&L%bӎZƆa-n ڷ$ $]Hя!,fX8 %G b@ x X/aNG giVNv&ɡ)̖8nx &TYp=o9^! [?md?BGBxf @^(j3­ؑ," E`7n C[jF`S3-!gNjrv(i1aфEh+@ `4_*qq@B`qXM  [(< *xa iG2q|C.zk %6܆.H1Js W1fhc bqBˏ}x?(PtIxnxw-o)Bqjv+ж.zbo}1!u`Cx`<2CT s D)v?aoE͈F*YBg? H[9><7Xl8ҭ* Ab`6a x5Q>t`G ሒG3XZk\D3arrKl`sPH X1htSE/!#L|ӢpQpdxy*hJo$=nY| !Mwj!a9P˺RdLZ6ؗ3h6X~64@О; 08ЗzX`MX^Eyyh}^GRH!( ,@!XAePSA@wHX((4Dyi҇Vh@h{0{*{ЄZe6xs^ˍʀy`*X>$R~b~M`pWe邮b{舰ty]@д=LӴrň$uj@@<Lpnc@@Q {N[/ 5؇`Qᵞ`~(0Xw@x`#fOq{Xw 5Y.xD@oiPݨ((! ESY %Fxb G91K{8fVXPȡJ[-o}C}8Q M~PD|{is0T~$8Ȅh Hz0Sp8a9T-`} H>Xla#c@~|/W5L8 |P7x 6HGSBXZ=8A#~P/ʤ c``RU6{xIp$ y@B#*m*=xT 9rx)@HHPp7H'h}8I! GF&iM$BGF!s{`ިr؇H[I%( C{ M`!  (؃`0m.V958H{xY}hwoRp؉KcuPza,]up{:= { SP+c@;}^ac}0J`bPx~@VI 0~wxE"1z%PL}tx?Pbhi%8HH$$ L ~}ȄxTPtM xu`^P~'Wr~؃8MǢTe^E x'3 8Uk^\P4 PNjpqiZU/Q_Qj *7x^@<4\ xh(~8^: m(%Oyd*0}){9 mb+T hekh;r p ii{(=0wRN؁4k/!Ѐ%bP$0!$*(khbGTpvl{ ؓzL5J`MH(+X:eb VT`_@`KJN19c3ZQaF<:_tU>@ПX`Hih{8y(}y{p (%Fȗ5(y`@Px}!@2@E(@.Pmڇ|(K`8ZY[EXPN` `FHwX{7'`ȄXN(20 8-hXt0B~`0'pyzļHw `I Z pé.V/XluYE$WZ8-q[PU௫-5,q9<`0D)3 ¤2; }0[\F`wbhwzZo \HG(P 3M`ր^>PzHxPvL*Ԁ(4>T]yDЂ8_x/!htHpZxw.r؁%989[#X{19&9T 7r4y d]Q[bԕ3/LPc>s]76{؞T1S k8⥃WЇR*M }5~ ~cF!/zЊ!b (&2&y [7C\{ȇypwKH<iЀfnր{J kpLIȁX>HkL`HPZ rK$育8dE%}H %+ps"h-Rh2b-v[phQi4Ȃ X~8 dFx}8}ItGx0Ohx.P&H&5\ha" wLJ.0buPx$` [~ی`B8'H2`H墍p8 }HIKEY=kH(!ЌiaH,!P[fX V鲉x8F\g>cU[pFcXIxMn"*y-*4 gd5؃;8@px%B`+ЇmXFP …v郹yo,,p+heZ WPkY( Puw%gITx@yU@v HZf tlUt [ه$d_&?[&rwf@zQ8b؆`x~yWUPx#:kaٹNIʹ| @Gy76/2hE4x,(4F Љ:H80VWhJТx6xwxh Ҫ8E'2SH( 9r@!H@`RRʫ7-Rl!FR 2dR(Xӷϟ?}@C 2H 2I(ͬY*@>TZLK$>b4?CtTpUhCK?P?*ӈ(BJ?J>;DA8G?K fx L< ـ r-la2jfjvh @>^x4!?N=-csvLa#k^=,qD:l?4= 9HBHH )@?2;,(-M(;:Pb!SO&(C&ŏ>L % "H *B7BL0HC ,XL:4; U4A&p?ק >IJ'͘  %Ap_,kt4c ,34B LChFQD1 LF5c[0d x' EKaT#=G8jh[$ {,S(wE^hR`s0`Ґ qXP0 4  ;\u"G?aCpB( *21Lp#p{+D>q`G тPAZΊ$L+тht`TC kZ.`!'6)ML HliLDl`jFIAn{C3 (F<Gr0 j5lnZCk(MךF2X !Cq=qd`L by1 l2{e G{1LvbJUr fq$P%%(UD DʨGKYJCHE҄&b1r?* `&0&C5…5 a {Nbͥ;0GQ7t1骡,[Z{8H`B#Q4nhpT"y0Y!=]HUSr `DH yÕ]WLR`"*$VmhdW >P*qИ'(_QqP@->  M1ygddȣ: !V%`[1a `t{E &T 7 i<щv+W/a8U30*(9k\0 ;nbYAH)ܑ$w|p1>r1@AՂ1 {=A<\# TRŊxHi V TN&Gc39v - 4 Kd@8Xp (ްѝvb`1~$Y*ap+V&n F̀E,B+`=]q .-0><& g0?ѝgt C?@<>1a4}AaFA+=[]p4cwQ}7(n5+Q^D0!E …) OX D*1~(F/h @nUy`$^;XB'ȱ{#(d< RD#zHæ]G?f~iTWEl,p66'&1(znx~>Yl7f 8?vF_5sXADAJE5CA!'?|]:C; (;715ܕ|?D(8L @6XϽ!>e'%5t@8C=ԃ=Lԃ49tUp>>H9;D 4C=ĀQ((MaI?l7HAY ٍFك0, m\lL#F_l̆'@4C[xiA(\MY$A{zJI}YEAC:dHI=d < @?Z=?X"@LPhC/t:WEH$?$cWq $>9\X4lJX&dB@ h,(<)LHB/lC=06D1,\C+ gIuG!"F3A(r A mܤ4e q5eSmp?B%P/JAC0@ AX 7D5|9C;$?@4,ZBa(^(|d*4|т?$MgDf+BF7$ª# :C0(QB/<ܡ8^'+C*)$ AU C;ᴛ9G^7G$>CդMfI\z Gbqph=t2/#?@:5@8dQ&-CUf*8Iv~G'< <4CyM ΁Fa݄?Bl M#0Pp?\?TA?5XAX0n.ف#>C&H$$1B_@ K? A?C4B@d/*/p@&-PR (9$AA=@@@Wf 4CP@=Iv"*2,(1¤ )*/,ƛϽ"= @F#_10+٨&ċB?t?!34VY{é?C(wQ'4t *0H5d+t T!1@0%`#*/ A2C;X,$Udď P<64/(L;|q 8C:8=7Sgq+gsT2TQ`祜AxC< 8d9tiP. PE Ԁ',>;K&@e"8 0a46Ë"7<>B>xH2?,>v@ $ /^ t5hC0Y;h/͞9 ?̀tAl/)aIu֠uZ- ?p@Xb,@dʥȃ8hT>+kdtX1Z{Wd`+"!P7LkC;|R  P%K , 1;(B ""/tBw*`t<(@$B&4w A k>T Ab;m &#Bj:lBXIaé1(8Ԁ, @&l < AS.<ic +8"?CT /?ǀi @!)%t1Dw<7tdXC>D@hC>X<8dMT@D7)C$,XE<8C! ,@'B(Ѥ,4_dTd /?07<,?,H  C=0׵xK&h xL!>0iLH;L샴ÛZK4Y#(^C@:;?@C) O/5A [@ 8Q3mBA9*g"¸N"#%X)4:8̂h"؂X@JZiI3?~'ScE VGV;E ֝9lQ;,WYOJnHjN^3J6lT>R˩oH1Kn>;Ϟ9CT(>whМΙd̝[nݺsRc_㻃2r>~ĥ$Hy*ĈѠJp#*U'JUrȐ#Kn=ѿDQɜ>Qԋ)O:u)ԨN>yo֨QX"u*=m=IkVV ꎧب%dBA#RGiBaPrPzj%>d*d;hcRt jԒCYc d@q. 2JFđ@JscOFZzFugmF4=q^HıNN< e6FiziwHtS㔔MѦ{LRe X/@Z^]*"(}JW-$=D@A ǧNr0´pѪ g× }6[0r&); i#R%rݻ1d*##-z{AHs6Fp#` yosOCG$K 8B!f!0q%DGcB ŹMI d>m%6JEh[IOVUۚ\Z1[&ǖ*%f ZYfK?v[iz H"GhJKIC2.5z2A--JC6F.RJ8\HMtc,vNCSO8ebf9K%ӘO EpgL $Y_eyq%%?̱1!j_G{*[Tjl#4.2ɮ@Ok#Vwх!w|x $ 0]yY⠄% B1S%F6#4i%bf&X_3RČ2Ocd&􎆜ҝzӟ5HctD]pVT6Ezh F(z^FԢAmp^>%\x\"$ѥ]{dr+^L#͆(;c'7#l'41%!l׻P$4{R B@)XCT =U\"IDĞaȖ Qjr 0weGҋw-|4ׅ@:):`M<[?&0tb7 %4͓ nPw1k qO,d'v 2yHCA*X@ڐ6Y{+RևN4Ijnb(rxbٶ;4.S ?!k}h5$Gp "/miJLm.Ǜtc`%*s6F=e; Й 2G>)5$Nյ?5.:Bs->%QTK)ɚ޵XS<淂"\ɡܦrS^/LSu;"I!mN J`*AQU|.:6I9x q6PevvO)* eh V‚m,2ЊuFdnKЊ=m-ɳpģ J$y~o97I]n\0 {L "/C4.`1!JuJTpJOcДVٮvhtCփ5;*6 BrGtV3켞(AC4JcHYղedK*fɺQ~u1\?VkK]2I 2/ hoQSTF1jmީyj\~.fڤ>c߅5˙z6uP =rp)Xv`WoG+,KbmpZ= V*,e0EFqӥH&R.-9`MT 6$lt[6N?" HF5 <]WMP֞B)xVk*R7NiQd髶AT%^5?du ME-ޜ!c[/ќra73:NkP`珿^v0dlZIS.{;ʽ*S{P_s=}e&Sc'3;ާH>\4{;|Owp_xqFX:5b "Y^sĘuH5!k\6ڭw  g׃ʡr_WqDV>[$, Hn54Hb 켽%bI\⚄Gn*/P q"p 'F&76x/4^b#tbƮb\#cH:(THioVh"XctZ?ZD$£8+[,B/4ýȦ0jo|j})oj vJ^NLJ._d/`$6GtO0b븼 eL:Z2e4 goC=H?#@P IyJ:. ! , V  Bo! N|h1cG$uތ^s5wWwF꠯^=?@ Dl!UHA(#e#PR׀e_ vҗ%x≄B]2vb :J*46?'N),rYgBq^PHJ1Đp >hDH'5$A 4SMNϱM\FP}G&wykIHSZi5|w7?O ѧZ|RH\tU\Xע4W]Fj(hh'zbBgdfY(|FJ*MBJRIiB҆Qi͆l=$ 1yE@9ӕ0L$^<[^@SM[tB!k&uTT|s e z#mUB%5!`w j(T@dN `UJ/ ^&"Hr"˘2 G -iBHS-+L5yNP5hay:599tҞٲ79!f7m,{޶8 D=h R b11Vdw*XF#V0CHKFGMYY}2VBNUtiPi0Z<0q'iQPüP'-Ȭ2?Ŋ,5X=C,! e #ÿ2;89R L+ܵFR=zBG^uNl M*=m'rxri/AatwUGzN(,įl*KUŀgx+Тa05(.Zd^S(Nq#5b;'8Z1AYe$΅E]y:!I1!"֩n8VAF<197iAZtVMlq.!wQIVrG|iQˀ$I|o]Ębi':թPd1ژ',)Ա19JΰL}aAx5#ԖV-^hO% EF\K~2[KqJ R)ux.\?Au``ه?Cz (e@DGY%A+#(YM4F%X<Ը1dr+b^ZGJb;AARP [6U "ɒYYv4)yF6$(=hD\\kPf<נPg)?a4X9FqK4Fꫨ@#릾ma߀M 5 L#&.ע"VYa)w-%C֕Ld%.ۙJtT cӖ0%vi(J3]5Nwy xC^xb*4;B F<~竏W^*>OfgR'O1f>} fD8Xazj劝I0Zn[A"$kwG}FU"q Va r0~MoJ?Mښ&\cшCfxb6Q\xG?oL{χdEnĀS AYA`Ps:e* p :fR@nt | @M3GP\bBVUW<${قHQ4j5-u]FJZǷ@Pt^6m.r V`0 aQs @~ P/q^8"Ye7 q!) 580f[8 H9uFaT,[0ahā42TP ߰ @ tOU< A{M4UB.@TزT00F]8|@MJϣ` QXV` qj `pP a  Y7B8}A)x `4*Sr!{Z!`#f8!3-f?@,N6#0'  @ VU&t4Pnp2B 9|,.q-.r)s.@ Xi  P`TK@V y/#( 0` (UEp7z7(xYvQ?fS8! %@BG8Z{G>*³ @_ KC PSV*&BP`#MxP%óUHs<s@ 0p@  0`1@UKR 0  6GpB@dLڐ0E]TFt{ !"r !U!C @"jffsqֈ3\[0 /` `p,;sE0 v \_h4sj. _PDK 0i p`  p '(y@ P) VdYA\tY1e6 hts ?"G& EwSr@ pЧy$ߠ%Y ` C  D]Zo<1&t {w* @`R  `@s h}0 : aEcXqt salx8e l+{(!Bl8s!Xt @ ""J"MN 0P/ `G / P; *}J `+d^PPx| a@ -I<6.lUӛṭ nwv o&wP{ʰъ tqPco7QP 0 0 @@ Y?~FGsFQ  + + 9kts540 д p*`` p & ްЙ%3Qbq Pc ik{%QQg4"C aoISiN-u]hz U `5 `Q0 @ѰR tq ;G 5F`@F pSat 1eB`b6N` 3 ~  ~s+  D~z2 PȪp 2@@  ^l怑up(&Z K p"42mPXP =EwRj_ ngp  p # ,+<+] 02d s(GrD` @ @ `9p`̀ ZZ?w /@0"p| "  π `ȅ 3Mf)P` ʠ ` *࿽`a` p} |7.v7$Ql V8 ;V=t"Sd!bSL q{2p )  ~x{p T  0w |!sA2yeg?0``J`` ~aJ! p `xɀG%61P0Ч ȵp :0 »\1tlhXّ5)ȉd Œ> <+Yb=ɇWwL EG~ m+UcuY9 ?~q-xA1QrLհ3A"cծq >b0 =`!Mn g5C?#|c:ay,eG-6tiB@<} 29(&h$hCto fСd3x {h(A!Q Dp dRHF8y; faE*@RbI`ˇa#X :`wC-?^ w@_9!;C0G1`ظ(`FQ2D QBȸ$01=j4q`)gl8͙;D0ΰ~gJ o"\w |#O= !aQ1aC-G H8!plKQFTC]Q A0& Iw<(,3QZPOHV(h~ÊCֆ7d AB3-& _]X87ȫbx <G`{Whp:e p{p6!ь#fR!\+T)'{`F/H!A;$,#1؄+qx8%~X% x} {xmF(`(-?'%ױoh|X%_cTyR`M0Dp \F[\Ї7p:ZaFT瘓} % ?t}D!=b cgp{( ҥ]kBh8G9a:YC:,x_X9T~88`(A$@\'PCuS27 Xy8wT@erhwӇ^uhhke[s; Ws1}t35}p+:b<L؁ r+'e`%X4  iV,܇MC'o}8}،@ _ZPQQ85mRW<a]iІ^9: ݰHx9fij(+;MhfH*w $(L&k_kh}:^bo(shp HF@*xTs -hgrxfP}HcusU9s=h`pWL[p-txt@" hhV1iXOV@9a@ -Z 4́|Ә==,\8PmA`$"x9kPfhm@zX$2xz`S@PRGs([%@@9P1 ȄwP{t؁@]qb/T`?c K (Q) ~0w} HЀ 8f0\w3m^D`^x==7#DwȉM#x$w`L-8 f(/{(Y_HH,z͸ݦS5_)>ph H˗Ųy;á?v;4s 0Ї%Qߢ(G0&w'D^H8]Y ~(?gK`qu(rbBN]هY'p*˪ЄiX6~`X8`c^z8pZԝPH4^@{XقrH~KH _fYUH8:ߘu70PRHAh 0oЍ509mpS2wX!{^%{ #r#R' Lp:l؁b[A8C5Ms!b>hЀx (H?ᡅt u#~ΞbxNVxPSuHHk'8~fwqgc~aVR}|(q`\yxZXSиm.cYWSLV8R.~KiHNسy0z.bsP TI582{tPx}H]~؄"-A*Ll!RbxCUTvg*2dZQ u=ȝhplTru}ptP(s_ b ucP@h`pӋ2vxx5\JU`^LqHb|WpdU`ZHSo,国Ytu<@FزASH xx(OP8B J\#_`mHo.&Sf2X&( 9iSHI'8TkH'H#x#8PS}T`pvhy!=2 ؎OT@"YE{cfXE8HV2,` U넋~86EP[؅FPuYUo_/_L40p᠎%ytIܐLxhtFȢAXj(P Hntw cp(==7  )ᡄUHi8,2=yp@؁Mk@XWTrp$#\Hymh};F@c(ջXt\S8Z`I/NU~0uoomL|! 9'C[h3鴑$?B Is~ڙOY5eXoIPsN4;0E4hĆ8 +Z#E=rk1Cb$#Jų=wh1q~5ۗT&[`wډ$qʑrCetϟX*ԨQGW=[!{# ҫH1jSZZŲ?oƏ_>yQUKTj/z>ɒ!G`lx0tD!taJb5!(EkbAGgNCHq5c?1>QdTh*QUN0bH $?PeY5 PB /cOx h3482 . xqe{jB]ցe!̰,1 )6)"HO?DJ9НJ*Q .d=@/pw<0A|(+b"PD\_n  , OvHNL!4lN+KMrW=LC 1B4ҘS #p1!r4CdrO(%BI!$ˆ8M:X Q`֧!"?-$1"ivJ?-?Zr4 8 ,R,ԥŠu,'$"p" '/޳xn+{@| _*1%A?r .Ӵ3=9$+v1NGa]VxI?H %wFsP .LR!PB5¥ ,-rp@,BY!HIX Ѓk Dhk ?'-װ/֑ K^#3l eH5`@BX@? ZPb|} B O"2!J0TG#LH*N }wp # }x%G Ȑ T dx.o0" >aRjD!yC"48='ڐF Wy@.PaoX(gQGp:Y\L&Ј15QYl"=l?a}8яS4Ѱ;pMS*  aW881wbz Gh6q"0DpXa`/ <ă.?xc39HMm#@2 ZF g3Kb:ȑ iyp0c{~DK؁ Sв?z48 q@9I0h)X8VHi# ~` I#&t ZЪ)Ma nCa <Tb$h j;OrPE!+d J6#иGB  B0,!1P#h>bX2 F&Yhp2"q8ǡ bN~ !# s̯W@+B>9܉P+z8}#oTH XαN)xL8h&  aHNX7`A\ i#g:b 1Vcxp$6 g "G<9ܡ DGicC ^qs(x F xBs?X`(3)X?q1̀Poј?^ ,1(2C= ?x"?Bxms/=C/00*).?ȋ^==8C&""(" .DAl H#4l B;XZTZC3pL&8h@hM(CA)( ,9C<3p (:P#5:샣C2O`(0(CV%a9 E$XN<&a6܃2|9[ َ84.5@ ?$C_p|: XƠ ?K0yI?dtA@6C%̂>|Y<%@@ieiŀ hq<]܅4*hk)d(`(32C?sBGYQ*C/G(LCC!.=Bg`'yD8D=C 43 Z ]CFB0\`: qCp#;؀̵C=t#8G1C>CX?M%ΑC;H8h4L6?1؃hCAEJ^]0)?HQu  PcA^U5 4 @ ` a  @h#?H0B>XAUd؋$DUq[*C:L4?xR+|CL|9L8>(?DL=l 2|Z$a (7e4>Q4C3< I=4lxP#$#pP'4Z0@@h>C DV i?CPn_7L )?ҢɆ4 @:$)(&t`bvc`'8,@]ee"D<L'@ $V>XiA`A(9h7 :R2p sb$',?C4Ht6 1qIB=C38 P0C 6g @ l̯AYyB;u|C?TC0@de"p5HC/B*|CPYB%`Ghe00@ &܎Ռ6l?`26B&)C?t (ԃnsD(H~XUB;Ckȼ*" "[lx\B.$];xCQ?`-><6\U%!)oC;U2J PA&Z=ӃW-2•d-؀?(V0*xB"l @̅V>eh%7\@m\eiVTpx9=A<8hCt*+$A +p?>XC=DjXBdeV ,C;lC%@9 6 S;8$.lc+: @hpKBdއe%,l T߉ ip>8U#A(FL!/Pvۇa4CUo$d DB&l$D ,Ad(%Gm]Jul`*NFBw|  llc@Ȃ>XBq#dIB,xOc&5^q(ܐKAÌ,X-@ް=4?XP6h//DA& ]eTFBCYPz'xjΎ$@\w*C4̀OC:,?I)-OPp~ʯ+ ,n6@J?ʐ{[:& :wY|v<ă9;<߈7|A(8 8$o_x-LCM G^2!+28\:C3):#( 7L,B3dʒ"xSDt&DZ:1 wl*Dç=C ؂ïz*2к%_=֏B3q>"}oB׫+@L00Y<&td0,xB\8B%xշ?SB%к\Zqx1HP'?@tI`*bOp2 2 nLMӚG, e\z\Hi͒ou+R,qHS55[sN0s.9Gw#RVɥh%Vr>Ί,Ԉ)? C* O-K3,D\}cAfD[}4F{FAzCN4^7(9u$KtGQ5;Dtd/̀N} PDfO$qy)`ae]jCH7ɿ*o*􉧕3&U)꧝~*ļje y;uYYڐ^h+И HfzÑjӰ7,vĒK4NHQ"^Nl3n G%RX)dsP<3JZ UP>b`B^M/-Za8+J0 #ff<mE⌱R}4D%7"ć)7f;7/|כ􆾋Ћ[r8&`hY*V! N uS!QFv̥je#ȡR0]> L(W&JhĤH3%8T**X(&Fx/lk2b}YgZE׊/CjܥD!Snʘd j٨GVԕb]-rvixV/:#N0z<5ՠ5_'D0JXMo(&pI7n3*4+i4a^f )S(XbrYfU+F,]͡DN(*GyhdtqZ_$7K 'AsâBx$h*qЇRHD}[*Sm JٖO ^W4rSK<83cŠ='-yf%MZ2RH$%SQ~F\( /R09U1F9auW ɼPF̢g$Af4#( xҲ##MFWE#Y[V$R΍]E?,PSɿɤ=c-VuP-$Tѵc*HU B83DʨvabC&2}d6# FBSJLmiYCk5Hߚ.5!H":Y;GMTB"mNE4Yv5@)J {F*Wkd:BԡLt^@RXrڝF/_M2//c4-C f4 lΔٛzAԶ %$> DF1t8EABNur;NE]W5h5X9vvw,Zx1kf )*dl,h%6>k n~C$\N\'e$^( Jw>WWR!b=L&.KIh'! , V<"P PDb O:bÊiQ"ƈ96|BC"XP0aze67sQFF6; 9r"]w3@iոՐWC zkXC1Z_!e먮]K(YR{Ra )ǡFIE)R3k̙Կ-P@r B!ذ!FyumStI$ de`̗^4| D fP՛祥;l'玜>U ȩzZ QUP Fc Mȫ^g ve%T"W\ƅ`y2%ɅuFɅ=F)qf)B0%DEҌQF ZmC' ģnmLyQrDN)RQBuZqPQ^xUEuU h$~??u)`%#9]{!&!%TH?zd\OBv٤&b)s((!!C?j )$kn[BbO4q8=aLZ(yӒ Ev> b&esٞzbVXqU].! ڥ #zu u^`8^>dL:cJe駬tACRvR nD'_ܭhZj^P"ls,8tX&Ew2yQAtTOe^NC}GTuthɩ}W %# ݯ%-JL?db*xJ /A<+-tl1yF 6Bi$=Dh*h,s)MP]RJmSM5TswW]X`-^XZbiUR Vb%hEɾJ^畾_y+,(%z rfr* *DE΀\Tي"|B&dcAALvNڕv*:;֗ĔiL+ϹR.\I#6i,i c=?c';/PK n9% ~'w p IQmAKAd$ U:\m(  2&[j-aY=yutB/:KNx#= AMY K 1Vvm?g~WjlJ5_ TB)r7t {اwTf ˀ +$AWAD!v|RrAHfdg( O'Ó@aJR3NiQU&5lMrb ZhMn꣐_GeCD1㉅"Rh:3S(AFĎBo؛vd:s#pSr)dȄɒl'%Kh=7'JD%X%!%W!RpLPͰ7fY?'€hzFUEr Ҩr@ O m"fq pt 8,‚K%[͒\ȅ  Ũ `H1 0  R @ ˹B0 렔  a w dmx(|"%ǎR)0w!{CY2)e[t[pKl^Н  -9܃ ڠ *"Qt0 lP.x{8#%;h|Ϣ|l0Н p)Pp` HѠͰ @ _qWE60/ss'U^RC >aRRe_]]x"7e" 'g&F2 D_  S (  @ @ 3Ny  @ P}`u&Ah9OXGw@` ؒ o P&4 jqZ' ]=q p`^7ՖG>HVr%!!e 0RL߰dXFdDf?gdFQHH0_DPPӐ e' P:0 :; ra^@ | Vk`tpOh[t\8A6C-A    T3pHPʠRRI haq@ _A jj ^ аG CzQrRR>( MH  P Y 0 f""?rnӐ"@ `@p ` p p Rp `7S(P*0 ` }`uPU@&i;RS w@ 0 ͐ p ^@ p @ ? @<8+8@8,@Wp tE!ybg䐓lP& @v,aj`PD    | `ɵ ` 1P `ppr. :Z  i!4BTB4E@iPX@ *dHplO"O p < JE9ks 4eRcV1=TB 9 Uh @ @ 1 `i {oF‹نH} XV `⠈@ G(w` zcYP MWb  8m+ @j hj  H=գbR mQ p : @ pq&M}.T! }J+6 ,0-8i @8 :EmwQ ~;B` cz>?qX7"@Y |@ w0aPŅ _vfP a,wpWP 6 p< :`HM"#`Mo$m[’jVa@aP` <Ѫ(j@ VMSP4&6ׁ jN <)@90H q BN<`re!RLR7} @ e0~ ^s8wm% 4P ŀ_ 苾k ÀӔ"` &Eepv`g Z&EAi` t@owDa0~M}4P<c=3` qU-RÇ8VdϿy6%m=~+g?s\Z_'KjI'O( 5j=rYb0PV!+V̙R&3RRZj*6[ϟfs@ŋ8vԡSW[gȌ5L`h| _?Lnm;og.Y}J|5'/f[5G;qw:`@2e?iGh} #'Н;nnu 4h9s3uq -Fϣ9qMC9e}J$Qxqb((0Nr%i$)p'Bhb(^'+(V+bxGOԈf)l{j20z @h3xAx"G5h6X3X6ڂ /qNJZ+ -{ygty'o^!摤(bؐ9=0`8gJÐAxIk!V(WxHbyҺ'ǐ+ќC*i@ S4rPr3 B'vꄔ 8f~Y}P~^Š~HGRi-m֑}gg䒫u̍q斚[ČnS?A&.a3cfaCP\@ m|k? A{ S9l ƶBCp@+w#hW$TE&8(n,` v(Ӑ#;#*1icD p.CU]pc%z2 x]:" QqCD$(L.)"ED7n<~!=q}K&!PhY)<~GX/?Z! ) R\FqLi[?PqJ*ǺeZԁ ụgUK?A L Jk7\BhhC.,Tk(Fp,*C[DҠ,T;Uß 5Úԙup} BTCA# )A?1~#Iڰ+nR GH?Ęэ B2Ѓ#X"vrMUP  @q8%HpOah‚-ajhf3 "TuɶJ] $s~ՏeĐF<桏4a'_!O؂{4k!-pJDPYHCqa Gv{@-  '`Pܣ <~cĀŀqQϱX+Ȣ#:^ZШ4jjHv#-bND^9.c$p)|J#+l$Ć@,4!-}bZZqPT.$Jn1(!CK8u !Aj C2T PC=ζYsI0j0u~TPЅ`58zNK8>LALRI,RT1qvBs?0Jy'FҤ\?91Bq")fK:X|)ĜVq , qMZ abd`@I*/,#->dk 1-8P\N'&XJ2,[F`}šW;#6FO76:1 ("8E',[>G9U8B ( dBh L{LcD'h=Z2i qI+OupY0G= `X9 -s8Q& wcg%*$a c :#ԲL ] ^q ~l:u1X(,`;mPiI\(,,-01R>znctkAx{0,k [%XP4X H}xXs ISze(Ȅ}q`f F81҄}`%@r9w0mh4:䂅z(!TRoZP>sM~BI @ۨr2fR`txVQwHzyx~8`Ux-@0 @u8@Wh]P{pE1pO뵻K;6(0(N9OBxCق%P~Г5P~pKoІTȶJ #'HWHvt"N`Bx.Á J ك(MuXAЄPpC\e JpjLJp(Y(_a~ȄZNZ }艠f`o]H~xH6$}% ~?Ї\U|]Vxa 9Nʾ̾k bxl V͝.bYtf*H@;@X ;KS <لW`؄Mw f82肐xxiJ.+p('@k@(阃A8oJ`\N~YȄ.0xJ;YЇJxqȄpSY؇Nh0NxΜp^moe^bpKwSXT8SSȅo( sjNH/V@* {xlzfkc0ƕg K9m\$m"7զi fC05^#:%Bk+6Ԉ }P0@+X%P20p?2/8'8mPPM(xKKXtCh@󳅝ЀրG8<8Y8T~ Lv꟝kH; vbk@ R^hbaZPF#iH׃?kNk .%Ri5Zp lăFgW{V&w zX;g>i *5x7rSK%SHK3AH2y?oC?%I'8.MOTii71m$HH##}O4KМs T`!@@ux؃ hXHTX '~@zSm|a= }L^`Nqhr҆xz f@JfbqRx=j^X`VXp!kTאm`]8{'}llQ* rgK4@~Xry̠)h(R)Fv\ Ls5Xo(0#hb)?pXnj=]ph$IBQ Jy12$#YJ&.=~ṃ!60 ? 3;+s~'PRp<35;֬B! )ttBJ[Bt0;ҏ8B4Ə>h*T:C.x ?W#()Wq)J`$EPl8vZgmz0߰1kБ=pSXa!UJ?x?h/ 9$LXCK #@E?2H'8?!"!${ 9Aoc #س=9Ӱ2dL!!I"-Tāx9DB)(J0v ?5 ;Dӏ;eO??rUWSbiORsN#b#_Nz ,Rcd1YU?Y}@ /@Yd-^xьfvAkVmm!?+G-G s1N +h<ʇ#? kH3DdXs=HZ1?^(̐AIK| %H"hS 9 vt X!(S0)}O|c;H-FSO71ɓ0 @&UKi(!ILh &Pq! EAA.u5G{C6 6jSpʠne X6q&s0 F3BAxc@~0CY(D(cDPAG3C?ZI4αo>j0y(剤A:#IG֕NIeyC쐇X*q+d M@xD IB Q@ .]$.q PI?Qr, ,a-x,!wagiXJ* _گeC'!v xv3`BP p1z `0q /H@yC `3,tPKgth&HBXa%odB K8 ~})HA`-Tc)!N OmS˪8U[>B iN%H.oāI=1h_:z%<`AEЇ.b$nͬ4 "@  p@ Ё x[F (H/sB ' :#Cv]D߁HGk6%(.[{'XA<6dNA$-H"8G+,1 C () A"(L><f.+Y#P{B@=ja v(6+RS!pB*^.`!`?q Ȥ^! S\G7aXwl+`aJ ^ z{< @8cćap"L:Qp<>2 /UC,CRapyTG8$ ՆS0vJA0B+EZ%Ȉ;SgHGCG=ޱrX#A8LV?@Aǽ|E2lÎ !C=x| R!l)qp7Rbta]+X]vHĮ@8P`@ 9n93 coEOZ e C3 ¢fGC Q;LC?XC3(0=I97$(2%xB?PB(|C;C ?)N{$K IQ$> #h?ċqC>C=W=¹(XA` PA$ TCp(4|7+\-+<)|SP.B]AV؏W$fi! $ AO @9bp0boVd=,!B4mC/P $.2A&!&XA\ AaAB?h=Dա  %>D 4V+:PA ,f <4=h*@|?|8B/*C@C& B+$ AD@E YCd6pM"K ?HHO=HDEL-:CE]P(\ 1?CAB;*A 0qZ!D0b88>Tpf38="@@?̂#T#PB&:)<?= C 8U`K$*(;n$38# q!&6C/R'd)BDVx$I*.UK"/qA_"69FQH(l H hP>ʠʃ 8B=TѩA/55?`AH%E<$)t*L=HA>8B_ʚ2B#\3\@؆Yg ̂>3'Pp 9<#R*d%d??$AÅA&CJ 27 p@ OEX3h'n`"yHV ɕeL^9 d*c1ن<  ,X0HZ=FktJM&,e*Ryqgʾ-(e6(OQB0C/G pBP?C,&|CF=*OUh4tei*dfg(@SM   Gjž)HP2&!P-@ >47: ͆× @ P3|/a+h3 5=1CH%9C%*A&@MC" @ S=qKe,[%9;' UCi/1I\88C& 3āGMC(`=63HU>7/3?p.Tp>zXHe6/1+hB()LCJ1,p;6)3*&<:r4'!*)Q~}NHOɁo2-0HC#1X2v'! l0 |hI.Hc u=X,/"8?1WB|llZ>%^ 99q>)YxvB&*9;4~O*G_GD9B70T>?W@84lԨFdكN;r.""G9rQMRȽW{bx"M oΠ> dΠAC C)\ҦIk֋Nvdh@FYZN2*d.GCT[FT?J(!`K)M}᪤iT'K†4jT(͡hEKo޿V(Rq"E*lX̭t/"=9 ( +C($;dA.Ca⢋00C*9/ޢDFB1K4O2餓P|ij5ijQ!R|-`)SIe^fiU\X\%!9HO>ȣM 3zObH栩jZhO6D)䍝0F胫AiO1$P-Ԣ6ݔS)WuVG*adNH9EF|/ "!=ēN4$ Hi|`lqOaP$si-ViVZ3ԅL$e7{6>N$c9 rtM~N8( Dh꫕2L= -Ury a$u͙Z]A`C[Ѥ0)d/d;Gj= 6j)lR\B 5rOIeݞW^X\U"I xσΦdfOX Jj)8i>#?£0lBPu-Ar5B܉vG8PdWg)ZGrک<ȸ ]Θ|ViU_XhRh n$^HDP!4b(A :vİ+:t,蕯d@!Oze NR%C&t#\U+ܽwZ%LWejj$Ya̹S]UdRb)^o3?ž׀Q_zpK/@ac<  }Bן?!'JPg) BU Qh"0HeZQb1bj! E,^1F92^ H2VXl<yIOx51f*]qt//pIGaj\EГjb sr4Q#h݇'Q~NŽ(It鲡LH ^³Se#aw$F ĈôWi `T RxbYc"4s 9lAW..o}oiD\9 Tc#l\Ǒ4$?qNQG(`AU $Dx'.ǫh*F2h>YPGN#Q]}ȗ0<ь,ѫHEJuԉQSH #mVG>ِ"}3[)^Wjk椪R\M'~Ӟ<榅G'rT:jL?-Os͢s[R48ULu2JYEwFcZuWCX†6Fj<D,[a,d=6al,uk\f+VЂ8b,+TOOչ .~ Cju@\ (Hu] &%e`'P2W \\W_ =ѓQqT[ծPHak"dխ`6mKźRҞblR4s`oYpmAb$?9o 3F\($;sVoɥ '_OB;M^TH!KP~x;<+a2GIkӪi]XCe.miG? I (.mlMe3%+ ߵHD(iT W{֢I<D:q?+!#r8ӦD,]]aRZZ _øOulYZWVe 9oؼLjT4fSΒ]-N'8 ЁHvN$nH3k$wN­[0C1*3,uϺ".8އ2Ei- aJU6mahӄ-򬍴zM\cCWL+8ɑsGy5! Ik5ΨS`(WUܦbS3p'*9~nt A'qkVxifUF1E: +yJ~}9xQk}&{޹e7c)h{-9x! , VB H"!#!*Oń1&4DE?.gaI[Rn_J/^lF @SYw@uzgWi d YF̦U{֑#ouKxGNCDo< SILԩ˕/k>E)RWAFBk֪!%N 5KpF[eJƷT\gʛ4o*ϹS Ϟ>{>4RrߙϠ@:^VC\ 1*hۯ?g1B\te ^u_2dxRX' bBJg|)b\IeEQC7h[n#%mhdM.YSN)ZPwO%O^^QDQEHS9^ S!HUeO~9bH% %v\Xb`az-%&TJVcQ6)Tf*V[pt!BA!v#46RFPBFI,+LN&4yF}OwlwfT9%VWUPo̡!wh5|bu|eɇ[T"v Ȩ% u(||ׂ~]xrd)qکdʊ,B*\VINPW泟}-ߠ,A i3bP0ƌ2_($j)IB:'f AVf:[Ad "HR#ѣE L[NtxXO JgJzAI{xYg?BP5(G Q''ƻx~R` ũQπtM`38,H1Ε&I! ,X$0d5:@$h5,l$t-Ek9U@$:)a2'hR78,bJ?"?2KQ.rD%c%Awq&2BR#Ja $9͋3%gFT)i%UB9 rv9kf6(tlUhfuHel dd-Ǫρ LMJ7QC֙eLV*".>*yJǖ&LY:nL-H~DbVe Cd 8? 3LJę]FkgJ2,d o Y5䄯9d 9*iVԖHG:4T)J[.7r+UʥXmk{WĈJi_A*d}8MR96)J Vю~?籩o{"˵-1=_!GW141mn)"ˆ8Zq(<G8^äq9Z%1D[̈U##|mlZ>wY>EKwޙ1f/3Y[x[cM1Xhnw"F%4DȬ2ArUS8А9 I!ÄDK T CmáZLC.a~8 ~s3 |ХJyO HlS0y(aFhk1\Rgqa?6T@ 9,\yG3~I=q $%khP^IH):^:%/$Ї>h®@a=J(A qL#^ۥ!(>,`TEzs7A\SFW@1!!!T1vs4N#9A/cirP EUA(:h32 pp+5Pz&07œpUS5T7LwAm EFfD B)ST TEaA919-]ceW 0 Đ p5h#3N:R2+GG UP!bE:W]35V"JqGY`QQ`PG @TpQ p $e@ 0 pЄ '_ fs 060 EW!BzF?~A@! 6ns{S1Bi49  H.tiVV8o`ӥP,-,nt]8^ @ `&Fa s `+< @poG  NY @@ I pKuTzLXY;A ;b l!!1U2["Tȁ q0#-O q 0p{ vp@/& T C!&pP'C? o r G@:` J@`  0lsx_ d@LCLSu`?g!g  E!!QGM܄[h$%PH2  p lpR )2F9 km` ` F qJA-@FWH&< `@ 6q0VP=\aA @ p I/A>~2Sf txL"F:ɴ8ݖzS  @N%RnF a6] 6 ,K 0P M 9*2+A  kSkpgV`%IZd 6aC_2 Jpi/N@ ` 00 gKwz   ZL(m(?|L?0 `x ЄVp[Ae9b@a@$b) 'iPp P f 0`2*  hR,2 Ҡ kP VgҐTP>dr}ZplJV& h5lpprP@ P7 g<8C`TT@ :E?Ebt?E{  p~qP P 2*#ê/@ 0[ p ` p pp/ rp$3VR4UvP` S-`1R;W@K $q7?qr0uE8   Mf m` $21A  0 8 5 f0PnP~Ѱ `s4` @{V ] ҐОL Ѱm P#.=}Kb<F`,-,`Zp' j k`v,;@8+PK 0RT0C%1x ⚌i 𠔶VШ# 9 0jp`>P p 7 sQzzv@%c^A m`m 鰍 Nn`rt  ɰ&JTyVJlN-3л+`6J f `0z@ @ -+?EPCqPsPڦk  ?N`s`h ŀ_  8 Ȁ؀   4J,5oOV i~wNL&p` znJp qn cCH1.qeܣ6aΜ@ԢFLlHEyk?~3H3{,!?w49rDR(bQg/t0 | WE! B ;s4 # 5ea|yC"+dĐJ v[GBwØ^P4J'-DO %[L'(1!}Jge(s46Ԣ-(+ɫrrºcyʢ~WD)ӕcqeCF-֩gW834}䨍-ĒDހ36 mέظ9nF^Y8i柁0Vharpfak\.7PyD*ܑJbrZGhiFKv )yi' K[=)ĨMDu#P'Sĩ)~iFu,Ǭt&ǁnٸFD0J|Kzԃ|S`ه-2 -OZ@5ЅI4Ԑ{@b+G0౫~ģ [:G',D {@!pBDX@(GLq-nU]F7duY](H1 RXcRBLk M(oأ>}" )$'9bȼ%$Y7Lf ac>n"p1D*~qPˈ*^4:HB{.٠.p AWhC,8l i9L@I=fЂ= pGGoCOae=!z##ƁB':Ӆ"#.䮙P4&]?FUE =х~HʘEpܣT<@As( vl쨃0̒?Hf ht|:0vxB.؂#p_hC#G=<` Vmc1- Pb.:T,^x$ҐNaV=9 d nÎ!Ѐ;o18QsL V|H7 }('NzvdDzW'ddD ON RbD0G>r<]C?a{c0G<82{hԠS#B14j|!Y`ɧ6z?T1&a ;ѠX.m3-eB?DsMjx B ZûgxT-h#wĭԠnuG;zA n  D%H8[[t)>+DtD{r ]B;1z`)H1P87='G=ṛn?ΡHbq,嗾4*ɪcC`G@}xH9겅z j < AR$=E\%,( :921nVhI(E/q>cEDek̃.$4Qa qL .x0h+F_ԣ- 8w"A9VN\.Rc ?1 b¹p.,au# Gx?JӌTh7 V{;点46}#G$QNlIr-H`G@#$^CpmbP~c v;C`9za{#VP |Ѐ R(H. FGۍw8>OX\ K8 POz-ІM"]i0mhP`*إo:X耇iHc%n6FXy@'P*҇xІ_脴fyVcL(=Kher@TH[]a ~@!GЇu0p[JSҩw{Asۇ ݣHS8wȄ?xw`93 @hȄ=qdx0©UP$V+4ؤK@c8KK_~zB⯧pD~h0(20y+~$2AXx@3`w`S @Hh#l I` {x\`u#w04'{@%!xE2PB'}  + ~,fs3 J8~ІHp}}Yh3SM؇Tk;pПsfA~@ x${hb 93J$I^Z+FK0cQ쒟d_8_cz`k|L@B۰ H󂶂@:mXPF[ h`%`x~`Aad2kr0h5(5І{P0pWx,!xmt.؄!4uU}x0;("y',(@xu xk ~0 \؇8#hpTЈo ^^WwXhaEЈuŚHdy08pGiʲ#8s"f/r`VXS#pQRcxE{aUPQnq yu$R]>`ͩ[ 9;xY2Z"0X+(?~؆ +2hh2HHMЇ].}?;F %!B0~#hdi.*`Іex+m0}`)t8 0~7;UHvПvDRT^۩FpGK]T &6UńIQ[PQZ<@Jc3>c/:礓Ұ߈c C`m؃3(08x5+TrhH65p .pڇ]IB0@@bww@N(2Pa}D[Ujxp2! N`.pd.}}҆ܐBP$=yЇ{`AIrʉ$X3KR4dAR@粀XPG|_Zgʽca\~nׄ,VQz >pUˀ ( /M 583xLx(R}8Ac+|kCBF%?`P$@1$H(HX!({X[s [NwkDLxlqINfNm-0ed>z9^ [rq^by@ˍ})9>V`\`oJ) }JR҇P[Pmw&h~Q3+I2 xu{ '8 NYʓKߝm`u0pLx{C҇v`qp,6iYH]P?8X@p.VP(*X8b Ѐ(ZpT^( 0䜁%pPvk D:/ }`x߱ iQ؃u8SDlֲ(VR̨twվGb^Z8mbЅQ^2bV]5]3]$F <ѓ:P\ ,` )bQ,~h/@L`ei].0H!Ρ[9@ҳՂX p@v~H( `E.`^vx2UhIXb`OS={@oEpG$a.UPL5 [gVg23-/F"`YpZ\+ - 0,mgk\X=.h+%4W5ł#PLF,=h!Y01bҸB(m~X`Ȅ@!kE@$2Ny`fY#s:3{:^hspg$ s8OM u8p?j1Z@w5Ђd%*Jh[hxrxoh(}<Чm=4@x8;6脤Gx @Q 0H0B8sc&h^7 w~Oli,Tȏ#Z;y2vȡ;qA8^sxmB@xdFt9+O߬BoR|ŁCB# {Bb&N;.f)R%I!B"ԪUN<T`O -jzasދFTjC(bֺoI0-Z 7ۖ>|ĸLj/Ǭ%JNwFQk摻6H6)Sf֚x?[fO!6Aw 5hc- 8 m1@ԁ',~*CPO7<Ï6Rİrʻ<4sOFBK/4K*FUj# V\ZlbdFE0 $ ^A/lĩRusJC`XaD]FV #HaDG# w1G sܱف(͸t'O/‹?,s 7u88#v">i:C;sM<p;s "1LT8Rq94(y;4PO; 3⬣0OK=lBI wP8X%$$Ob"U\$` xCqR?^a# }P)e 3tm Q BPS0EFp^lw ^h'd#p8 "ԓD S%bC< F "q#qAd 54aTbPD!NhcJ8? Q[A<@dp6i(DP$XN @?ȡ eN X0i0 szDqЇ! ;m:uXbGF0,uteJBG=ȑIZ<)< bU `L4f0:呞 .bC?~VsBgc#9tG?ā8 °H6A6ֱf7 #  |co)b]t=a{pwCp}@ 3aabHY!!oC >yӛ+` hQz{+hMA#@dI 0C& ,8C;Z5^ԃ6 DQ JB"Ađ>1A9"@4XOPRRT4,|$@ VE^t(0m !ˌ?TœQBy`9B!́)):Y?H;>m:M?D< >,: A@%C?B x]0tH6!BC0$CP@CRڃ6#BZ"tHd@,bP4氅 h#M5CdW&xȄ*(=,cH1))^;CODLL@7,+\?l.@E3'|("@Axg2)ˌ0;iC?X$(gGP!DT:B0XC=,;؂` 4u8B2@@>6MIF')BĀ5 8u@h5C?_;ø>$D.p* `(?R)0qBPLxZUi |4܀d1qAA 7(s59xP$!A0(>Y2 `bA(%-l%*J,D*ob. #LJ+@2T Z=P>DC8C0R .BlMxG%P"+%XB$B*BИzcL4t@ DA&B4 =|驭F(AM(&1 8$l‚ACqiq+ EB87@u@.1EEr p$ V1ȃ8QAjmjY&C|,?1t9A$|öكPB3|$;%%M' 9A $,@5+Cyd?(* 9C/;l.tQ(`%m4f dB*?W=ޣdҰDKC@=2%1)`:h.<|-|#s ?0SEqPl$ N>H Bz?(lhS@ ,S7>'X@@ ?)$AP3XA;Ayxi4AD]3Bȁ="P ,AB8@ 4-X+< B @ LnAx@ h~EZihz$#A $AB0>Bb k 47:tM۴ DT8+. 3&QP4h:)? o$AXA9 A=B žHsBdZC0BĀx@h {@Iqp@\B9? P8SxB !=We@=6K 6B ?""/ 0;Cr6-*$>2S&d2zx'|<@<(A (ȃ=P2<"\!܃5gi ouUT%[buyBAsB*K+*؂2C/ v B/9:&C>C0(;`;̀ [D@A&B&\tykId40AD>C<5C"H빃8HLøPC!@ t+>ԃL&}C/\=?x줭zB;dy7/ lb (2WSx}+)t<Bx_uu{ML=tA4X:M(@,B4ÞC', G601(KPJPB B/hA$K59M^,@ ̀/F*ނ->І)PA&3S,Xj|%%yC;p<0 p@,.wӷG<0(5ï=kgٮMY%#;() 8A&%?B"Cb+lܸbrx+=I>aC0Ä_565͂j=/h<60ˇmi:D(B')< 8>}>]۪ %+/L,e 0>h o]Z($9>lRPOCUJ+C/¼xBjSh(Hi+*R8PdClgkr 蔇>CF(Q"|R&$&6(?=(,ƪ9T.xB$tS0R(dBX\Yb5_:Q7o&rw`%1#z> EZ:vi9^F[Nz# %r|8ňx8(9 D<`tSB@ jdRz*ג&J< EDO(Q1ĻXf=eds6UTr\lU:[m\-5F::9԰!ڈl˷;] ʚdN9;-'Ҩ~irOFQ R$f/(9嘑#TNA@UAveG:yeKBK;Vcu{RzWR~TYXuZT`!E3L[LfBFd{(EcP:2 )BZ )+MEI"1ȊfBa4nFa~t;YӖ<$eń=]KE5[n[_T{WڒpI;蓞܄1"k"wFQ11yPQFTTAՅ,EUf U͈Frv8 1W[XQM[ւ*h ZPĈ7smAɮ9}kyt%,CFND4=A).@;2Vye+ *ie|%S!ĥ,, ڌ 9T[0BYiU4C)J4!D &j( w5.<ΦPEY(oC'0= ! Nmi# F""m8Z@P[Y RKƕJ p@+U>͹JUq]f"MX7v %O(WACCyxԪaX)jNgzO`wnҤ9utEɆ &yrF$y8GylAXN!*Srq9hIJ&Uxݻ%g}+7"Z$QkI؂R+9xbF6e>PJv)<0}^ 7f(V2v Q#Fӿ Qj1xYإZ):?dpUfs0vtY tl E".d6iHv )n5fs Ѱ3!mHn9Q4TCE?5@`.K*4ɂwz, Q`]EFACr`ȬRZ{סY<ɶӲ61niF.WߵA_َIl ;X-[^n̙^r̉ l U"QBQR9PܑJ9V4(A[54ȐYCeoZGpuv]JQt޽:]RN4!DIqN SOQx ʆ"eg42?޴+|l _isִ :0y?5}&jQ5WN}J;)֬ Cˆ Zm%rZ{-x^P?x2 _2eEbChv)+@IJ @OA@fԗo!7АQm@BdDLmQSA8RZud]v[eR"%&xG 5ySETlExW?uYy!uѵ?vEIxa%8R%?XduBJer:X?ƥiR@mo1B)BԚKP,ҬEK/E O`yAEPDTYUlQ\5|]IWҟZyo1^y9_"{=v(d|EBbY-b*+ 4m(vq {piDBbRodqc DQRӶ^lWSYP=?VA߼^#rgx®| cʈtH\ӥÎh-LI(Ƙ#≉f|:Jf)>f!@l\k@Rp!D =DC EyECTPJev>uPE1MgwSu;nl.\A{_'#_[g}M0/hN%0 XVb衇#RuTHFH h%u+!a9j`2$F%']ĭ;,%xY 39k?Zaհ.G?ei[b}E@Z!-uk,"~TV! !0 MENDd89RˁIVm>kY+u@q3$2u9;yaX090S2)ݺ7P*EU'N]X>MADV%)Lo_4 Q\8e}3G9Zʝrb:LsPHGk@iIsP'v@ )=F1QBؐ)SC+K^ƕm_*,/\0g*.\Ksaxd$C̘L*hTќ%RHaĂ;8Hz*AwGhi&$ZMPL3QMWc!NћO5ZhEK%hFE201L}bgNї(HfV5,A41k"+՝.!bbӒ*,na*%)5h:>[JWAtlf 6>PE&L>rd% hR ceHd_Sy.S31XI=dWgs@,t:cYCl% Gzlղ,LKJ4-iA(]p7pqK`@ލ굕\rɆY/þ-P*!ԔP4SJO} ,V19  +#=HO8@T8)°ЂH4J/x2`K"Jx ņ E21{x^{vU>^iYxOs[1Ö.O BD~XfDZSYFNA۱ ĪJW:aHW.SNufɬ[.gQ>R){̣H}(\," %.emS6!9,?궰 1p23r=yvp*Br#KۑJwVhg\ &='wsj਎ +rH q@>!ωMC.S3xi"`dH9Byyu}4`'m2N1"Vt%P,sCA3Av2;,'C21 @ u`\ql9^[?]A1/RJr@ KXM7 0w qT 0 'SLze|R/65%0a7/`%2"!BZFZ)?#@0"2Z%k@2Ch"baV#11 01%B3-66s.ե` QX o X@pG`@5 @0Ҡ 'Y  S 7b0a&!Ma"B&Tr86 1u**"}zG}QZ@@ Ā 0fP l` qS{YRs  1d`0 @ &a,^ ha 0 `  х< ϰȰ P @ 6⑐Y207i  ߰  @`; 6~o|kSw` 0n Z ֐* 'ٕPo 0 q `: Ұ BM1 wFq"ڀ Q}d x1Pg`9?zo%C /pЅl  Ѿp p*r 밯* ّeEq&y oP `F{M & : ɠkQo0'CD} $K@@IK@  B(P נz-4I  P x0}Y / m` 0sQ px P @ P @_ m ] `p I=n@V @ E^vV9Qm`V@ <9cf ii p&ljCc/Q'<<<{ ]`  頱pE ,% c" P0J @V m pV@ +Je`0,N۾@p `+`+ @ PLS?*Pn\bIh5赺قG?h7O݂ YĢ'!: a Ʀ'?*؄U,e) Kzy|xq^X?pI`hP;e;1~(:9{mFST2=xĒ&LzDAp#1aU̧1юqc[Qx4M"1Ĥ1LS.JX\b?bI 2AƆr?` WzQ1%3Xazg#B PXI)q5CV@\oSL౎~ԣ8<!D6q;  % ^F!$U=) kh|c`Fh㎞e~BW u,^LtWNTIC g ǢN}ܗ0O6ILx6l|N i4D{2*tcPHC84GY q*!Ytj#= pj%" G00`<ދi0#!\?f `$1 d8hF(JyD߸9A RĘhciDNJqqYyb)}i }X`+O|"`|/ulv: ͸TM%F;Ae:/@d2?^'!m^S`Ȅz{P@ @H``2 L@b~p 9o wh fȻyNP0rtySe!IP~%8kxf Zh7.4q=>cvax]hZz@>1~EpR8)0/?PX % H0{WXA03Q\0{ڀt8,S*xw?F"ePPMI@*zH8,@!(HeP$R$X.C0iptWi f,JRhyJ#$.*x`r;}zH8`*`{x!؃4PzVH=X`RHRH'R.68Y(c08 SɴggUP[|u>S $6ʀCdC;臏3` ǨiH} HHO /{BX 8 P4SP^Å}XZ hL|@Q[vfhY{.(PspL o @8}XzrHySɄRڄ=y8o`$f7RHx1ycTUT_aPI8K5>hPI_ZPQc|I>p8MBIF * $/pw: Xh0ʊ5X@Q 90h}{Pyo؄4%h(pE[8T4rlF,h̔Lr+mPyW.p8s0H8^8L!@P!H!@wXhx (H}'wW`!.*#d8ӓ/D_0K+K(Kh+O PW`P[l8|E4(2)5p_@ F3?PpIa]0`+ hohF!Hx?H58# .!E@F`F2L+--{h O}zH}І`( 8em`w%$@?PXF`t8HP$YЇ0ϧ1E XBb*Pb XG8(])H\X%Pb5VUPdXE0J8M`DMHb N CpDŐpeq~h͜ ?2ZJ W ?%rpʳW$ yHtPS0 [Npui( jՌ̛u0ds`xGoXSՀ7}S8(4}ME.Pxub܃MP?(q O/O}cU'ՅG(R\ OńIIW\4@ (\PPNQGW[Y Š6@=utKS9؇#EX Uѣ0ZP Ȳy0PhpipPohsm@xދ ~H%`bsPH Հ}Sw`u kM}'Ї`}@5yfoAcwYEIkRE ` f6[ORx 8:aZIPac,oɐ>G!}hH}x?XYSp5PXѱ|Q&2pUP&H:$]$F25C@Ah3 szx{؇Y Lh4qi^OX@}@Kp%i"Oo:z W i mHoDhUV V-~knf[fc <Ȃ=2--82 k{~Po.Zu[%v +6)rQ~8u0 PmhMT402`~CAOЄpnZaO($hMYhYȌ\k bAyЀ(8jHNFjIsaqq腓`"r ؇k0>jXrf{`.SHlRI:/a^xG0RkcRa8ָ >qĮ3 鑾:U)В@ :S ,hk pkXu'OЇ?x(xxT%OJaZ ;wJ1dv_X8pd͌~; [0YoR(H tb fs0rSRaoy^7 Oykx;\V ɒ 6@h6 h|qUpnfHgH$SvfbP;^(x!Z0I(?Q?w?r(Wfx0!ȄІ@ê@s~]bf!`_KBWYwІh8H9HPoo?}Ho8{XܓOmP`?{*P.0obԆf#xSp<V`Td빞W@kU0g]xWI 4ʺL( f8-V=陞AJB6e(er:8ֈXы>I+&& :'0L' @ l^'sCUhCG;Z| KDfM`oTem*jHExL5s8f@q q0`>ESH)&Z *6lxaE RUKՄDlyѭ.UϢz&AӃA>"ȹT/[T9ӕN3gʹO8g„%XٓIQ.Q9p!Ah\3aEJ"?\"/ՠ@3Ĉ(Z̾_=k"A?Gya og~zae_Y% ^=?AmBtwu(E*~* DRJjI?3MR#-K`"D @TG1GY Tԉ44 #jlਡ#CYa F$m&s?qFeO:G4G?X#N=?8(c)H $uoeCāC 1<(8H j0RH!K3O>D(ܓ#A ԣO40 LZ ?FsWl9liNCV&2Ɯ,X !P? fq X ||8@QCā<[@-=B!1p3hg 9αw#% ,Ե%;@E1`>Y"{?B1 u?( ,4 }]&!92G (%0z؇ГL@ Lp={*&Д H1d\ J ڠshB*l,(R`%eKϔu^@>p;f4h;a{c7$X`ox?CA4#(=x1NCU,plQNU^P"oh"? DN82'x'BjB:4jxE PAhG Ԋ@z !ك"(@A  ` 0 E , ~C0^8@C? >9]`@Q+, ^0^`@ͨG=sq Q":?H܃ap 5[\JG`F(?~4fijo[G=0Qp ŅHa!I)_8A r8$#q]+<@ F3zQbF̀q@K$S"z^PVx#-pC0}8INpԠ{$>$3cbA `=ADsEއ;UYщos09B-&DQQ^P\&CMŐxV8^ْ$880ȁh̃$]AP3,DC?B́eQ3l>HClB!Ot)?9d o>C+8?PJ" B*̂5l>XCF@-DL?H#Ā eZCF@ @ x@2]y)t6:@$Xm؆>C :LĻ@D?##hClѼ<|0-AQ\RpRSP!?l! Ch쎏?́'C?Bu!ʁ#B3~̓)A`X9c!4C(fY:2A )18 ?(T+L?HC (B?>t Dw ܤ0%U @@@%PB?dC86CB$ ?`]>4" 67ha)5̃B3L98mH=T܁QC>pJ>ȃ<d2d'aR'AS4dCjCB=9%hS@A+%#',b\);D)LC/C=:8#?DB10 tBdԔ@$<ԃ-8A d9 9 @F q4P(I=?.)tF@ 9C:?D,(C46Hy<+BB/=λ!n#4mz08 @1&i&'?ЋA,!(CW?\4C,P-,l;!X*,(s6C48A='$%:փ#((&0Q,>@C04&B=} %@@C"P>f0l"A85r?#̌5@@r>89Cm A C3%xe+8N1l77+ Ж̅A4k&6CcO؂;܅>$C]D@xA&C4(8 /? B(-*9+,q/C=f/Ef)=ivFS;$;plo $&6/$6z3,;C;B2B,)0 0{*&)- N2D)@H8Ѐ ,PԀ;>_. *ij1ª"p,C4̀ Ā$t"hA @d5[3%F"?$A&AO(0A]Z9 JC**>@f/ CbL`-GtԒB2'` AlX7/aV%x%̋a>H(5C>>4gs7ψD2cU@ 9X&6hS A=Vr^6(C0(4 ~K'uaC05$=HC!B4uv;,d0@-^i׊K%%_#+*?> Ā럍@00F48܃$\Tl2^,\'zv-X#~#P*@$X%41؃];LCfsb -M\I'g'0ƻA hQ-4@q>\R¶]>; <ԃqC @7>W텰4.0( m(ė A0`SyD/s*l-vjRZB.46Ú'X@ @xC?xBJ۲E/RC/&@ ,;X4$/\8_ ^*r郯_|o*@n-B*lj_B't*pz;2Cu+XM+]Ã8BoFh1`|0g/%1.Tr_5C/Bjl^1'@5Cl>T?PZ^B/H: ;L**D<.Lgz YIF.LC;^ԃ;>4CFk3ebD*Ђx;=žug:$7$Kdû7-%(jZ#X êklΈ2PGLfbf5@ȹΠB׏_?ӷ/(Ȑug.ARWSp %F(Qrs'9 =d1iC9 4C=,r$C=GD> "Duɿ*1p0'KN4jM@,O*BV IJʒKŶXTlLq` ,0X-K4[{-J9òƌt&Z/k3/+$K 650 c8N@N_8A(@vDDEaa(a8+$H<TR+>*.g:EVCٵ]iTpbqVt[pAM ֢ĬgEX["'\ΌZHZ7f3B_4Yθ "h<| )Ou.X?&G /?SP=ST2O4NF‹VyeъyYUĜ؟[_W 8L 3]iR&ӽߋNW&Cn9l fv;Tϛno>8`F*oT'Mv)9YB!:AB)bNe*$bYeg "\n-\ -L` -Jv17s$3ܛC>I#t|!TE)3;9Pg9:+4qFaDǨ$"O4qnT!!XrIdZF"},p;[]u~ VU06KRCP7 RF$=bؐ mJNVX;"z<$)<rOOU~BG,5(洔&҉2y D0 P6 B"-tX` kv$(f 4<5MzL#HG91:G8Jjׄ6M8diCv "]WoFfI& Cҁ=btN<ДSjQO7Q ATJROǿ&:P. j*]VϬ^eWZТ+EW&ъmt\gA5t7S4f8Q̗瀩3<$737֌zpR'U= JdUr 0Bϫij*ke-b15 `Mo79%؎Æ8!xBR D)/$Uxʸ=y38bϷ#NDsSgUT ss\B!Uҳ.2S41aB#.x7&q3o{ | $=̙# n>`tTR큘#Mنs T̉qT岲UX,3ӠHH-Uրª?! , V@" (H4E-F$9^l( &'[ҋM/5qdÓM5l6nړ ўr$MzGN;lܙCU꠫wj5dhWu-ĨYGw֑۴nGQ]v)ݫ_'OBeRCi⍣HE|ԩS*"E*g-arE<#GxJamx9E^#s\5GoBdg{^eWX'Y׃nQRI|Eډ%MZ(raU*shETdPQ zЏ~FhD,K=aDKv=tEuPwnP2ցcqUx^uWzRW/Zsnhb&Ia vB'12eJ?2erfSB훌BniB:P:@2BўIKTEKuXeQ]M95TY_%HާUXbu?o|ݧ~H%vVbM–PCQ&ʐbNpc?[{È?ARJŊ`#iYXӿ<0_D&d2 f9TW,PӛuҠ!BY֭EK!Uwq! M:ѩuIZsWd}>|1[%ғ7ow%F2۴0{94 ;G1S@9as 2 BJ2DG$g;baHOBCG5-v̰fE4goɑu7vȕ'5=AWl0ڰX}Q P0  Q o' `Kob 0  g.EXX}QSd? R!q!!3) !f@N6z{][VKqhVO+CA,  BZPԢ%`-p 8h ḛOpB``p` N@A /#k\rV'gxw6v E Am_pxN""#2!CPBr{RaU `?Vn;iA[ppg`W ́5AiP˥ @ K15B MV0?5 ͸ P]qC 'r'X6 Eu0a RX88#1wg! ߠ1S}x vts9Q4Zp-[  p wheC\k`v@gm `CQKSJ(1pb-.QA` ]jQ T1@KЌ`PpO }]k WfE0B?m(p ͠  vh@:9am`>gρ$\+ D  1#LGA @*H.CT2ܡ%Vtr 0TT$ RB ]p'|B О`lkjEo'QayuF? ` ``` `!``uW8! up_   n,Qa1r$C3l g@zVՁ4bJ8 }0 ciCӒ+?a 5?5!2 `@ @ TmBuF X:z1KH  ` p 20p " @r@4V:p0:|Kc:%I1Q߰a0i g"=Oa5RZ# P /2@ 0{װ^RH>0RxxLbiSgFq8F8 f!Rz c!2 "v" P^pIE[0P P ]l Ϡ 0pR O Av*G-A r4$;1cQw0 È `e kCb"&uUL.s D@ `pZ}@ 0]`!/uR4Ґа_{@džf  ! `0X +HFV 0Z ;˼ p p  [[p 7sQ%ʡ{$ \@q @ @ 9` AQpU )  0 ӍkP@5@p -IP` e(ʆf p Ҹİ  u X PF4P ՠX̼ P  w0kt:ɠ K((%Z  @i`%j0`e0PawB5W k08Nq zkp0 P q0밦 "C ѧ0]`:Q0 ZI+< J&ӡ,0P ؏-3;  p$0 31 @ۙG  @ ,Ϣ4U`pۅ ֐ \wP(PQ@ wEDaj"}@/Rb|,@;I+nh C `ߠn1-`_fad_MY8 B X  V Pm e(OP3.42޼ ܀ L p0 pD kO`pIvЫQpے *i0` mЙ;`)  ` P0Qw ~nPC-R]EdT^G K+0+90,06T @ 9LJx:s_ Y!0!F(` ' İ1pI)3ڎ31^ : 'z Ȁ f` N5{f`S@ V0lp ] j:v= u.~6j 0>TT q+6@y4]Sf F`q!0X@0@+[XRF~ZoD6^&ߝ~0СWۿn㺕CRdgԩ_?|ܐqwO[ -欜Yce͚3qjL0alfŊsBe" H'莿5eX6;ro;w4^oҢk(PAӧoV,Z|nb<:A#+R#FfӮd)bҤ-=x:դ&K)=x'<ex3Rw7\?~ Eѷ)9[4O0X^}k H 6%Qt\nyhȢ~ƚ wu0as`lY=%;Z5D-* 6b0yI ;اTX'9" +L_c#+0$Fe>D8ZV-XpbW9qW^AERq-Egs~8D: %(:K4{܇~\zWq p9WLL1e(V J" {8 bqФ裒 4 eIL-!E)xFrd 5rB@'|E`z ,&Ƣ (HWgb#dԘK9k}~LK颅MN~^!%q* ѥUESgU:M<M)1'էrⰅ(f)l1EB$#2ccQ'JTqv9r>Dg+\p fBG^;GaodB: +a|F6V)I,ip0xse^J ~Xa(R@B'p^g9G#:ZF֌ea hXG;귎W$xX7QƑ*!; "o%9Fmhsh>xa@64(G䒀D(zMQbs&N]X1  iZ/q(=iN(PL0DcR͐FrG0@4ᔖ"~:zAAF1@Z p U  ECCi-Dڰ!w wA,pb\ "dw1  $жPaoCs# B*x2 %bC%p~PFXu]0Yo@>FTG^!EQ &=)}T8)H ^H3p R"ƣ -?!TF* a[@uAŅ =܀0'dDop3B={cZ=+aHU?H Tu:jiP"sdw#P:&sH"@% E$xA8au QZx&`-AD!@mDr/ ֮}mL3G3~{w@a~X1N+ i|]Ų, ~TF5>qOhV22Q uNQ[pqH!2hTyHH$al`2L+! RnGMd!$-Pw,r t6k }F ^ ~?bb샐D>@wB Z4c7hXhG/tbY*~rԷO MhcF0!yd?#PqWUBT|\%-G5,jp6Z2 _Ѓ&" yVf] ? -ȁG=~.zeb(5`t)L9:` `Xaf0%X%P u`^8F115$~XyxyX(0tІkp$`}`z1wxHGsxT@MzD*}L`EІ̐ 22i7x%2p.xL !oPt$0hЇ1wZPHT0S=i("0a0g+(DĸG8cPhqH+5 ~@EJh,1R0}y8zEk{aq>?z3= +Pw#X&8#p%}f0O .P(HD@!@ӈo@kxuH@PǶk;؃p;ix\^Ce(yo@H8u@Xm4} 2 }hV+;1' %`8zz=؄4 ^X"+2?Cb# g@8Rkg0_[UJ z>@_p>pߒ|ghױ`{zs#i5` D3l568hWhH&HmP`Qxo; PCp{,t\MwL8xhDYY fAJhM`$h Mxxox((.  [ `uX}Hy؁M `x4 %8`kSV %!h81CPJ]HĖ>IZJWq룆E>Ȃ(X~Ng#Z@d X|vCЇ48A5E: }`U(H0{Ȍw@Z. 21wHS8I: Xh6<%2PPu\MTG{ Q6ڰH qPx}wP @qY#($ mq؇` 7hT2^8qR!WfӤ. 81įU{wb#R4Jp 0K0dx]KJPtVDlPn8{LQ4@2gN(9\;{@5rr0!6@2X(s؃q`ZBhU%#$T /  k}`3=P N\ a9VwXΛx8sHb@rE`fKmӇW{Hs܁#~< "1X`S(~H>801Ӆ DfQgJhEX7VvPј0xK;}x@8k62z03JD}؄&V4ee (7(?*+#@A\F5=S@E/ڰ [PhXAAA]NFx㘇`h1YL̈́y8Kj{tA'Pc1R/=,8R48GXD]] cgUQPLQSv~`YE;itp)a㈂}:2 ӥbbQHh@&4`X  )txD0Fwx:~TP!`Hp#@Aw,Yvx0PF~p A PJ`:wPkh=~HLw0?[$Q.s%!qRC$^h'$[ 6Vd)/P cR(]R|῝IXaf-kK@3ޚ؄өyBHmP2X:R(!b .48ϰ*XxS0A0mA6u 5sLp؂%4;D}SbxHpI/.jA%\li8/Œ{x{V[ip =$$;~`*^uE[UbsH ʫ4llgg3`:5^15X}؇e+5 5W~)#ts`P MpFj&P,$ϔt2+9(؃]{ *`/ F% C% 4b]P`~ژ$ I'jHd߇N؇WHo XpewV}؄! Lvi y~[аS 2kc#RO)pVQ)h[PpFEEg{7`VU~^p58H`hY btt ဇS%h!R X=؃K k*0&#:gC@ i%SMI2PD@́A՟$yBEӋY'H~h{'n#'8H/w3jL,S&iGNR [ O߼}hɝ*)~iVnbEkYSƋ?%A:E* aElo_U (2L@0pԒK/?|"x`xQE.sQGYEQFa(vsQ!̳U\uuVD3?e1e0K(̜3>Ș5˼$A"Y*bi&]q$ͤ?2#h# 9 I2IP70O!??@p!h6)C N?#*䴐:i3tWCѼ5J@E?4A(%4}udL҈prDLhh[=븼>A($4#!3,!H }/#2 9Ĵdr?xD@>&,Q?O1B@$ybrH&`Ã~hQ`Pqd1(1XbI/! F LH+L0;JױaSs5GA7w1K#/ ab9efi 4Gp2 m8b8<d5 AВ P81G4ArDІ6 i E  Rm^c;~-A?AIr )䓐'>\m fЁ &IiDGF=0@|pЀ, c@00YP7*0$!Wc4G<ͣWʠ0Aa +L45!6! Y` 41%1?3ApB<0H(^%(@3 ?X (jF>ҡ [<Րc$8C ~C?K}hȁ4<s\11_6 k!Yl}>C`"0 Qr we'n jP1 T*^Vlx0))VeZ 0_Ycsh0i0BPD W!Hf A X,ʚ`A <`7Ȉi8A2)zAYbHD$p|"ʨ?BAPjN G:0h\X(:]b0T8EC!D,,f~2 & 0`&Έߛb0&nP=f\.쑏\B5X ĸh|E$~c"Q6A3A$,aj$j(V]<, (@A FЂ7TDYTQ5Y1Bmw.xG=oXG42mXC: s8;я!-`n(\莢K:A{@4h iC=!,҇>iEEYSx(G1l`ᢉL L@#",(> {Ԛ xяud(rͬ)h>bb Kshyr (xry>̡`5AA0b=Dl2DXv?# ,38V D49N $`%?\qϔF8r &=ݽU30)A+ZVw#EX$5:@Su M̰ R ʅ8z!  ?Q"5Pgh^* Q#6,fB+A CiB8(gKa :1|4 %(яt%p?C8*a :S&a EtAsh̃z@ ~@wh|#@Cu3hC8t-)5`t ?YAB*,`~xPB=C \?d"A`HBR!\.ȁ?4ˉ])˜Z7W0,A]@8 M.O,%4Ch08A#J@ 34:='tf4F@E*uC;PBGwBy>OP! %$?cyȄDTHX4h{ɁK#5-%X#=JR'I!B=x9) Bbq'0=: pL W4a 䊩eB1x@q@;H,F 1 B!9Hv@ ;C3X z@. :A@* B5j4?@ ]@ B:7d2lC+tWa ,BV@!8s$7@gUQ/ M?G´0,CX9HC&$+J:aAtB!b4P4xP_.= &/x)*F dBלZ4{B>@uP=4C0p<@iPB"0BI;CyB~5C= @ym'i|Up=$v4:F -@@+X=XJ"?;<l@ @<;4h, 8C8!)B,)BAb6m9\*t-A P. ]8@0Ă;C' ;@ 0BZq>,!28mBa)EO.Q3ԃ39$ā؀$9x=)I-CA@Bq(4?DׂZ2L,n*"hVA'h|%$%|>9-~Z2X5 ֟Y;*<.yH/46@ /C39C%*1/?~T¼BW[!n7]iǧ)g1B%1gxVDmr^QթA;HC+_a-͏ .?C)}溕DQ3pd Bmt1|:[ F6b<-Z6DB j GA1( -8C=Ug;B'0.K'D[1X; vQ/ABB`/u?/}4ahͫt*&yJ{o28@Ƀ7~yC PԦRX. Y )ÚSBT'%:4%P{fB*HC;D`19B/г@j^=PQ"J +8%O?~@£Ej9RF"%qTRK\<{QRL)VHZE7x8[ ֩UT[jN׮䄕FMXre6cݺ-[6s޹3'-T۲rԐ u읰jԜech.^eɐX :' w- tz F`&9qژѲz> d8%VzZU GK]OT!CK>dH|y4Q EK۹uIH<|e(OR饙i$Q<IiTXQ(Vdin\V*+;-5J2,,6ڊ@q#EQkFcQPLQ{+58 d$Lh@KͳA~>$N5+ aGpT7Frd簻;Y(;FsȻs<@)"Jk?M:dBRKI%| $J)\J)gT3L. C >:+{+0ۂ,lD. -T4%o|-A @꣫,K>4D ΄cAN\AL89$ΐBҤ3OhPG ,1ϼJ ԓdJtRK#/A&<u%"e$ZOOᐪa-YDL3cKj+F@3Sc58C+i4hbVBiwx)ykN5xC{Ӕ98m<TO<)JL%qǨ˪ÒY4K7y痗hѴD5J{-|w㤗{;߷OSN/ `"H=ܒJ)Mg>TRtd(D>]E)=y.x.-IVDeKeR,]&Hz k%n"=\];$' zYWosqJt!B@lj0w'wC\G<Xz(щg"+T' @CI`"|?R@ -S#ʧBWu+y-ȓa -Eg^ iXB y&Hf[Z-zN;װWk+Zڨ1h >Gbb*1')"s%4ԱD#6hUjiJT1(Lg IF4\őXE+>cZAF2VbId=Hx&5iPc%bA]'>ސ\d2z_r 4 䗰) IEB'/aܤ,hң O)'a|JdJYqAd 43U%Ǥhkq[J$05މI>b@!2[x\\NssS^6E_('TB 14A@o!}ʦ#yUMS0? (eLD:HcCh5fnQZ` ti6CQhZVhjj /Ù9ALPh+8@ϚeireN]xc?m nzW(:#`uImʜoa2}J)FȆ3h*Zl4 dݫit3lAwGaVWUkʙĞumDLG89Ms؄fMpj[fCEQ:v2C&( P'3~s2L0=zCNr"*wϥc%K*IO5Tq*\Ey@lDʬϚ2(K-l/Sk ST ŎԚ7XINo/R3Cb%>2|✫:NuߠS5Pu{8DƭusE9$R"2 Q/ -ϖ*, ؄k3XR,Xy%Pҭפ7ƮF83uWg;{1y㳾a숧H#n0u4anVucOnOU}A4[IzHDP@;libnsgif-0.0.1/examples/disassemble_gif.pl0000755000175000017500000000417311126561232021057 0ustar dsilversdsilvers#!/usr/bin/perl # # Disassemble a GIF file and display the sections and chunks within. # # Warning: only part of the specification is implemented. # use strict; use warnings; die "Usage: $0 IMAGE\n" unless @ARGV == 1; my ($image) = @ARGV; open IMAGE, '<', $image or die "$0: open $image: $!\n"; undef $/; my $gif = ; close IMAGE; print "$image: ", length $gif, " bytes\n\n"; my @gif = unpack 'C*', $gif; my $z = 0; output_chunk('Header', 6); output_chunk('Logical Screen Descriptor', 7); my $global_colors = $gif[10] & 0x80; my $color_table_size = 2 << ($gif[10] & 0x07); if ($global_colors) { output_chunk('Global Color Table', $color_table_size * 3); } while (1) { while ($gif[$z] == 0x21) { if ($gif[$z + 1] == 0xf9) { output_chunk('Graphic Control Extension', 5 + 2); } elsif ($gif[$z + 1] == 0xfe) { output_chunk('Comment Extension', 2); } elsif ($gif[$z + 1] == 0x01) { output_chunk('Plain Text Extension', 13 + 2); } elsif ($gif[$z + 1] == 0xff) { output_chunk('Application Extension', 12 + 2); } else { output_chunk((sprintf 'Unknown Extension 0x%.2x', $gif[$z + 1]), $gif[$z + 2] + 3); } while ($gif[$z] != 0) { output_chunk('Data Sub-block', $gif[$z] + 1); } output_chunk('Block Terminator', 1); } if ($gif[$z] == 0x3b) { output_chunk('Trailer', 1); last; } if ($gif[$z] != 0x2c) { last; } output_chunk('Image Descriptor', 10); output_chunk('Table Based Image Data', 1); while ($gif[$z] != 0) { output_chunk('Data Sub-block', $gif[$z] + 1); } output_chunk('Block Terminator', 1); } if ($z != @gif) { output_chunk('*** Junk on End ***', @gif - $z); } # # Output a chunk of data as hex and characters. # sub output_chunk { my ($description, $length) = @_; print "$description"; for (my $i = 0; $i != $length; $i++) { if ($i % 8 == 0) { print "\n"; printf "%8i: ", $z + $i; } if ($z + $i == @gif) { print "EOF\n\n"; print "Unexpected end of file\n"; exit; } my $c = $gif[$z + $i]; printf "%.2x ", $c; if (32 <= $c and $c <= 126) { printf "'%c'", $c; } else { print " "; } print " "; } print "\n\n"; $z += $length; }