Re: [boost] [gil] Can not open test.jpg

Christian,
This file needs to be swapped out. Will do that next week. Done. Thank you.
Marius, do you wanna try out it the new gil::io? It's located here: http://gil-contributions.googlecode.com/svn/trunk/gil_2/boost/gil/extension / Will it be available in 1.43?
Let me know if you have questions, problems, etc. I have one suggestion: Gil::Io extensions do not work without required libjpeg libpng, libtiff ... There is no way to run examples from "boost_1_42_0\libs\gil\example" without required libs. There are problems to match boost::gil and "external graphlibs" i.e. http://stackoverflow.com/questions/2442335/libpng-boostgil-png-infopp-null-n ot-found
I think that libjpeg libpng, libtiff libs should be included into boost and compiled with use bjam. Regards, Mariusz

Mariusz Kwiczala wrote:
Christian,
This file needs to be swapped out. Will do that next week. Done. Thank you.
Marius, do you wanna try out it the new gil::io? It's located here: http://gil-contributions.googlecode.com/svn/trunk/gil_2/boost/gil/extension / Will it be available in 1.43?
Let me know if you have questions, problems, etc. I have one suggestion: Gil::Io extensions do not work without required libjpeg libpng, libtiff ... There is no way to run examples from "boost_1_42_0\libs\gil\example" without required libs. There are problems to match boost::gil and "external graphlibs" i.e. http://stackoverflow.com/questions/2442335/libpng-boostgil-png-infopp-null-n...
I think that libjpeg libpng, libtiff libs should be included into boost and compiled with use bjam.
Personally, I don't think it's a good idea to these libraries included in Boost. It may cause number of problems, versions compatibility, duplicated There are Boost Build extensions available which allow to build 3rd-party libraries in fairly easy way: http://svn.boost.org/svn/boost/sandbox/tools/build_extensions/ I did some experiments 2 days ago and with success. I'm going to try them with Boost.GIL soon. IMHO, the build extensions are the right way to go here. Best regards, -- Mateusz Loskot http://mateusz.loskot.net

Hi there,
Marius, do you wanna try out it the new gil::io? It's located here: http://gil-contributions.googlecode.com/svn/trunk/gil_2/boost/gil/extension / Will it be available in 1.43?
Yes.
Let me know if you have questions, problems, etc. I have one suggestion: Gil::Io extensions do not work without required libjpeg libpng, libtiff ... There is no way to run examples from "boost_1_42_0\libs\gil\example" without required libs. There are problems to match boost::gil and "external graphlibs" i.e. http://stackoverflow.com/questions/2442335/libpng-boostgil-png-infopp-null-n ot-found
The new libpng seems to have thrown out some symbols. I have to check my io extension, as well.
I think that libjpeg libpng, libtiff libs should be included into boost and compiled with use bjam.
Don't see that happening. Regards, Christian

Hi Christian, Christian Henning wrote:
Marius, do you wanna try out it the new gil::io? It's located here: http://gil-contributions.googlecode.com/svn/trunk/gil_2/boost/gil/extension
Will it be available in 1.43?
Yes.
I was hoping that there would be a proper review of this, but I understand and sympathise with why that hasn't happened. Nonetheless, if you consider it's now finished and ready for general release, can I encourage you to encourage others to post their "not review but review-like comments"? Sorry if I have missed any announcements; I've not been glued to my Boost email. Regards, Phil.

Hi Phil,
I was hoping that there would be a proper review of this, but I understand and sympathise with why that hasn't happened. Nonetheless, if you consider it's now finished and ready for general release, can I encourage you to encourage others to post their "not review but review-like comments"?
Ups, I think I misunderstood. The new test.jpg is going to be in 1.43. My submission is still waiting in the review loop. I have a review manager but he is still evaluating what he is getting into. ;-) Nonetheless, I remember you made some comments a few years back ( 4/27/2008 ). I consider them mostly minor updates and have focussed my effort more on high-level features. But they aren't forgotten. Here is a list what you were suggesting for jpeg format: - DCT type: You can specify the type when reading an image. - Scaled Decoding: Todo - Never figured out how to do that. Couldn't find anything on the net. - Partial Image Decoding - Same as Scaled Decoding - MMX/SSE - Not necessarily this extensions problem. A user can use whatever libjpeg. - Rotation: Same state as Scaled Decoding. - In-memory jpeg: This is done. Please see unit tests. Regards, Christian

Christian Henning wrote:
I was hoping that there would be a proper review of this, but I understand and sympathise with why that hasn't happened. ?Nonetheless, if you consider it's now finished and ready for general release, can I encourage you to encourage others to post their "not review but review-like comments"?
Ups, I think I misunderstood. The new test.jpg is going to be in 1.43. My submission is still waiting in the review loop. I have a review manager but he is still evaluating what he is getting into. ;-)
Ooops, sorry.
Nonetheless, I remember you made some comments a few years back ( 4/27/2008 ). I consider them mostly minor updates and have focussed my effort more on high-level features. But they aren't forgotten. Here is a list what you were suggesting for jpeg format:
- DCT type: You can specify the type when reading an image.
That's good. And writing?
- Scaled Decoding: Todo - Never figured out how to do that. Couldn't find anything on the net. - Partial Image Decoding - Same as Scaled Decoding
Well, I think both of those things are described in the libjpeg documentation. If you can't find it and are interested in implementing it, please let me know.
- MMX/SSE - Not necessarily this extensions problem. A user can use whatever libjpeg.
OK.
- Rotation: Same state as Scaled Decoding.
I agree that this is not well described anywhere, but the program jpegtran can do it.
- In-memory jpeg: This is done. Please see unit tests.
The last time that I looked at your code - about a year ago - my problem was to take a very large TIFF and to chop it up into 256x256 PNG tiles. I wanted to do this without having to keep all of the image data in memory simultaneously. This seemed to be beyond what you could offer. I'm unsure whether or not it's fundamentally possible with gil or not; I had hoped that its idea of "views" would make it possible if the views could lazily obtain the data from the source image. Even if gil can't do this, it would be good if your libtiff/png/jpeg wrappers were usable for general C++-ing of those libraries. I also recall some concerns about how you were handling errors from one of the libraries. I think you had a setjmp() that was bound to fail, or something like that. Anyway, I am glad to hear that you still plan to have a conventional review for this work. Regards, Phil.

Hi Phil,
- DCT type: You can specify the type when reading an image.
That's good. And writing?
Just added it. Good idea!
- Scaled Decoding: Todo - Never figured out how to do that. Couldn't find anything on the net. - Partial Image Decoding - Same as Scaled Decoding
Well, I think both of those things are described in the libjpeg documentation. If you can't find it and are interested in implementing it, please let me know.
I would be interested in a pointer to details of Partial Image Decoding. Depending on the amount of effort I'll either add it now or after the review. My time frame is kinda small right now.
- Rotation: Same state as Scaled Decoding.
I agree that this is not well described anywhere, but the program jpegtran can do it.
I consider this a "nice to have". This extension is about IO but again if it's easy to integrate I'll do it.
- In-memory jpeg: This is done. Please see unit tests.
The last time that I looked at your code - about a year ago - my problem was to take a very large TIFF and to chop it up into 256x256 PNG tiles. I wanted to do this without having to keep all of the image data in memory simultaneously. This seemed to be beyond what you could offer. I'm unsure whether or not it's fundamentally possible with gil or not; I had hoped that its idea of "views" would make it possible if the views could lazily obtain the data from the source image. Even if gil can't do this, it would be good if your libtiff/png/jpeg wrappers were usable for general C++-ing of those libraries.
You can read subimages from a tiff image. At least in theory, I just noticed a bug when trying to do that. This bug is only with tiff images. All other formats work fine. Once that's done you have a gil image which you make into a png without writing it to a file. You can use std::stringstream instead. Here is an example of doing this taking from my unit tests: BOOST_AUTO_TEST_CASE( stream_test ) { // 1. Read an image. ifstream in( jpeg_filename.c_str(), ios::binary ); rgb8_image_t img; read_image( in, img, tag_t() ); // 2. Write image to in-memory buffer. stringstream out_buffer( ios_base::in | ios_base::out | ios_base::binary ); write_view( out_buffer, view( img ), tag_t() ); // 3. Copy in-memory buffer to another. stringstream in_buffer( ios_base::in | ios_base::out | ios_base::binary ); in_buffer << out_buffer.rdbuf(); // 4. Read in-memory buffer to gil image rgb8_image_t dst; read_image( in_buffer, dst, tag_t() ); // 5. Write out image. string filename( jpeg_out + "stream_test.jpg" ); ofstream out( filename.c_str(), ios_base::binary ); write_view( out, view( dst ), tag_t() ); } I hope this gives you an imagination of what's possible with the new io extension. Is this what you have in mind?
I also recall some concerns about how you were handling errors from one of the libraries. I think you had a setjmp() that was bound to fail, or something like that.
I'm using setjmp in the jpeg and png specific code. Regards, Christian

Hi Christian, I've just had to remind myself what this was all about. I may have forgotten or mis-remembered something. Christian Henning wrote:
- DCT type: You can specify the type when reading an image.
That's good. ?And writing?
Just added it. Good idea!
- Scaled Decoding: Todo - Never figured out how to do that. Couldn't find anything on the net. - Partial Image Decoding - Same as Scaled Decoding
Well, I think both of those things are described in the libjpeg documentation. ?If you can't find it and are interested in implementing it, please let me know.
I would be interested in a pointer to details of Partial Image Decoding. Depending on the amount of effort I'll either add it now or after the review. My time frame is kinda small right now.
I think the situation was that you were decoding and discarding the stuff after the area of interest, which was obviously wasteful and fixable. The more difficult issue was whether it is possible to reduce the work done prior to the area of interest. I don't have a good enough understanding of libjpeg to know the answer to that. Presumably there are similar issues with the other formats.
- Rotation: Same state as Scaled Decoding.
I agree that this is not well described anywhere, but the program jpegtran can do it.
I consider this a "nice to have". This extension is about IO but again if it's easy to integrate I'll do it.
Unfortunately it's not always possible to respect partitioning like "this bit is IO" when that breaks the performance. But again, I still don't know how to do this rotation. I have a feeling that there really aren't many people around who actually understand libjpeg properly...
- In-memory jpeg: This is done. Please see unit tests.
The last time that I looked at your code - about a year ago - my problem was to take a very large TIFF and to chop it up into 256x256 PNG tiles. ? ?I wanted to do this without having to keep all of the image data in memory simultaneously. ?This seemed to be beyond what you could offer. ?I'm unsure whether or not it's fundamentally possible with gil or not; I had hoped that its idea of "views" would make it possible if the views could lazily obtain the data from the source image. ?Even if gil can't do this, it would be good if your libtiff/png/jpeg wrappers were usable for general C++-ing of those libraries.
You can read subimages from a tiff image. At least in theory, I just noticed a bug when trying to do that. This bug is only with tiff images. All other formats work fine.
Once that's done you have a gil image which you make into a png
So for my problem of chopping up the TIFF into lots of tiles, I think I have two choices: (1) Decode the whole TIFF into one gil image. For each tile, create a gil view and create and save a PNG. (2) For each tile, partially decode the TIFF into a gil image, and create and save a PNG. The first choice uses lots of RAM. The second choice uses lots of time because the partial decoding has to decode and discard all of the content that precedes the area of interest. Is that true?
I also recall some concerns about how you were handling errors from one of the libraries. ?I think you had a setjmp() that was bound to fail, or something like that.
I'm using setjmp in the jpeg and png specific code.
In jpeg/read.hpp you have a namespace-scope static jmp_buf. I immediately worry about thread-safety. Even in a single-threaded app I can't see how this works if you have more than one jpeg file open. Then you setjmp() in the constructor. The jmp_buf is invalid as soon as that scope returns, so if libjpeg calls your error_exit() from after the ctor has finished (e.g. in jpeg_read_scanlines()) it will crash. (Have I grossly misunderstood how this works?) I haven't looked at your other uses. Regards, Phil.

Phil Endecott wrote:
Christian Henning wrote:
- Scaled Decoding: Todo - Never figured out how to do that. Couldn't find anything on the net. - Partial Image Decoding - Same as Scaled Decoding
Well, I think both of those things are described in the libjpeg documentation. ?If you can't find it and are interested in implementing it, please let me know.
I would be interested in a pointer to details of Partial Image Decoding. Depending on the amount of effort I'll either add it now or after the review. My time frame is kinda small right now.
I think the situation was that you were decoding and discarding the stuff after the area of interest, which was obviously wasteful and fixable. The more difficult issue was whether it is possible to reduce the work done prior to the area of interest. I don't have a good enough understanding of libjpeg to know the answer to that. Presumably there are similar issues with the other formats.
AFAIU if not fast ROI access (or tiled) is supported by a format, then by scanline access is necessary. I'm not libjpeg expert, but it's scanline oriented. For example, here is IReadBlock function of JPEG driver from GDAL library: http://trac.osgeo.org/gdal/browser/trunk/gdal/frmts/jpeg/jpgdataset.cpp#L841 It uses LoadScanline function: http://trac.osgeo.org/gdal/browser/trunk/gdal/frmts/jpeg/jpgdataset.cpp#L112... IReadBlock performs optimal reading for particular format and raster size. In JPEG, block is a single scanline: N-COLUMNS x 1-ROW In TIFF, it is possible to perform tile-based reading, then I/O is based on blocks of tiles but not scanlines. It is noted in performance optimisation guidelines for warping (resampling, etc.) here http://www.gdal.org/warptut.html I give references to GDAL library because it has been my main raster I/O and processing tool for long time and I have some experience with it. I think it could serve as a good reference on how to perform I/O efficiently against large datasets in various raster formats. Personally, I'm strongly interested in developing some of GDAL strategies for Boost.GIL, as extensions, for instance some algorithms, resampling, I/O strategies support (scanline, tiles, etc.)
- Rotation: Same state as Scaled Decoding.
I agree that this is not well described anywhere, but the program jpegtran can do it.
I consider this a "nice to have". This extension is about IO but again if it's easy to integrate I'll do it.
Unfortunately it's not always possible to respect partitioning like "this bit is IO" when that breaks the performance. But again, I still don't know how to do this rotation. I have a feeling that there really aren't many people around who actually understand libjpeg properly...
I may be missing what is this idea of rotation here, but if it's rotate while decoding, I doubt it's possible.
- In-memory jpeg: This is done. Please see unit tests.
The last time that I looked at your code - about a year ago - my problem was to take a very large TIFF and to chop it up into 256x256 PNG tiles. ? ?I wanted to do this without having to keep all of the image data in memory simultaneously. ?This seemed to be beyond what you could offer. ?I'm unsure whether or not it's fundamentally possible with gil or not; I had hoped that its idea of "views" would make it possible if the views could lazily obtain the data from the source image. ?Even if gil can't do this, it would be good if your libtiff/png/jpeg wrappers were usable for general C++-ing of those libraries.
You can read subimages from a tiff image.
Do you mean subimages of multi-image tiff? There is also an idea of overviews and tiles. I'm not sure if all TIFF container variations are supported in the GIL I/O. I hope to find out while I'm reviewing it.
Once that's done you have a gil image which you make into a png
So for my problem of chopping up the TIFF into lots of tiles, I think I have two choices:
(1) Decode the whole TIFF into one gil image. For each tile, create a gil view and create and save a PNG.
(2) For each tile, partially decode the TIFF into a gil image, and create and save a PNG.
The first choice uses lots of RAM. The second choice uses lots of time because the partial decoding has to decode and discard all of the content that precedes the area of interest. Is that true?
You may try to read by tiles or whole strips of scanlines and cut them to tiles. Best regards, -- Mateusz Loskot http://mateusz.loskot.net

Hi Phil,
I would be interested in a pointer to details of Partial Image Decoding. Depending on the amount of effort I'll either add it now or after the review. My time frame is kinda small right now.
I think the situation was that you were decoding and discarding the stuff after the area of interest, which was obviously wasteful and fixable. The more difficult issue was whether it is possible to reduce the work done prior to the area of interest. I don't have a good enough understanding of libjpeg to know the answer to that. Presumably there are similar issues with the other formats.
For now, I consider this an optimization. I someone can show me how to do that I would be willing to add.
So for my problem of chopping up the TIFF into lots of tiles, I think I have two choices:
(1) Decode the whole TIFF into one gil image. For each tile, create a gil view and create and save a PNG.
Depending on the size of your TIFF you might need to use the BigTiff lib. You probably know that. If you are working in x64 why not load the whole thing? RAM is cheap. Unless you have your image is several TBs. Like this one: http://www.aperio.com/bigtiff/#Sample_Images
(2) For each tile, partially decode the TIFF into a gil image, and create and save a PNG.
Tile-based reading is being worked on right now. But as far as I know a tiff is either scanline or tile_based. You cannot read scanlines in a tile_based image and vice versa. I might be wrong, but that's my understanding right now.
The first choice uses lots of RAM. The second choice uses lots of time because the partial decoding has to decode and discard all of the content that precedes the area of interest. Is that true?
Yes, I believe you're correct.
I also recall some concerns about how you were handling errors from one of the libraries. ?I think you had a setjmp() that was bound to fail, or something like that.
I'm using setjmp in the jpeg and png specific code.
In jpeg/read.hpp you have a namespace-scope static jmp_buf. I immediately worry about thread-safety. Even in a single-threaded app I can't see how this works if you have more than one jpeg file open. Then you setjmp() in the constructor. The jmp_buf is invalid as soon as that scope returns, so if libjpeg calls your error_exit() from after the ctor has finished (e.g. in jpeg_read_scanlines()) it will crash. (Have I grossly misunderstood how this works?)
Let's forget multi-thread safety for a bit. During the construction of the my jpeg_decompress_mgr I tell libjpeg's jpeg_error_mgr to use my own error handler ( static member function called error_exit() ). After this, I save the current environment into the marker ( int[16] buffer ) using the setjmp() function. The marker is a static global inside the gil::detail namespace. Once an error occurs error_exit() is called which leads to a longjmp which then jumps back to the setjmp point. Next we clean up and issue an exception. Hope this makes sense. In a single-treaded application how would this procedure be a problem? I mean how can you have more than one jpeg file open? For multi-threaded usage the above is problematic since the marker can be overridden. In case the user reads several jpeg files at one time this can lead to undefined behavior. One solution would be to create a marker for each read operation. Do you thing that's a valid approach? Regards, Christian

Christian Henning wrote:
I would be interested in a pointer to details of Partial Image Decoding. Depending on the amount of effort I'll either add it now or after the review. My time frame is kinda small right now. I think the situation was that you were decoding and discarding the stuff after the area of interest, which was obviously wasteful and fixable. The more difficult issue was whether it is possible to reduce the work done prior to the area of interest. I don't have a good enough understanding of libjpeg to know the answer to that. Presumably there are similar issues with the other formats.
For now, I consider this an optimization. I someone can show me how to do that I would be willing to add.
So for my problem of chopping up the TIFF into lots of tiles, I think I have two choices:
(1) Decode the whole TIFF into one gil image. For each tile, create a gil view and create and save a PNG.
Depending on the size of your TIFF you might need to use the BigTiff lib. You probably know that. If you are working in x64 why not load the whole thing? RAM is cheap. Unless you have your image is several TBs.
I assume Boost.GIL as general purpose library and not specific to particular environment, available memory, etc. configurations. Then, I think it's not an option. I often works with rasters of N GBs (not even TB) and swinging large monoliths of memory around is fragile. What if I have 4GB TIFF image with raster sample size of 1 BIT? Would Boost.GIL handle it? How? Would it it get 8 times larger in memory as each sample is loaded to basic unit of 1 byte, for instance? I think that the Boost.GIL I/O interface should be designed in a way that it doesn't force any limitations and at least allow highly optimised implementation of I/O specific to format. I'd be truly interested in discussing various aspects of handling large imagery in Boost.GIL.
Like this one: http://www.aperio.com/bigtiff/#Sample_Images
(2) For each tile, partially decode the TIFF into a gil image, and create and save a PNG.
Tile-based reading is being worked on right now. But as far as I know a tiff is either scanline or tile_based. You cannot read scanlines in a tile_based image and vice versa. I might be wrong, but that's my understanding right now.
Or srtip-based - a chunk of scanlines. Best regards, -- Mateusz Loskot, http://mateusz.loskot.net

Christian Henning wrote:
Phil Endecott wrote:
In jpeg/read.hpp you have a namespace-scope static jmp_buf. ?I immediately worry about thread-safety. ?Even in a single-threaded app I can't see how this works if you have more than one jpeg file open. ?Then you setjmp() in the constructor. ?The jmp_buf is invalid as soon as that scope returns, so if libjpeg calls your error_exit() from after the ctor has finished (e.g. in jpeg_read_scanlines()) it will crash. ?(Have I grossly misunderstood how this works?)
Let's forget multi-thread safety for a bit. During the construction of the my jpeg_decompress_mgr I tell libjpeg's jpeg_error_mgr to use my own error handler ( static member function called error_exit() ). After this, I save the current environment into the marker ( int[16] buffer ) using the setjmp() function. The marker is a static global inside the gil::detail namespace. Once an error occurs error_exit() is called which leads to a longjmp which then jumps back to the setjmp point.
It only jumps back to the setjmp point if the stack context in which setjmp was called is still valid. setjmp is called from the jpeg_decompress_mgr constructor. You make libjpeg calls (e.g. jpeg_read_scanlines()) after the constructor has finished, right? This will cause undefined behaviour if errors occur in those calls when it invokes longjmp. (Have you tested this?)
Next we clean up and issue an exception. Hope this makes sense.
No, it doesn't make sense. Sorry if I am missing something important. Maybe someone else would like to have a look at this code? It's here: http://gil-contributions.googlecode.com/svn/trunk/gil_2/boost/gil/extension/... near the start of the file.
In a single-treaded application how would this procedure be a problem? I mean how can you have more than one jpeg file open?
Errr... you cannot have more than one jpeg file open? I suppose not. I guess that illustrates the limitations of this approach.
For multi-threaded usage the above is problematic since the marker can be overridden. In case the user reads several jpeg files at one time this can lead to undefined behavior. One solution would be to create a marker for each read operation. Do you thing that's a valid approach?
No; it seems to me that the whole idea of using setjmp/longjmp is broken. But as I say I have only spent a few minutes looking at this code. I would be very grateful if someone else could take a look at it. Regards, Phil.

Hi Phil, let's start at the beginning:
Next we clean up and issue an exception. Hope this makes sense.
No, it doesn't make sense. Sorry if I am missing something important. Maybe someone else would like to have a look at this code? It's here: http://gil-contributions.googlecode.com/svn/trunk/gil_2/boost/gil/extension/... near the start of the file.
My understanding setjmp/longjmp is this: #include <iostream> #include <csetjmp> static jmp_buf mark; void try_something() { if( setjmp( mark )) { std::cout << "we are back" << std::endl; } } void error_exit() { std::cout << "ups we had a problem" << std::endl; longjmp( mark, 1 ); } int main( int argc, char* argv[] ) { try_something(); error_exit(); return 0; } When error_exit is called we are jumping back to where setjmp was called before. Do you agree that's the correct behavior? Regards, Christian

Christian Henning wrote:
Hi Phil, let's start at the beginning:
Next we clean up and issue an exception. Hope this makes sense. No, it doesn't make sense. Sorry if I am missing something important. Maybe someone else would like to have a look at this code? It's here: http://gil-contributions.googlecode.com/svn/trunk/gil_2/boost/gil/extension/... near the start of the file.
My understanding setjmp/longjmp is this:
#include <iostream> #include <csetjmp>
static jmp_buf mark;
void try_something() { if( setjmp( mark )) { std::cout << "we are back" << std::endl; } }
void error_exit() { std::cout << "ups we had a problem" << std::endl; longjmp( mark, 1 ); }
int main( int argc, char* argv[] ) { try_something(); error_exit();
return 0; }
When error_exit is called we are jumping back to where setjmp was called before.
Do you agree that's the correct behavior?
I agree with Phil; that's undefined behaviour. I can't access the official C standard here, but in the C99 draft N1256 (http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf), in 7.13.2.1p2, it says (of longjmp): ... if the function containing the invocation of the setjmp macro has terminated execution in the interim, ... the behavior is undefined. So, once try_something has returned, the effect of calls to longjmp is undefined. John Bytheway

Hi there,
I agree with Phil; that's undefined behaviour. I can't access the official C standard here, but in the C99 draft N1256 (http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf), in 7.13.2.1p2, it says (of longjmp):
... if the function containing the invocation of the setjmp macro has terminated execution in the interim, ... the behavior is undefined.
So, once try_something has returned, the effect of calls to longjmp is undefined.
Does that mean I have to call setjmp everytime before I call libjeg function? This way the function that calls setjmp would not have been terminated. Regards, Christian

Hi Christian, I wonder if anyone will notice this message amid all the mud and flame-slinging that's going on? I know - I'll get everyone's attention by pointing out that the fundamental problem here is that the C library, libjpeg, has a truly awful API design: when it gets an error, it calls a user-supplied function-pointer and that mustn't return. Christian Henning wrote:
I agree with Phil; that's undefined behaviour. ?I can't access the official C standard here, but in the C99 draft N1256 (http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf), in 7.13.2.1p2, it says (of longjmp):
... if the function containing the invocation of the setjmp macro has terminated execution in the interim, ... the behavior is undefined.
So, once try_something has returned, the effect of calls to longjmp is undefined.
Does that mean I have to call setjmp everytime before I call libjeg function? This way the function that calls setjmp would not have been terminated.
Your choices are: 1. setjmp() in each function (scope?) that calls into libjpeg. That's nasty because setjmp(), IIRC, is detected by the compiler and prevents some optimisations. It's relatively non-intrusive in your code though. 2. setjmp() once, and make sure that that is in a scope that contains all the calls. This means turning your code inside out, but it's not impossible because - as we've noted - you never leave a jpeg file open and return to the user code, i.e. the setjmp() can happen soon after the user calls into your code. I don't think that destructors will not be called when longjmp() "pops" the stack, so you need to be careful about what types you use. 3. (deleted - idea too horrible to share.) 4. Try to throw an exception from the error handler. This would be ideal, if you could be sure that the exception would propagate through the C code. I believe that gcc has an option to control that. I have a feeling that it is enabled for some libraries in Debian precisely to support this sort of thing. I know nothing about other compilers, and even on Linux it's probably not reasonable to expect that the user will use a libjpeg compiled in this way. 5. (Grasping at straws) run libjpeg in a co-routine, err, not sure exactly how that would work, but something about an extra stack... 6. This is what I'd really like to see: copy the libjpeg source into your project, and then do (4). You could do some other tidying-up at the same time. My recollection is that one of the other libraries also had a setjmp error handler, but that it could be configured to instead return error codes while libjpeg can't. Not sure if that's accurate though. Regards, Phil.

Hi Phil, first of all thanks for raising these issues. I believe it's very helpful for my submission.
Does that mean I have to call setjmp everytime before I call libjeg function? This way the function that calls setjmp would not have been terminated.
Your choices are:
1. setjmp() in each function (scope?) that calls into libjpeg. That's nasty because setjmp(), IIRC, is detected by the compiler and prevents some optimisations. It's relatively non-intrusive in your code though.
In my opinion this is the best option I have right now.
2. setjmp() once, and make sure that that is in a scope that contains all the calls. This means turning your code inside out, but it's not impossible because - as we've noted - you never leave a jpeg file open and return to the user code, i.e. the setjmp() can happen soon after the user calls into your code. I don't think that destructors will not be called when longjmp() "pops" the stack, so you need to be careful about what types you use.
This would turn my code into an ugly huge switch statement, with a lot of code repetition. I rather not do that.
3. (deleted - idea too horrible to share.)
Don't even wanna know. ;-)
4. Try to throw an exception from the error handler. This would be ideal, if you could be sure that the exception would propagate through the C code. I believe that gcc has an option to control that. I have a feeling that it is enabled for some libraries in Debian precisely to support this sort of thing. I know nothing about other compilers, and even on Linux it's probably not reasonable to expect that the user will use a libjpeg compiled in this way.
I agree this would be support nightmare. We all know that the user wants something workable out-of-box.
5. (Grasping at straws) run libjpeg in a co-routine, err, not sure exactly how that would work, but something about an extra stack...
I'm already drowned. Maybe someone else on this mailing list can go into more details.
6. This is what I'd really like to see: copy the libjpeg source into your project, and then do (4). You could do some other tidying-up at the same time.
This is only possible if I have someone who is willing to put the time and effort in. I don't have that right now. Leaving for loooooooong ( 2 months ) vacation soon. Also, do you know whether or not libjpeg continued? What I could see is to have a separate project that provides an "updated" libjpeg source. For such users we could provide a compiler symbol to compile optimized code. I'll keep this option in mind.
My recollection is that one of the other libraries also had a setjmp error handler, but that it could be configured to instead return error codes while libjpeg can't. Not sure if that's accurate though.
Do you mean libpng? I believe I have to update my code for png, as well. Thanks again, Christian

Phil Endecott wrote:
Hi Christian,
I wonder if anyone will notice this message amid all the mud and flame-slinging that's going on? I know - I'll get everyone's attention by pointing out that the fundamental problem here is that the C library, libjpeg, has a truly awful API design: when it gets an error, it calls a user-supplied function-pointer and that mustn't return.
Yes, that's pretty abominable.
Christian Henning wrote:
Does that mean I have to call setjmp everytime before I call libjeg function? This way the function that calls setjmp would not have been terminated.
Your choices are:
1. setjmp() in each function (scope?) that calls into libjpeg. That's nasty because setjmp(), IIRC, is detected by the compiler and prevents some optimisations. It's relatively non-intrusive in your code though.
I can't believe performance is a serious concern here. I think this is the best option. There's still the thread-safety issue. Can you use the cinfo to pass the jmp_buf through to error_exit? If not then I guess the jmp_buf could be stored in static thread-local storage...
2. setjmp() once, and make sure that that is in a scope that contains all the calls. This means turning your code inside out, but it's not impossible because - as we've noted - you never leave a jpeg file open and return to the user code, i.e. the setjmp() can happen soon after the user calls into your code. I don't think that destructors will not be called when longjmp() "pops" the stack, so you need to be careful about what types you use.
Yes, that's undefined behaviour too; see e.g. N3000, [support.runtime] p4: A setjmp/longjmp call pair has undefined behavior if replacing the setjmp and longjmp by catch and throw would invoke any non-trivial destructors for any automatic objects.
5. (Grasping at straws) run libjpeg in a co-routine, err, not sure exactly how that would work, but something about an extra stack...
More trouble than it's worth, I'm pretty sure.
6. This is what I'd really like to see: copy the libjpeg source into your project, and then do (4). You could do some other tidying-up at the same time.
Sounds nice in principle, but again the benefit over solution 1 is minor, and the maintenance burden would surely be huge. For example the entire library would have to be put in a namespace or something so as not to clash with the 'real' libjpeg. John Bytheway

Hi there,
1. setjmp() in each function (scope?) that calls into libjpeg. That's nasty because setjmp(), IIRC, is detected by the compiler and prevents some optimisations. It's relatively non-intrusive in your code though.
I can't believe performance is a serious concern here. I think this is the best option. There's still the thread-safety issue. Can you use the cinfo to pass the jmp_buf through to error_exit? If not then I guess the jmp_buf could be stored in static thread-local storage...
I have updated and uploaded the code. If someone could have a look I would really appreciate it. http://gil-contributions.googlecode.com/svn/trunk/gil_2/boost/gil/extension/... http://gil-contributions.googlecode.com/svn/trunk/gil_2/boost/gil/extension/... Am I correct to mark up the write operations with setjmp's, as well? Does someone has an idea how to deal with multi-threaded scenarios? Regards, Christian

On 24/03/10 20:13, Christian Henning wrote:
I have updated and uploaded the code. If someone could have a look I would really appreciate it.
http://gil-contributions.googlecode.com/svn/trunk/gil_2/boost/gil/extension/... http://gil-contributions.googlecode.com/svn/trunk/gil_2/boost/gil/extension/...
I glanced at it, and saw nothing else wrong, but I haven't been remotely thorough :).
Am I correct to mark up the write operations with setjmp's, as well?
I imagine so.
Does someone has an idea how to deal with multi-threaded scenarios?
The jpeg_compress_struct (and its friends) has a void* client_data. If you make the jmp_buf a local variable and pass it through to the error handler using that field then I think everything should be OK? John Bytheway

John Bytheway wrote:
On 24/03/10 20:13, Christian Henning wrote:
I have updated and uploaded the code. If someone could have a look I would really appreciate it.
Well, have a look at read_rows(). Say one of the jpeg_read_scalines() calls fails and calls the error handler. I think that: - The dtor for buffer will not be called because you have longjump()d out of its scope. - jpeg_destroy_decompress() will be called twice, once in raise_error() and again in ~jpeg_destroy_decompress() when the exception propagates up.
Does someone has an idea how to deal with multi-threaded scenarios?
The jpeg_compress_struct (and its friends) has a void* client_data. If you make the jmp_buf a local variable and pass it through to the error handler using that field then I think everything should be OK?
Just put 'this' in client_data and put the jmpbuf in your object. (As I think I suggested before, to me personally it would be more useful to have a set of wrappers for these libraries that only deal with these C++-ification issues, rather than the full gil integration that you're offering. For example the whole issue with memory usage where you're saying that "memory is cheap, everyone has gigabytes these days" just doesn't apply to the digital photo frames and mobile phones that I'm dealing with. So in order to get anything useful from this, I would love to decouple this 'library wrapping' from the gil aspect.) Regards, Phil.

Hi Phil,
Well, have a look at read_rows(). Say one of the jpeg_read_scalines() calls fails and calls the error handler. I think that:
- The dtor for buffer will not be called because you have longjump()d out of its scope.
Agreed. I wonder how I can fix that. I cannot really move buffer into class scope since I don't know the buffer's value type. This type depends on the current pixel type.
- jpeg_destroy_decompress() will be called twice, once in raise_error() and again in ~jpeg_destroy_decompress() when the exception propagates up.
Fixed.
Does someone has an idea how to deal with multi-threaded scenarios?
The jpeg_compress_struct (and its friends) has a void* client_data. If you make the jmp_buf a local variable and pass it through to the error handler using that field then I think everything should be OK?
Just put 'this' in client_data and put the jmpbuf in your object.
Done. I should have thought of this myself.
(As I think I suggested before, to me personally it would be more useful to have a set of wrappers for these libraries that only deal with these C++-ification issues, rather than the full gil integration that you're offering. For example the whole issue with memory usage where you're saying that "memory is cheap, everyone has gigabytes these days" just doesn't apply to the digital photo frames and mobile phones that I'm dealing with. So in order to get anything useful from this, I would love to decouple this 'library wrapping' from the gil aspect.)
When you C++-tified libjpeg for instance, in what container would you store the data? You probably would use a template parameter to give the user the option. I do exactly the same. GIL is based on concepts and so it lets you define your own image type if you like. For instance when you deal with huge images you might want to create your own image type that deals more efficiently with memory. Also, how would a C++ wrapper help you with large images? All in all, Phil, thanks a lot for help. It has more than helpful!! Regards, Christian

Christian Henning wrote:
Well, have a look at read_rows(). ?Say one of the jpeg_read_scalines() calls fails and calls the error handler. ?I think that:
- The dtor for buffer will not be called because you have longjump()d out of its scope.
Agreed. I wonder how I can fix that. I cannot really move buffer into class scope since I don't know the buffer's value type. This type depends on the current pixel type.
You can probably just declare the buffer before you call setjmp(). However, I only have an intuitive idea of what happens. It really needs someone who actually understands this stuff (i.e. the spec) to look at it. For example, the GNU libc manual says: "When you perform a non-local exit, accessible objects generally retain whatever values they had at the time longjmp was called. The exception is that the values of automatic variables local to the function containing the setjmp call that have been changed since the call to setjmp are indeterminate, unless you have declared them volatile" That seems to suggest that buffer becomes undefined. In a sense this doesn't matter since it will be destroyed when you throw, as long as it is undefined in a way that doesn't cause its dtor to crash or leak.
(As I think I suggested before, to me personally it would be more useful to have a set of wrappers for these libraries that only deal with these C++-ification issues, rather than the full gil integration that you're offering. ?For example the whole issue with memory usage where you're saying that "memory is cheap, everyone has gigabytes these days" just doesn't apply to the digital photo frames and mobile phones that I'm dealing with. ?So in order to get anything useful from this, I would love to decouple this 'library wrapping' from the gil aspect.)
When you C++-tified libjpeg for instance, in what container would you store the data? You probably would use a template parameter to give the user the option.
No; if I were doing this, I'd first wrap libjpeg to hide all its nasty warts like this error handling, increase the type safety, and other "thin" changes - as above. class ReadJpegFile { public: struct JpegDecodingError: std::exception {}; typedef uint8_t sample_t; ReadJpegFile(std::string fn); ~ReadJpegFile(); size_t read_scanlines(size_t n_lines, sample_t* data); .... }; Concerns about e.g. containers would come in the next layer.
Also, how would a C++ wrapper help you with large images?
My point is that your gil interface doesn't help me with large images in limited RAM, and your current design is "all or nothing". Decomposing it into wrappers around the libraries that are independently useful would mean that I could use them directly and get the benefit of e.g. the error handling stuff, with my own row-at-a-time code on top. Phil.

On Thu, 2010-03-25 at 16:28 +0000, Phil Endecott wrote:
Christian Henning wrote:
[snip]
Also, how would a C++ wrapper help you with large images?
My point is that your gil interface doesn't help me with large images in limited RAM, and your current design is "all or nothing". Decomposing it into wrappers around the libraries that are independently useful would mean that I could use them directly and get the benefit of e.g. the error handling stuff, with my own row-at-a-time code on top.
I second that. I'll probably need this library quite badly next month. So I could gladly help coding. Also, allowing a more low-level abstraction permits creating image types for images that do not live in memory. Which, IIUC, is what Phil really needs in his TIFF use-case.
Phil.
Regards, -- Felipe Magno de Almeida

Hi there,
Also, allowing a more low-level abstraction permits creating image types for images that do not live in memory. Which, IIUC, is what Phil really needs in his TIFF use-case.
In gil there is something called virtual images. One usage example would be a procedural image displaying a mandelbrot set. See boost\libs\gil\example\mandelbrot.cpp But virtual images are not limit to procedural images. A while back I created an indexed image type for gil using this functionality. You can find it here: http://gil-contributions.googlecode.com/svn/trunk/gil_2/boost/gil/extension/... I hope this tip can give you an indication on how flexible gil can be and how easy it is to create different image types. Regards, Christian

Hi Phil,
You can probably just declare the buffer before you call setjmp().
However, I only have an intuitive idea of what happens. It really needs someone who actually understands this stuff (i.e. the spec) to look at it. For example, the GNU libc manual says:
For now, I'll do that. I also put a comment to keep a record of this problem. Hopefully someone will get back to me on this issue. I don't consider this a show-stopper.
When you C++-tified libjpeg for instance, in what container would you store the data? You probably would use a template parameter to give the user the option.
No; if I were doing this, I'd first wrap libjpeg to hide all its nasty warts like this error handling, increase the type safety, and other "thin" changes - as above.
class ReadJpegFile { public: struct JpegDecodingError: std::exception {}; typedef uint8_t sample_t; ReadJpegFile(std::string fn); ~ReadJpegFile(); size_t read_scanlines(size_t n_lines, sample_t* data); .... };
Understand what you mean. Quite a workload you are describing. ;-) It might be nice GSOC project, though. In a future version of gil::io we might just do that. My goal right now is to replace the current gil::io with the new version and I'm running out of time. I'm in the process of creating the final release candidate.
Also, how would a C++ wrapper help you with large images?
My point is that your gil interface doesn't help me with large images in limited RAM, and your current design is "all or nothing". Decomposing it into wrappers around the libraries that are independently useful would mean that I could use them directly and get the benefit of e.g. the error handling stuff, with my own row-at-a-time code on top.
Imagine for now libjpeg doesn't allow for partial image decoding. How would you solve that problem? My solution might be to create a virtual image container which only holds a certain amount of an image in memory and the rest on the hard drive. Though, while reading a large image this container will handle limit memory situation on the fly. I have been glancing over libjepg documentation. One of the advanced feature is called "Buffered-image mode". It goes like this: "In buffered-image mode, the library stores the partially decoded image in a coefficient buffer, from which it can be read out as many times as desired. This mode is typically used for incremental display of progressive JPEG files, but it can be used with any JPEG file. Each scan of a progressive JPEG file adds more data (more detail) to the buffered image. The application can display in lockstep with the source file (one display pass per input scan), or it can allow input processing to outrun display processing. By making input and display processing run independently, it is possible for the application to adapt progressive display to a wide range of data transmission rates." Do you think this feature can be used to read out sub-images? Regards, Christian

Christian Henning wrote:
Also, how would a C++ wrapper help you with large images?
My point is that your gil interface doesn't help me with large images in limited RAM, and your current design is "all or nothing". ?Decomposing it into wrappers around the libraries that are independently useful would mean that I could use them directly and get the benefit of e.g. the error handling stuff, with my own row-at-a-time code on top.
Imagine for now libjpeg doesn't allow for partial image decoding. How would you solve that problem?
I'm not sure what you mean by "that problem" in that question. Do you just mean "processing large images in limited RAM"? If you do, the answer is that I would just process the image sequentially, e.g. row-at-a-time. For operations like scaling and tiling this is straightforward.
My solution might be to create a virtual image container which only holds a certain amount of an image in memory and the rest on the hard drive. Though, while reading a large image this container will handle limit memory situation on the fly.
Well my digital picture frame doesn't have a hard drive. You seem to be over-thinking this a bit!
I have been glancing over libjepg documentation. One of the advanced feature is called "Buffered-image mode". It goes like this:
"In buffered-image mode, the library stores the partially decoded image in a coefficient buffer, from which it can be read out as many times as desired. This mode is typically used for incremental display of progressive JPEG files, but it can be used with any JPEG file. Each scan of a progressive JPEG file adds more data (more detail) to the buffered image. The application can display in lockstep with the source file (one display pass per input scan), or it can allow input processing to outrun display processing. By making input and display processing run independently, it is possible for the application to adapt progressive display to a wide range of data transmission rates."
Do you think this feature can be used to read out sub-images?
Perhaps. Phil.

On Linux, where I develop, we use PNG. As far as i know, the following library is pretty much the standard way to interface with PNG's. http://www.karlings.com/~danne/pnglite/ It was written by the original png developers, but has a simpler interface. Should be adequate for your purposes. Just grab what you can. On Thu, Mar 25, 2010 at 2:18 PM, Phil Endecott <spam_from_boost_dev@chezphil.org> wrote:
Christian Henning wrote:
Also, how would a C++ wrapper help you with large images?
My point is that your gil interface doesn't help me with large images in limited RAM, and your current design is "all or nothing". ?Decomposing it into wrappers around the libraries that are independently useful would mean that I could use them directly and get the benefit of e.g. the error handling stuff, with my own row-at-a-time code on top.
Imagine for now libjpeg doesn't allow for partial image decoding. How would you solve that problem?
I'm not sure what you mean by "that problem" in that question. Do you just mean "processing large images in limited RAM"? If you do, the answer is that I would just process the image sequentially, e.g. row-at-a-time. For operations like scaling and tiling this is straightforward.
My solution might be to create a virtual image container which only holds a certain amount of an image in memory and the rest on the hard drive. Though, while reading a large image this container will handle limit memory situation on the fly.
Well my digital picture frame doesn't have a hard drive. You seem to be over-thinking this a bit!
I have been glancing over libjepg documentation. One of the advanced feature is called "Buffered-image mode". It goes like this:
"In buffered-image mode, the library stores the partially decoded image in a coefficient buffer, from which it can be read out as many times as desired. This mode is typically used for incremental display of progressive JPEG files, but it can be used with any JPEG file. Each scan of a progressive JPEG file adds more data (more detail) to the buffered image. The application can display in lockstep with the source file (one display pass per input scan), or it can allow input processing to outrun display processing. By making input and display processing run independently, it is possible for the application to adapt progressive display to a wide range of data transmission rates."
Do you think this feature can be used to read out sub-images?
Perhaps.
Phil.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Tom Brinkman wrote:
On Linux, where I develop, we use PNG. As far as i know, the following library is pretty much the standard way to interface with PNG's.
http://www.karlings.com/~danne/pnglite/
It was written by the original png developers, but has a simpler interface. Should be adequate for your purposes. Just grab what you can.
"Should be adequate for your purposes" - I'm not sure what you mean Tom. We're discussing how to process large JPEGs in limited RAM, and how to deal with the nasty error-reporting mechanism that libjpeg has. I don't see how pnglite is going to help with that. Anyway, having looked at it, it seems that it decodes the whole image in one call into a contiguous memory region. So if I were trying to decode PNGs then it would require that I had enough RAM to store the whole decoded image, which is exactly what I don't have. It also doesn't handle indexed images. It does have sane error reporting though. Regards, Phil.

I'm not sure if it adds to your dissussion. Just thought I'd post a link of library that I think works well, maybe john could get some ideas from it. On Thu, Mar 25, 2010 at 4:11 PM, Phil Endecott <spam_from_boost_dev@chezphil.org> wrote:
Tom Brinkman wrote:
On Linux, where I develop, we use PNG. As far as i know, the following library is pretty much the standard way to interface with PNG's.
http://www.karlings.com/~danne/pnglite/
It was written by the original png developers, but has a simpler interface. Should be adequate for your purposes. Just grab what you can.
"Should be adequate for your purposes" - I'm not sure what you mean Tom. We're discussing how to process large JPEGs in limited RAM, and how to deal with the nasty error-reporting mechanism that libjpeg has. I don't see how pnglite is going to help with that.
Anyway, having looked at it, it seems that it decodes the whole image in one call into a contiguous memory region. So if I were trying to decode PNGs then it would require that I had enough RAM to store the whole decoded image, which is exactly what I don't have. It also doesn't handle indexed images. It does have sane error reporting though.
Regards, Phil.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

So you are going to do JPG. Wow. Thats a tough spec. Whats the goal, complete coverage, or just the important bits. For jpgs, I use IPP, which is not opensource unfortunately. Lots of issues to consider. Are you going to do jpg 2000? On Thu, Mar 25, 2010 at 4:11 PM, Phil Endecott <spam_from_boost_dev@chezphil.org> wrote:
Tom Brinkman wrote:
On Linux, where I develop, we use PNG. As far as i know, the following library is pretty much the standard way to interface with PNG's.
http://www.karlings.com/~danne/pnglite/
It was written by the original png developers, but has a simpler interface. Should be adequate for your purposes. Just grab what you can.
"Should be adequate for your purposes" - I'm not sure what you mean Tom. We're discussing how to process large JPEGs in limited RAM, and how to deal with the nasty error-reporting mechanism that libjpeg has. I don't see how pnglite is going to help with that.
Anyway, having looked at it, it seems that it decodes the whole image in one call into a contiguous memory region. So if I were trying to decode PNGs then it would require that I had enough RAM to store the whole decoded image, which is exactly what I don't have. It also doesn't handle indexed images. It does have sane error reporting though.
Regards, Phil.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Phil Endecott wrote:
Christian Henning wrote:
Also, how would a C++ wrapper help you with large images?
My point is that your gil interface doesn't help me with large images in limited RAM, and your current design is "all or nothing". ?Decomposing it into wrappers around the libraries that are independently useful would mean that I could use them directly and get the benefit of e.g. the error handling stuff, with my own row-at-a-time code on top.
Imagine for now libjpeg doesn't allow for partial image decoding. How would you solve that problem?
I'm not sure what you mean by "that problem" in that question. Do you just mean "processing large images in limited RAM"? If you do, the answer is that I would just process the image sequentially, e.g. row-at-a-time. For operations like scaling and tiling this is straightforward.
It seems aligned to what I was trying to suggest too.
My solution might be to create a virtual image container which only holds a certain amount of an image in memory and the rest on the hard drive. Though, while reading a large image this container will handle limit memory situation on the fly.
Well my digital picture frame doesn't have a hard drive. You seem to be over-thinking this a bit!
Perhaps, generally I mean, it's not a bad idea to manage a cache that could be used by underlying I/O machinery. This cache could be used to store most recent blocks, so they are not re-read from disk if re-accessed. Though, it feels to me as an application specific feature, but on the other hand it could be implemented better if made as close as to low-level I/O. Best regards, -- Mateusz Loskot http://mateusz.loskot.net

"Phil Endecott" <spam_from_boost_dev@chezphil.org> wrote in message news:1269391277318@dmwebmail.dmwebmail.chezphil.org...
4. Try to throw an exception from the error handler. This would be ideal, if you could be sure that the exception would propagate through the C code. I believe that gcc has an option to control that. I have a feeling that it is enabled for some libraries in Debian precisely to support this sort of thing. I know nothing about other compilers, and even on Linux it's probably not reasonable to expect that the user will use a libjpeg compiled in this way.
This is always safe to do with MSVC++ on Windows because it uses SEH to implement C++ exceptions and SEH 'cuts' through everything (it is handled/implemented by the OS)...If you are going to use exceptions anyways then this would be both the easiest and most efficient way of handling this issue (on the mentioned platform). You would only have to make sure that the compiler knows that the libjpeg C functions can actually throw a C++ exception...This can be done by the user by using the global /EHa compiler switch or, better, you would provide wrappers for the affected libjpeg functions that are marked with the 'throw(...)' specifier... For compilers that do not use the same approach as MSVC++ but 'work' on Windows and support SEH you could just throw a SEH exception from the error handler and then later catch and convert it to a C++ exception... ----------------------- ps. Just about parallel to this discussion I finished a first version of my 'native GIL IO implementation' and sent it to Christian for comments/inspection. Now we've decided that it would perhaps be better to make our discussion public on boost.devel considering there is an ongoing related discussion. I've attached the few emails already exchanged and below you can find my response to Christian's latest mail. Anyways I would be glad if others would be interested to look at/comment/test my proposed code (if by some chance it, in its current unfinished/limited form, applies to their platform and needs)... ----- Original Message ----- From: "Christian Henning" <chhenning@gmail.com> To: "Domagoj ©ariæ" <dsaritz@gmail.com> Sent: 24. oŸujak 2010 16:14 Subject: Re: [gil] native image format loaders/savers
This would be only viable if you can ensure that you'll cover all features of png. Nothing less is possible.
AFAIK GDI+ officialy does not support only the HDR/16bits per channel PNGs (it can read them but it converts them to LDR formats). I do not see this as a problem, even in the current official release you get a compile time error if the underlying IO library does not support a requested format (as a documented and desired behaviour)...and this is what will happen if try using native GIL.IO on Windows and ask it to produce a HDR image, it will say 'no can do' at compile-time... For my needs (for example, loading a bunch of relatively small PNGs on startup for my application's skin) this is perfectly enough...And leaves me free from libpng and zlib...
If you think you have that how hard to you think would it be add it to my extension? You could for instance add a new format called "png_native" and start adding your source code.
Well I could start with a separate class, but, as argued below, I think that coexisting/differently named separate lib* and 'native' implementations classes, as a final design goal, are the correct approach here... OTOH what would be an immediate show-stopper for me is if you would insist on forcing std::streams usage for IO...
You could use whatever buffer you want BUT you have to make sure it's derived from std::istream and/or std::ostream. Have a look at io_device.hpp.
Is there a specific reason for this requirement? If you ever stepped through the Unimaginable Horrors of code generated for a simple statement like std::istream blah( 0 ); you will understand my question :)
I welcome the change to use tags instead of different function names. Even more than that, from my experience with GDI+, it would be even easier and cleaner (and more efficient) if went further and changed everything to objects/classes with member functions....that way, as a simple example, you would not load and create an object twice, first to get its dimensions and then to read it...you'd create it once and then call its member functions until you're done with it...
The goal is provide an unified interface that all format share.
Isn't that much easier to do/provide using classes that share the same interface? Easier then making function wrappers for each of the classes. This way we could also turn on-disk/compressed images into GIL image concepts or atleast provide an automatic template/operator based interop layer between them. So one can write image<pixel<bits8, bgra_layout_t>, false> gil_image; png_image_t image_file( "my picture.png" ); gil_image >> image_file; image_file >> gil_image; ... Later/independently, wrappers/adaptors for image classes of 'popular' GUI frameworks (wX, JUCE, Qt...) or native OS 'constructs' (GDI(+) on Windows...) that turn them into GIL image/view concepts could also be added...
BTW, you don't need to read the dimensions first and then read the data. That what read_image( .. ) is for. It will take care of allocating memory and reading the data.
Yes but that is only one special case for which a set of function overloads already exists, but for anything else/more complex (like for example what has been requested in this thread, to read only a portion of an image, which GDI+ supports out of the box with its lazy loading) a new set would have to be written...
Instead of using a compiler symbol I would suggest a new format type like "png_native".
Can you elaborate why? This would seem like an unnecessary complication (of the public library interface)...what would this gain...because, if you are going to use lib* at all you might as well then use it always, in other words what good would the ability to use both the lib* based implementation and the native one interchangebly bring? It would surely remove the possibility of a simple one-place configuration of the implementation to use... -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman begin 666 01. [gil] native image format loaders_savers.eml M34E-12U697)S:6]N.B Q+C -"E)E8V5I=F5D.B!B>2 Q,"XR,#0N-3DN,30@ M=VET:"!(5%10.R!-;VXL(#(R($UA<B R,#$P(#$W.C Q.C X("TP-S P("A0 M1%0I#0I$871E.B!4=64L(#(S($UA<B R,#$P(# Q.C Q.C X("LP,3 P#0I$ M96QI=F5R960M5&\Z(&1S87)I='I 9VUA:6PN8V]M#0I-97-S86=E+4E$.B \ M-S8S.&4V93 Q,# S,C(Q-S Q:C9B-6%C9C$S:C)D-V,W,V(U-# Q9# Q-#E M;6%I;"YG;6%I;"YC;VT^#0I3=6)J96-T.B!;9VEL72!N871I=F4@:6UA9V4@ M9F]R;6%T(&QO861E<G,O<V%V97)S#0I&<F]M.B ]/U541BTX/T(_4D<Y=%E7 M9'9A:41&;T=&>6%C4T@_/2 \9'-A<FET>D!G;6%I;"YC;VT^#0I4;SH@8VAH M96YN:6YG0&=M86EL+F-O;0T*0V]N=&5N="U4>7!E.B!M=6QT:7!A<G0O;6EX M960[(&)O=6YD87)Y/3 P-3 T-3 R8S,R,&,V,3DP83 T.#(V8S@R-#0-"D]L M9"U8+45S971)9#H@1#!%-3=#,C<Q-C0S-S,R,CA"03D-"E@M17-E=%-C86YN M97)"=6EL9#H@-C@Q,0T*6"U%<V5T260Z($0P134W0S(W,38T,S<S,D0X,T$Q M#0H-"BTM,# U,#0U,#)C,S(P8S8Q.3!A,#0X,C9C.#(T- T*0V]N=&5N="U4 M>7!E.B!T97AT+W!L86EN.R!C:&%R<V5T/4E33RTX.#4Y+3$-"@T*2&D@0VAR M:7-T:6%N+ T*22!D;VXG="!K;F]W(&EF('EO=2!R96UE;6)E<B!T:&ES('-H M;W)T('1H<F5A9#H-"FAT=' Z+R]O;&0N;F%B8FQE+F-O;2\M9VEL+2UN871I M=F4M:6UA9V4M9F]R;6%T+6QO861E<G,M<V%V97)S+71D,C<R,#<T.3$N:'1M M; T*#0HN+BX@86YY=V%Y<R!))W9E(&=O="!A(&9I<G-T(&1R869T('9E<G-I M;VX@<F5A9'D@:68@>6]U)V0@;&EK92!T;R!T86ME(&$@;&]O:RXN+@T*#0H- M"DDG=F4@:6UP;&5M96YT960@=&AE(&)A<V4@1T1)*R!B86-K96YD(&%N9"P@ M=VET:"!I="P@=&AE(%!.1R!)3PT*:6YT97)F86-E+B!!;&P@;W1H97(@:6YT M97)F86-E<R!S:&]U;&0@8F4@<F5A;&QY('1R:79I86P@=&\@:6UP;&5M96YT M#0IB96-A=7-E('1H97D@=VEL;"!A;&P@=7-E('1H92!S86UE(&)A<V4@9G5N M8W1I;VYA;&ET>2 H=&AE(&]N;'D-"G-I9VYI9FEC86YT(&1I9F9E<F5N8V4@ M=VEL;"!P<F]B86)L>2!B92!R96=A<F1I;F<@=&AE(&5N8V]D:6YG#0IP87)A M;65T97)S(&9O<B!T:&4@*G=R:71E*B!M971H;V1S+BXN86YD(&]F(&-O=7)S M92!T:&4@9'EN86UI8R!)3PT*=F5R<VEO;G,I+"!M;W-T;'D@82!M871T97(@ M;V8@9')O;F4@8V]P>2]P87-T:6YG(&%N9"!R96YA;6EN9R!O9@T*9F]R=V%R M9&5R<RXN+@T*06QO;F<@=VET:"!T:&4@8W5R<F5N="!I;G1E<F9A8V4@22=V M92!A9&1E9"!S=7!P;W)T(&9O<B!I;BUM96UO<GDL#0I&24Q%(&%N9"!W8VAA M<E]T+69I;&4M;F%M92!S;W5R8V5S+B!4:&5R92!I<R!A;'-O(&$@=&5S="UT M<GD@;V8@=&AE#0IN97<@1T1)*R Q+C$@*'=H:6-H(&ES(&YO="!R961I<W1R M:6)U=&%B;&4@86YD(&ES(&%V86EL86)L92!O;FQY('=I=&@-"D]F9FEC92 R M,# S(&]R(%=I;F1O=W,@5FES=&$@86YD(&%B;W9E*2!I;6%G92!C;VYV97)S M:6]N#0IF=6YC=&EO;F%L:71Y+B!)('=A<R!U;F%B;&4@=&\@9FEN9"!S=7!P M;W)T(&9O<B!I;F1E>&5D(&EM86=E<R!I;B!'24P-"G-O($D@:&%D('1O('1E M<W0@:70@=&AR;W5G:" G;6%N=6%L('1R:6-K97)Y)R H8GD@9F]R8VEN9R!T M:&4@8V]D92!T;PT*9V\@=&AR;W5G:"!T:&4@8V]N=F5R<VEO;B!E=F5N(&EF M(&ET('=A<R!N;W0@;F5C97-S87)Y*2!A;F0@:70-"G-U8V-E<V9U;&QY(&-O M;G9E<G1E9"!A(#,R8FET(%!.1R!W:71H(&%L<&AA('1O(&$@,C4V('!A;&5T M=&5I>F5D#0II;6%G92!A;F0@<V%V960@:70@=&\@82 R-&)I="!03D<@*'=I M=&@@=&AE(&5X<&5C=&5D(')E<W5L=',I+B!)(&%L<V\-"G1R:65D('1O(&%D M9"!S=7!P;W)T(&9O<B!P86-K961?<&EX96P@=FEE=W,@*'1H870@<V5E;7,@ M=&\@=V]R:R!W:71H#0IT:&4@9&5F875L="!L:6)P;F<@8F%S960@:6UP;&5M M96YT871I;VX@8G5T(&ET('5S97,@86X@:6YE9F9I8VEE;G0-"FUE=&AO9"!W M:71H(&QO=',@;V8@8V]P>6EN9R!A;F0@;65M;W)Y(&%L;&]C871I;VXI(&)U M="!F86EL960N+BYI= T*<V5E;7,@:6YT97)L96%V961?=FEE=U]G971?<F%W M7V1A=&$H*2!D;V5S(&YO="!S=7!P;W)T('!A8VME9%]P:7AE; T*=FEE=W,@ M*$D@9&]N)W0@=6YD97)S=&%N9"!W:'DN+BX-"B=B97=A<F4G('1H870@;7D@ M<')I;6%R>2!C;VYC97)N('=A<R]I<R!P;&%I;B]C;W)E(&EM86=E($E/(&%N M9"!T:&%T#0IM>2!E>'!E<FEE;F-E(&%N9"!K;F]W;&5D9V4@:6X@)VEM86=E M('1H96]R>2<@:7,@;F]T(&1E97 @96YO=6=H(&9O<@T*<')O<&5R("='24P@ M8F]W96P@961I=&EN9R<@.RD-"DDG;2!S=7)E('EO=2=L;"!B92!A8FQE('1O M('1E;&P@<FEG:'0@87=A>2!W:&%T)W,@=W)O;F<@*'1H97)E('=E<F4@80T* M9F5W(&UO<F4@)V1E860@96YD<R<@22!R96%C:&5D+"!Y;W4@8V%N('-E87)C M:"!T:')O=6=H('1H92!C;V1E(&9O<@T*(E=H870@86)O=70N+BXB('1O(&9I M;F0@=&AO<V4I+BXN#0H-"D]N92!M;W)E(&EM<&]R=&%N="!T:&EN9R!I<R!T M:&4@861D:71I;VX@;V8@=&AE("=M86-H:6YE<GDG(&EN#0HB97AT97)N7VQI M8BYH<' B+BXN5VET:"!I="!)('1R:65D('1O(&%D9"!M;W)E(&-O;F9I9W5R M871I;VX@<W5P<&]R= T*<V\@=&AA="!U<V5R<R!C86X@8VAO;W-E(&5X86-T M;'D@:&]W(&%N9"!W:&5N('1H97D@=V%N="!T;R!L:6YK(&%N9 T*:6YI=&EA M;&EZ92!T:&4@97AT97)N86P@;&EB("AT:&4@<W1A='5S('%U;RP@049!24-4 M(&ES('1O(&%S<W5M90T*<W1A=&EC(&]R(&QO860@=&EM92!L:6YK:6YG(&%N M9"!A=71O;6%T:6,@:6YI=&EA;&EZ871I;VX@8GD@1TE,(&]N#0IE=F5R>2!! M4$D@8V%L;"DN($YO=RP@:68@>6]U(&AA=F4@82!U<V4@8V%S92!L:6ME(&UI M;F4L('=H97)E('EO=2!L;V%D#0IA(&)U;F-H(&]F(&EM86=E<R!O;B!S=&%R M='5P("AL:6ME(&QO861I;F<@82!S:VEN*2!A;F0@:&%V92!N;R!M;W)E#0IN M965D(&9O<B!T:&4@:6UA9V4@24\@;&EB+"!Y;W4@8V%N(&-O;F9I9W5R92!T M:&4@;&EN:R9I;FET(&]P=&EO;G,@=&\-"F)E(&UO<W0@969F:6-I96YT(&9O M<B!S=6-H(&$@=7-E(&-A<V4N+BYF;W(@97AA;7!L93H-"@T*(VEN8VQU9&4@ M(F)O;W-T+V=I;"]E>'1E;G-I;VXO:6\O97AT97)N7VQI8BYH<' B#0HC9&5F M:6YE($)/3U-47T=)3%]54T5?3D%4259%7TE/#0HC9&5F:6YE($)/3U-47T=) M3%]%6%1%4DY!3%],24(@*"!"3T]35%],24)?3$E.2U]254Y424U%7T%34U5- M15],3T%$140L#0I"3T]35%],24)?3$]!1$E.1U]214Q/041!0DQ%+"!"3T]3 M5%],24)?24Y)5%]!4U-5344@*0T*(VEN8VQU9&4@(F)O;W-T+V=I;"]E>'1E M;G-I;VXO:6\O<&YG7VEO+FAP<"(-"@T*>PT*(" O+R!T:&ES(&=U87)D(&-L M87-S(&ES(&%U=&]M871I8V%L;'D@:6UP;&5M96YT960@8GD@=&AE#0H@("\O M(&5X=&5R;E]L:6(@;6%C:&EN97)Y(&%C8V]R9&EN9R!T;R!C:&]S96X@;W!T M:6]N<PT*("!B;V]S=#HZ9VEL.CIG:6Q?:6]?;&EB7V=U87)D(&-O;G-T(&EO M7VQI8E]G=6%R9#L-"@T*(" O+R!D;R!S;VUE=&AI;F<N+BX-"@T*("!T>7!E M9&5F(&EM86=E/'!I>&5L/&)I=',X+"!B9W)?;&%Y;W5T7W0^+"!F86QS93X@ M1TE,26UA9V4[#0H@($=)3$EM86=E('1I;6%G93L-"B @<&YG7W)E861?86YD M7V-O;G9E<G1?:6UA9V4H(")B;V]S="YP;F<B+"!T:6UA9V4@*3L-"B @<&YG M7W=R:71E7W9I97<H(")B;V]S=#(N<&YG(BP@9VEL.CIV:65W*"!T:6UA9V4@ M*2 I.PT*?0T*#0H-"D%S(&$@<W1A<G1I;F<@<&]I;G0@22!C:&]S92!T:&4@ M1TE,+DE/(&9R;VT@0F]O<W0@,2XT,"P@8F5C875S92!T:&%T#0II<R!T:&4@ M=F5R<VEO;B!)('-T:6QL('5S92 H049!24-4(&YO=&AI;F<@8VAA;F=E9"!I M;B Q+C0R(&EN($=)3"Y)3RDL#0IA(&UO<G!H960@=&AA="XN+G-O('1H92!F M:6QE<R!))VT@<V5N9&EN9R!Y;W4@9V\@<W1R86EG:'0-"BAO=F5R=W)I=&EN M9RD@:6YT;R!T:&4@9VEL+V5X=&5N<VEO;G,O:6\@9F]L9&5R+BXN($EF(&ET M('1U<FYS(&]U= T*=&AA="!T:&4@=&AI;F=S(&%R92 G;6]V:6YG(&EN('1H M92!R:6=H="<@9&ER96-T:6]N+"!W:71H('EO=7(@:&5L<"X@20T*8V%N(&UO M=F4@=&\@=&AE(&YE=R!'24PN24\@>6]U(&UE;G1I;VYE9"XN+@T*#0I)(&AA M=F5N)W0@<G5N(&%N>2!O9F9I8VEA;"!T97-T<R H:68@>6]U(&-O=6QD('!O M:6YT(&UE('1O(&$@='5T;W)I86P-"F]N(&AO=R!T;R!D;R!T:&]S92DL(&IU M<W0@;7D@;W=N('!E<G-O;F%L('1E<W1I;F<@*&)U="!O9B!C;W5R<V4@=&AI M<PT*:7,@:G5S="!A(&9I<G-T(&1R869T('9E<G-I;VX@86YD("=T:&4@:&]U M<B!I<R!L871E)R!S;R!B96%R('=I=&@@;64-"CLI("XN+B!)="!C;VUP:6QE M<R!W:71H;W5T('=A<FYI;F=S(&]N($U35D,K*R Y+C @4U Q('=I=&@@+U<T M+BXN#0I%>'1R82!C87)E('=A<R!A;'-O('1A:V5N(&9O<B!E9F9I8VEE;F-Y M(&%N9"!R961U8VEN9R!T96UP;&%T92!B;&]A="X-"E1H97)E(&%R92!Q=6ET M92!A(&9E=R!-4U9#*RL@<W!E8VEF:6-S+VYO;B!S=&%N9&%R9"!C;VYS=')U M8W1S('1H870-"G=I;&P@8F4@8VQE86YE9"!U<"XN+@T*#0H-"FAM;2!T:6UE M('1O(&=O('1O('-L965P+BXN9V]O9"!M;W)N:6YG(#LI#0H-"@T*+2T-"B)7 M:&%T($AU>&QE>2!T96%C:&5S(&ES('1H870@:6X@=&AE(&%G92!O9B!A9'9A M;F-E9"!T96-H;F]L;V=Y+"!S<&ER:71U86P-"F1E=F%S=&%T:6]N(&ES(&UO M<F4@;&EK96QY('1O(&-O;64@9G)O;2!A;B!E;F5M>2!W:71H(&$@<VUI;&EN M9R!F86-E('1H86X@9G)O;0T*;VYE('=H;W-E(&-O=6YT96YA;F-E(&5X=61E M<R!S=7-P:6-I;VX@86YD(&AA=&4N(@T*3F5I;"!0;W-T;6%N#0H-"BTM,# U M,#0U,#)C,S(P8S8Q.3!A,#0X,C9C.#(T- T*0V]N=&5N="U4>7!E.B!A<'!L M:6-A=&EO;B]Z:7 [(&YA;64](FEO7VYA=&EV92YZ:7 B#0I#;VYT96YT+41I M<W!O<VET:6]N.B!A='1A8VAM96YT.R!F:6QE;F%M93TB:6]?;F%T:79E+GII M<"(-"D-O;G1E;G0M5')A;G-F97(M16YC;V1I;F<Z(&)A<V4V- T*6"U!='1A M8VAM96YT+4ED.B!F7V<W,WAV:FMD, T*#0I517-$0D)104%G04E!2W=#9'IX M9&IK;F]O9W-!045&54%!04]!04%!6EAH,%I82G58,GAP66DU;V-(1'1(1W1V M,G-J,F4V6"MH.6UU#0I62FU)46@W9%-I5G1*0V1X5W)117-K0S(R-G1+23AE M96A.:V%M>#)B<$=Y52LY=G9M4FU$>'DX=T)%4#)B;'<Q2E!A6C@S-TYW.51R M#0HV-S%E=G!J*U%.*W5Q54U1*U)%435M2TA8=%5';S5&.#AI8FI59UEE9'IQ M.5!J-#%7=G!8-'A18F8O4TYB:'4S;7-F-# V6&50555$#0HT;W=)43!05%EH M-C8Y:&AI>$(U8C%,,4)6>#516D-02$1!:7E02G1)9$EZ=T=Z64M01U)06$A. M27)4;V)U,CA#3VE426]E-3-'1FQ4#0IQ2CDT;W=M:DXT34%A5EE&;EAP1#@X M8C=%+U9-4FDR,'8W=3-Q.$MI4S4Y53!D0WHV5%<Q>DE"-DQJ2F1'.6Y51'AI M.4=O<V(Q168K#0HK3W!066=78V<R0D$P3$AN*U%(<65D9D)N8VM)86Q'3'5" M>E W-%0U9DU294Q34T-K3EEJ0DIM5S51,4AP:G9H36=Q;'1P;VY2<G1N#0HT M1#(X5W=T*T)!:55904AB>4%Z0V-936='1%AQ.6)U-W4Y;U9P,6)Z,D4P.4UA M<6E#2$E'1TE994U%3F0P3VA1:49*1E!H1%!W:51'#0IR3C%T,W%Z,65V;FDU M>$5Z8C19;3AL=TQ03T9N974S835&<GA2=WHK:4Q':$<K+V5V9B]L1DPO9D\S M-D@S>' W8C=&*V-0=V5V,SDO#0IS2&5S2#5W9$AX=V9W1V=94VPR>31U9U-: M2T]U-5EX=&=J-$EO.5).,WEC<S1"1C)L2#5O8U$R34%M=TYI4%4Y0CA91D=0 M06<X.&]H#0I/4D1E:41U1C9E43A(:D5Y67 U1F9..6ID66E&46U$8W)2;C%0 M8F1/+VAO6%)/,C5!9D]C3W9K>%EP:&5,>D]K1U!3,6%61TA"<%0T#0IN06%% M8S5&0F\W1G)"5TU23FQY<6]6;5%.6B\X5E-F=65&9U5&;TE413E-84Q!=5!A M8452:TQ88T<O;S-+44EC:D5C3W%23T@U1$50#0HV42\P3TML5$8P3DMT9V=' M>E%996TT5&=):5(U4D])=GIF8D(O<W-80TLT6FIL9#,Q3%<Y3S<X,F5!5T%X M4$5*9VI3;&=T6G%.9'1$#0ID06AC1$EK8G=*.&,P2595>D-&-45E0UI$4&PS M3DQ!1UIC46=L0DQI:C!!=TI/4CDK94LK1$-R.%AX;EIL=BM(5W5D93 U<WAK M-E9,#0I61E(O*VY$9$I+36M+=7,W3"MI=%IV=%@S3W)O<"\S;75913=89'IR M-B\S;4-49G98:34X.3=)='=05F4W>$DK*TA$:D9/,'9H<B]S#0ID=U$P4C0X M3V-J:4,U.#,R2C174C)B53-&>#4K=$EW62]0-#@K2S="9CE/4&Q4135(1%AB M>E@T;TLP<&-E+VYW24-T2UAF=E-M84)R#0I-5SDT3%1.-3A$5$5R5&EE5#@Q M5S)(9G!,631585E7355*,')A1%=4>6-R57A31T%E4DYI5'$T26=I>'I3>45, M.$<W2G902G5#6DQ6#0IX,&1$=VTV241B0RM.>51"9TAD141V,T])86MV2DIK M2S!G=D%Q4S-48U-9=#901C S>#A04V1/1G9'-#9K3T1S54-/-V,T84U!>3@Y M#0I10V<Y1VY)<4<X<4E237-Z8E=,<G)Q,$\S4SAY2D593TAE44Y!5$$K24%( M3W(W8VQ*-'1J135,=WID:&M.<DEC,VY#56U#;T5!45$Q#0HT1T)F3FQT46@V M2'9B4T-L5'A%2F1Z4RMC<6I6:T-8:#@S;FXY0DEI2VAQ:%9A07AD<4AB=F]D M<%%$0FUR=DE-2#9)2%1O=5 Y25AP#0I)=U1#2D%P;$16:T1K,T9):5<T;B]/ M45%V039G4VM3:#!F:$5G;E!02&IV:W-X:7-A=W%C249Q335",FYI64Y64T@U M2FM:4D5!>DM5#0HP-DU0=U=217A/4"M567EF4&A*=$ER1$-3>C R8EIT0G9D M9&UF15I-4T1A<E5J3GA(<3DU3W=4>$=J26=#9'I,1#,W2E)!0S5W*VHR#0I. M455:.$)O0FYE;F1I,C=N4D5(2DUC-%E%:DIF04DO-CE)-TM624M$1T])-#E1 M4FDY4&\Q97171F1P5#1F3DDT>%%/3T8P1$=(2&U-#0HS-S)A:4Y114)*:TI$ M8S)R1U!R44IO>%%&>5E,,$1.0C4R,S9W668K:UE:,FMT4VU!-'192TTX,&EW M,&<W-F)-14A+86A65G=Q.%I2#0I3<55Q-'I!>6=!:W5S8TY!5$%:=79V<T%B M=S Q2G5096=/-T194&QV0W%..$IP+V5E=%)'34EC97,Q;D%(>4I255=B=$EE M239:8VHP#0IK53$X>6M12E518F9%:V%V2C!Q,GE03E%!3T5/,'!+5T8Q-&A) M,6,T=U918CE"86]*6DI356Y)34-N=S1L1&QB5%AF9TU'175K3"]W#0I636-& M0GHS2EI*9E-B:F]2>G-D54E*:S%-:WE9:V%'5454=V)48E4T>3-'3"M&:5DT M9&)!>#-W9#(X47A*>$A'>&%P341-:4UV;VED#0I636I"-T521%!W:VMO47<Q M-FU-84Y1=F=92E5);D8X<4U0<4EP=$]P5TEA4%)V0W!5;GDX-G-R>$HQ<CA4 M,T5R4G4W3E5C>GI0,S5C#0IA3D=)<#%P<TM!*V).3%9:2$4S>#%F:W9&;"MU M*RML5DA$>59+0F-A6G!&>E!D=6U.3G-K935T63)P-E=N6'AH,71Q64Q79RMK M=FUL#0HP6FEF6#!$4&-E57 Y<54S<G-C24AR=&I(>$1C;6]W2S5D*UIZ25=* M4V\U5'!0<%-45DAN96AR1F8W44MK=E4P5DUD,$]F3$1F2S@O#0II<FY:<D]2 M:5-"95<T-"M)<%-'9D].0S=M3S9%2S9O=S)G6'!P.49),$4R5V]$9RM,3V16 M4S5F-$Q#=W)L=F1'9S@X<G<V1%A5>E8Q#0HR;#1L86YS,D%Y=E8Y4F=$6"M9 M>D5/<TM-,VUO>DIQ-#,T,74X*W=R>#,O1T-!;GA*,W$V0W-P=D9H2U=L9FIZ M1$I)2B]/.7-%<DID#0I9.4U.46\U0B]Q6$YW8EIT.'1W65!$8T=M,C!-<VIZ M*VM5,4).<V\U-E=:3TTR0U!H.%!*=DQ+4T%%:3=D6#%N<7)Q9'5R2FEK:'%8 M#0HY25=-8V5T9D,Q,U-G,'!:2$8R1F@R:V953TIY*V]7>6U1<G5*<&)73G(S M,W!N1F13*SA':F-L;D9X931F,VY237)$4DUS-#%D1D)IU.55:>DIW=$Q7 M,'AO<C,U:5!I;55$1T\Y;%9%5V%J15-31C@Q=6Y+,V%R*S%W=$11,WA"1EI! M=698,E10:FQJ>'9J:F]O=6):,F@Y#0I6,&A"43969#,U235N<W9X,C9893!L M275)9%953&)"3D,P0UI&1G=0=5E1=FYO3FYM>GDP=VTR:D]X;TU20W=J8V9I M2RLW,DTX+T%9#0I6:D5:2W%6<F%A86AT4G(U2U9L86AL<F$P=7!M8SAY-D]2 M45-685IA;V=Z<G195D-14W9D1&\K275U>D1$=$DP95)45W V:T5"83$P#0I, M4S-1,4Q44UI#9W)F9S5$.&0P34-G=E=B<7%0;#)(0E9S-&IT5E-P8G-X8FXS M,G!K0SEL='8S5CEC9W=:-S%W1%9Q<6Q'<4A3<6TU#0I.5'<W1D<O+TUS-DYN M,3(R5"]R3E1L=C!G869'1V1B8G O:6DP,G=$0E W4S9F-7%D1%4K9V)#<%!0 M8W-*=S9993!95CA13D)'0C=E#0I%;&,K:F4R1%8Y2$E:4$%:14E:.69M<D%T M5U-05U@W5"M&46)K16,W:E=+2DHX55@Y=V0K6496>$0Y0FIW:B]1-CAJ;4IZ M;S!74F-:#0IH,49M-2MK07%'9CAH;S,R2E5X<TUJ,G!G;TE"."LW-#)T96E2 M3$5C6#9.4RMA;SA/:D$Q>$MQ>78V=VE%:#=I4T%85W%S1V5/8D@X#0I257@Q M6C=3<7560C=H840R0S!%9$9)2C9Q*W!G-F)2,V]89C%C=U!U.3924WIC0W-) M=7)A-4EE4W9J2WHQ:VYN+T9Y2'1+5DHX1EAZ#0IE66<R;W!6=U)487-49VMS M2S5V92]14TYC8G4O2F1&4U=".')4+TUC1$TX1C!S5V9'9%9*;$@T<VQG+T1% M=E)C<C4W<E916F8Q2%<T#0IZ-FY,,G$T;G-J6EE80S!7>59)4C@U:$5394)R M86]:*SAH:S-T855Y:CAI=$]:6&M0<F5S:%5U-%-:9'9.2&=04$=85#%Y<3%2 M8EAT#0I55DQ-8W-W8TE1-U)W.')63'@W>DEP1VQG,WEL1W!I5%19<59V>E%0 M+WDX1FMC+W=:<W!)9&M%8FI.3$98:71E3%=O,#!N<UEM660R#0I&,U=E4B]& M1#!L1DDY3'-W,3(S*W@Y07EE<TQ+.')P3C$K25I7=DAA5TM4;$5S=$]I6E5J M83,P>4A5<$IM875R;VPU=D8Q67-C>6=H#0IS=#-L,4QY5G%85&%Y4$]X8E-X M54Q,;$-)9F%R;VPS27).=W(W.&AT<C!J5VYT<D1:6$5G=#5M5#9+2U1:;4=# M5V)2,W!L2V9Q-GE1#0HW4#$R,G W<&E9071D1G0K=TU:5SE/849$>7!U3D5, M=$MM.'1R6G9S+V5A5FY!<$9T85!35G!U6E$X2D575C4Y;4PS57-15G!O,C5Z M#0HS<W-S<&%X:4YZ679B834Y:3-8379(<FMM6%%E,F9U2&ID=C(T6$$W:31M M>CDW=V\Y3$)I;E%T.5),=$A'.#53,DMF=6I534-Y3W!R#0IZ,61023!U1E)W M>D5A,317239$>6-G230V8VYB:U9B32LX5E(Q8VI%1U%D5GEY06)3-4PX=T=V M;U101GIR-TU84&1D0CEM1W),:%=6#0IE=6Q(<C%&:593239G-UE42V5A=T]. M8TLR53 R3G1N4VAT86-N65=C4UA3159/2"MQ5&LU4$A3-6I3>59B330Q+VXW M16%N,C5H;&\O#0I+,F-G;C-Z;E=027%C+VQN1'!B=7!82T]9<UAT;5!.5D=D M5VQY5V)5*U$Y2&IC83!$:5I/838Y1C)S<FUL9GEW2%4Y5T]W=&58,T=X#0I+ M8THY8V%T36PU5TQK:3)#4$@S,D]:67E+<D@V;$-A-U).2$PT4U%";C%54%$W M2V),04YO<7A03FI.;D$P46))2FUT-F5P.49Q9DIZ#0I(:6]';')Y<GIW-F9I M<$I86'$K23<V2FM,8S5L3#%X27-V5V1N9G(P6%E*,69Z=EE!+RMU<SE16&M: M6'=F64]Z3#%A3&9W4&EY>&8O#0I!,4),07=154%!24%#04%N03-C.$<P<4QV M;$%*04%$-TI!04%&04%!04=6-&1'5GEB;#ES85=*9EHS5FAC;5%U84A"=WA6 M<G)B.7,T#0I%=CEE25 X1$XO,%%U960Q-T=Y83=B;$Y$-#=T94E6,6)C3U!0 M;T%#06DS4DYJ97EQ2T]O2DXT:3DW9F9K2'$O16ID3G1G6F%7>5)N#0I/3"]H M4$1I:DA"."\W969G4F919BMR<6E.:TAK5FA$=4=$6F1';7-F8S9U>&-D,6<O M=&9+5#1P2FPW:S=4=&-B9U13>FAN<'-I.69S#0I,>E1$;DIR;W!.;'%.;$IR M,&-):F1B4FQ&;#%217=V2TA)461#,6Y5135W=6945D%0950U>3<K24M:0F=3 M1W=)=6U$344R:D=6=4E'#0IC-$M',4-33S503U)C13E3=$)R:$IG:'!-,$E1 M3FLR,F1B1WIO.#1A2UEH1'9D<V9Z9G!'>3)G,GA+,4%J0TU4>$5:66A(46)) M9'HR#0HX9DA.>E4Q:DM89')-3#0K>FQ(5E5K075G8T]79U1$55=41RM65D1Q M>4E03GEZ9W!M:6,O>$8K9CE(4'<T<5A,.%AQ3$583DU!:SDP#0HU5FAK5F)! M3T$V>D1-1C4S,S5Y*S=P-3%J8W,S;F(U>&5N2GE96%-A<'DS:F]V4#=M>F5T M,35F9%AU.#,T045-<45.*VE-8WHT2U-/#0IA9G-745EE2EA.3&U$.4Y4;$)M M16,X8D1I9%153S-7<WAY-&Y,;6-M.%1Z1VHU5SEC96]X-3-J3D-1875K=34Y M44QE4V%H>4Y0*VEJ#0I$-3-00GDX469-0T-';S-'>FIE=C1!='1S2&YL25EC M46DQ:&]357IS97=3>$92<C Y26YT93=!:V])<E5U8U<S1W$V:EI1,7!M;UIR M#0HV1#-3;')582MG*U-$,C,Q:T-/9U1O8F=84FY"4RM+05<P<E)%;&M49F%W M=#9K<%I.;V-6:T8W-GEL>6MC3&M"-G!1>F8O<51D9D-7#0IE0S0R0U9*;F10 M1&DR+U!U<W%B,DTK,E(K3B]&941Y8D=W3CEA0W=G1DDP-F,O,6HS.41(8V]N M54UG4D](>4EL4T=+07EC665H<C=D#0IV5E9C:4$R,DI06"M!2B]I9'8S4#@O M-3 Q0FMA42\P:5="3EEB;5)5-5-T4F)W9C9O96%13VQC9%@W06AW-6(X,6@P M<4M,8G S>51H#0HY44%N3%IY03,O0G8Y2V-X6%EZ;2MO92LP5FY->#A:=S-/ M;E8P>79G5U(X3FI';&8O=7!C1%!V<%=8,FMZ>%5D:6QW:DYS9W%X0VY.#0HU M0512<6E3=6]F4'IV3D)31VE8,65'<DTU<40R8G-264U1.6I,9U-13%A'16AU M044V-&TS=V1.:$I(1V=F46='2FY-.&%H1T]S1UA*#0I$3V4U>$I4-49&,D@K M9$1Z6%ID>&=A-'!2;5,W2DIA34LQ=G,P0EAX:$%D8EA"2$EQ.5)R6C0T,4HT M:TY",&<T>5!,,3A$:6ET66=,#0IA:4]/=5=U3&Y5=D]J>C52-3=E5$EY43DT M=GIO07I5-3AY0DQ.,D1966ID95DR0E)'8T-/27-N3VHQ<4Y6=4]S,E=W,51K M-6%V>F50#0I50GA#3SEZ8U5!1DHS*V9!-G9/8DTU:GIL>EDQ+WE3-T]B<VE1 M2'8R*W0K=FPR96YR9$Y4,#%Y,7).55)S<D5$,7(T1V=L9$A8=RM6#0IP:$I) M:U=E-%EC-5I9=D-%,$,R:4Y9:W)7,%)G-F,S4GI,9FMP+WA)=4Y).4Q(*S<S M85AC3$\Y,V%P93-#93%D8D582T573GIE,DI4#0IU<$]C8S-%<&U+1T],5C-S M;6Q%3#-C:E15<DIU-$Y:;&LS66(W;$=G8C8R1W!%,DIG0TM&2%!I,#(Q16U. M3VA+43<X:S%&;TYJ14YD#0IZ4F]G4%9Q0BMS1$TT37!M9SAU2$M2+V(P<4$U M-7)S1VY%-F]L-W-+<6-/64AC=VQW-%!!1GI,0TIB33DR*S=F4VUT4$9M4GI8 M,F8T#0IQ9DYL:&QP<&0U84HY5TXO:70V9F\K6G1S.59Q1FU04UE.27E7<$EQ M4')Y<4YC,3!136YV4'!G66PT=%)D-C904GAP82M9-'!,-'%'#0I&0CE/3T54 M5V)G+V-M8T1#.2MR;T4T47=%2S1Z,&5V6C522&IW0U(V+U=(;E,W.%AM;WEY M:TU':4TK,$9A-U150UEA0GA,3'1E;6\P#0HW4D]P.%A*8E1#,U%T1D-F.554 M-&Q/:$LW2$%#:')N=UA55E=H,6DK1TDT:$]K+VU5+U%+,6)4031&26%Y0D1P M:G5U3%E&,T9I<D5V#0IW:5AO15HY87)25%-X-TAE4S8P<5%T<C1!=4MA5314 M,$M#;64Y1DU"2U=.+T5K6EA853AV<4YH:3DU2WHW57I!=T9B=F9K03%#56M0 M#0IN=D\V9'=-0SE/<E90=VHQ<UI!=4E20DI10VE!2E R<$]X-TXU=6A4.30O M3SE+8VDR>&13:C-O=3@T9T]T5%1*8U9#445V1T1*83DK#0IN9UAU0S)L06A* M2S%2*T8V;V$T<$0P2DMJ53<W;E=(1C!-*TA.2T<S>$PU56)91'9G2E-M979B M>C)X9%,T03%$6FPW0DPK."MW=W17#0I"<$)I1#!V3E0K175P,EE8*VUH94-4 M=SE(;D1S65E(,U5S9C-15F\T9&=(569:065+9%$O8S!O>F9",T5H:FU4=U<V M9CA&05)"*T]X#0HW;D-M.39P3W,K*UE$07%/0V5:=T4T1C=N8F4O3&@V9&PP M>G-.0DY);U$Q;'8V;W,V=4Q,=D8K4G=:-&EZ3V-G0F)F045K:$IY5'9"#0I. M:$=#6D4Y<'9%:'!U371S>'%.;'549U)J339H06ML:&@V=F%S0TM44%%,:'9P M0T-,8G)-9UE*3T9#3V50:7%86G<O;C<Q1WA)5'=##0I7458K2#,R<'9&0TQ) M9%AI9VDY<U-!56UM0FQ394A-:DUF2S17;VPK0DTP-WI.8V(K04IV*U)D57%H M0E=S1S-(5C-94#9I-U9U:S=+#0IK,51.;VTR9V909FMF37IW84=71%%U0WEE M5E-$,'-K:W)L1&M+,F)B-T595RME2T=.9$(X42]9<4%)1&A&:TUX:FEW1RMZ M:$UX0S!"#0IS649T8DA*3F).;&=.2#%0<T,S.4\K:D5E=WID14Q31DU3431V M46)4=%AC>% P-V\Q<E=*8D$Q27EA0U="66M12$)M2C(U3D)Y66-/#0IU-&-O M<4%N0RLS3RM):6=52V1)5#!U5D)50G-)5V97;F%O.4UX6D%R1DE)-4MP+W%7 M8C166E5.07=.4FIA0V5&-G!C5#113V4U06IZ#0I266=7>6AH=4A,27(Q<FMP M>&%G4TDV95=S2W!),7A-<$18>6991$=V:TQ:46-H9G(V-T1S3'$R=3$Q1DQP M1$-4-W!E:U))=C9*26QF#0IP-%1-=&U)>50U;75Z03DR,T]),C17>3)G0R]: M3F5N,W-U,&--1VIP4S<U2"M(1VAD4W(W1CAO-UIE*VE59&](>6<T;7!F3FM9 M=6E8#0IX56UT3TI3:$=51$U!;$)A<UHQ6D1B>7,Y>FU$+S1:.6U#=F9,*VHO M8T-)0C1Q5DY%<WHS16QJ17AJ=$I1-GE%;VMH44LR*T='4G1I#0IU-%)N1&QI M-7,T,#ER-7=%=&4Y;&QE5U1A.5%&5&-.,E54>$))2#="1E%/.6LR96]/:D1D M1&5B=FEY=$PY.6)5-G1!>&\O9VAL=U,Y#0IN2$PY,UDY1'4U9BM7>FY,<D<O M271V82MV:$<P=TI64&Q,3RLQ>6UO238O3V]64$E6145&6D1Z-#-M05E:<%5C M2E8R47ES3%5I1GA'#0I(6&U(4D)O;B\O57!*>&%K3V$T5W%T=5-3:V$Q4FIN M2%%V97$S6F%%4G!X-$$V5D=(8V\T04)B56U'=B]0-FEG=2MX471O,6,P9'=T M#0IV<D%O4D-(6D]C,T5'-%(Y4TUM9T$Q3VU8=U-:;74K46=*<34X5TU.-F)3 M=U)E:C-X.6E+9FTR54%S<&9Q3W=2=6XO-6IG-S-G-6MN#0IJ0V5U15)S4T-6 M6%-H:'5123$O,WDU:%@R=45V1%)O;'),4SA/9C-V;U55=5A+46<V3U)92C1K M939&5VU.=$QV1$XW=6]E-WDX2FMW#0I393!9145,-DQ43TYQ<7HW2DI';$AM M.6163E Y0FQL9T=:-5<T851Y;T14-5%V=&5X0F]A2'%B831O94$U;'9O,UAF M-5=I2$)R,C=8#0IX:"\Y-&%1+T16-G-&=#AF1FPV<U!V,3<T8DE84&,K*U,S M:$1F26$O>$EI5E=065A)9V-V+V<Y45-W345&04%#04%G06Y!1C-014-F#0HK M9W%T1G=!06I(04%!0DU!04%";F-&.7=C;6PR65A2;%@R2FAC,E5U84A"=S-4 M,7)C.7,T:W0K;F%V-$1X<6QZ2TDX:5=8-&QP.6IE#0HY6'1C-7IW<6-J2S=6 M5F9&;VEH231O66EE4U)O5S503B]V8G)":T%3245(<5E8<W%U-6]P3WE)8C-9 M,4=D-E!284U$9#=T3BMF=C1P#0HK,$@K9"MZ-6Q%=VE/-'$Y3S1D4F4K9VMT M1$].279(-E9D,4A16$5+3&-J,4(K249J35IJ>#98:S9V>C96*TQ.27 O3V%- M06,U;U9"#0I2,FQW1FMB>C)*=$U'8DAC1FIK4%HX-&LO06-:3TQ(;FMP,W0S M<EE+4WHT;G1%,6TT8V=B97DW2%)*>&=215IE=VU*=FU024A8:TM3#0ID4&=0 M-FI,0U%S2VUL2GE'66-,24E">7IE>65M-4U:>F%90C1V=$$T=U)A.6II4D-I M1%=G;$1I=4<X-&E*-6@W=UE2=VED>&-N,3(X#0I(,7I94%AU-W=X-%E#5U!I M071V15EB3&1L3$=O,RLS93,Y.3-H:VET13AA5&)Q;%93*VY)2E=#66AC0TU& M-'I$94UA-S!I64I%1&1H#0I+:&\K*V-#+V5T3%!Z>BLY:4=*;DUN3DE'3&=5 M=FYN:EE%5$A:63)Y46%.<V4O93!D,T<K9C-P;3<K,F-(9&@W1B]$:CE06#)T M<C-D#0I/*W5D=FIN64\Y:F(W445+84\X1CE$16]N<4=86'5$-C99:5-J539N M0R\Y4%!..3)F0CAT6E5..5-X+T%#04QB.31B,DI(6&E545A!#0I#,C!A>#)& M8V5A1C!&-5=B3W).17=I:%%H,7A$=6LT8T\S3CAE,7@Y0C)B6'!894]B,W9J M0F=G,#%K:TU51S1.54]W144Y<C%O1&-/#0I#,D]B9C8P0E1D1$589'1*16AQ M>DUS>4=G1TAZ:4YO<V1J>5=D3#-%:G-+4F]83T]0=VQJ:C Q;G@X.'AH245Z M;S!M12]O;7HY4$Y0#0HS-3980W%J27,Y35E595DX1WAN.&HQ2%%&=$)*8VYG M,3AI22]49G(Y:CDT1#E3*S5$,$UB1F0W<VU)1$]P=4-"65A"9$IW9T0X3EDK M#0I55#4Y06]J-F920SEB-4Y$2S(Y24YO;4,X0WAR,FE++TA*2'19+TQT*SEV M,6U%0D1"13@P27%S>F-:13%F5%%42'%"-4M01W=*0E!8#0I79$Y(335':U52 M5$=41V1J3U-:9TEH9F=J,DYI-FE49TQ+3W!1.6%2>$5N5SAV1DU21$=D<%0T M1&5)*T]*179,369%>#0K2GA4150T#0HQ:S8X4#9H4D5V:D-:;V17,%I)8T@U M33-12%-48D0K37@S;VIY65)U<'5H;S!4*U%S-FM40DY2=FLK2DHV269X05 P M1RM&9DI%335J#0I,3%%,97!+5%EN-'=D<3)T>75:>DE'8G-58S51=U4W93AZ M2VAW>49-0E<Y24\U-$UB96IL3VY2,SEO6E(Y3VYQ5DI01V%Q461M-C%IE M;F-(4THY:W1&8VLS5'1O034S-6UQ4C=",$0V0W1O4'=%,U,Q56LO475"-V)X M-&AC148V6%E%9C=":T5,:4QR=C))44Q216],4T(V#0HV:%!E-'15>#A4,T=) M2V](="LT-4%4;3DK;E)#9TA-=T1)>%9H.$-%-U1V>DU'53).,7)U1U!);F)Z M6$E!:$%H1E)H:VAP>D$X;U-H#0I24&A34DAP94%I8C-&9'=V3C,T>6QT>#%/ M9VYZ9DHK35%P<5%)1U1K4&]Y+V1N161!=7-094YS=GE)<C)T;D%E*U!!=T)D M;C%$;7E1#0I%6F9K2&%X.7=N9UA"2FM':51C0E4R>G9T=R]A*SAD=&QC;FIF M:#AB-'E-66EF,D0O47=J-3$V3UA2<$EA;F-E=E,K1VM)8UE+4'!I#0IU1C!F M26HW>4)C0T]X4W5*=UEK:69Y-F5Y1&$X;F5X3%=48TMI3WAZ5T@R54EE0G5Z M0E=/:E%U0W<S35=23B]A:3EQ:4,W4C4W0U%%#0IQ8E-T3FHS;41D*TM&-FAW M,S%62E!A*V-C<&%&<5EZ=$%Q46M)2GII06)$=R]%9TMD34QX53E(2F1N6$5J M,'5#5W,X3&=814)Z:V9J#0I+=6%006Q';7$X64)Q2D=T;$=T-5%0:CA+;C5X M,754:5-$>%):06QY:D]M67AH45=S;59H-6DO57IO<4]J;6I!4$19+W)$1V,K M9V)%#0IR14930T9)02]4-5A%,3%0:3)L9DMO=2M41'4X4&9V=#5"4&]E<$%W M<W-7.7-H9$UB2&5A0FPK;'-83FA+43A*6#50831Q1D8X:4<W#0II9V%W=45S M5&E3=U)8,7$U;'%C2EIK>4LY66AS2T5C<W5F95E/>5=7,'$V:S=3-VUJ<35O M44=04'9505=Y;4925$9K84(R4D1W;VI5#0I%;60R-#(P2GI9955F4FDO;S=- M=VYP339.04)$=VI'6F-A9W%"<#5%3VLR5$UG259G,&<P1%%';S!V-#933DQX M,DA-.4=/1E0K0F5.#0IQ*S%61TU#0U%"53@W,$XR;E=84'EM1C=H9V1G:6A1 M8DA65G<O3S1&=7IS1VMA;S1/07IM>G!*-4%J6D9X<D-75$=.87=857ER2W=F M#0I+<F=K5$M8=$IC>&UW3W1L;4%A:G5R64EW-F9!355*5E5(>$)4+V)H:G-: M:E W>7919D4K;EA(.4-#5EET42MU4S50:VY!665R959$#0IW34-I1V]%<4=$ M-$A8-%!W4')I94]237%!+W=+0F=K1$EW3D%C<7%V:6E133)+57HX+W@U5U1# M2U-!04=X9T]"1VE31%5!33).,&DT#0IH0VQ";T%:13!0-#)4=6MT*T)-3V(U M44]T03E)0F=A245'.4585SES;&QA*S=P4D])574K<71)<3%Q8F-S3SA%4T%8 M6GAZ:4UA37IM#0I6555Q:T$P>59K9VMO6791:6HU-#1,,CAG0V5(*V1G,&M2 M:F]#*UI'16]I.39-4G=Z:6Y)<%)1-$=I3SE&.3995TY$9FHQ.'50<$9J#0I7 M13 K8E!D-C(V,'%1,D]Z-U)135-2:C0O;BMP1G=-1$=(439D-5$T;5%P0VXX M+V4O9C$O37!A34=V04-W*TEX-EA:<FUF<4]-=V(K#0I!,$IC;T%K5"MW>DU4 M9FIH<$PK4W,O+W=L9%(X*VM2:T5#,WEY.%IG1W%B*VE,33=H2VI..%@S;TA0 M44)N:VIV5#%P=FE9,#52>D(X#0I#>7I&0CEY='%K3T=U9#1B9EA305EC<&]B M0UEM;U=!-FQM06)&9#97269:-TA!651N0S5P53@O:R]!2&IC;R]W6$9P,%DR M5FDP<5IW#0IP9V<X-6=(+V8P:#E666QX;S!):&5G6%%X;$DY2SAH0F9/1VM0 M;%!26FPV3V\P*WE!1T9%3S0R:D%K<D4Y8V=,9D5Z=C,T56=C9V]E#0I)2UE1 M9'E606]J-W5%3RM6=4%-=$M(=C9Y,4A21')23'-A37,Q,C96=W!S35A79$E* M,35G=%1I3$9D-T%'6&YJ*V5Q.&Y8-S1-3&DQ#0IW67EU3"\K93!Z;W%-6FM2 M>D5L0R]&8TUK=&<W-E!C3D0V,6QG:2]X9G%'9FM1,F=/>D9,;RMS9U-T;D9G M,GA,665G84E43S128C9$#0IQ>7E81E!1;451:6=6-$)"-F]7;4$K2U)6564U M94<W<&DT-4Y133=#<GI3=S(Y55A'=%A3*R]E9F(R-DM*-4QN<VHT64(K9&9Z M84Y4#0HV279S=U12;$DW06%N='=4<DMP<4E&67DX27)J,%99=#)53RM$8V$S M,DM33S-6>68R=&9V<C(X="MF,W$K<V$K*TYV='AA9C-*>F8T#0IK<E)1-S-2 M62LK5'HW465"=#(S;T%+1&Y).'$W:U,P>FM+2F-O;&M#,C=V0FQZ4&\V9W9! M27)F+S=P,#0T35E6<&-M53%,=V)E66MZ#0IH4&UQ5"]:-D\V*T)06FA03FM! M-5)H-75H>F\K5$Y14C9%16ED,U<U,FIG0C)Y:3159U$Q.4YJ36E10EA*<#EU M=#0P:$-U-U1):%AE#0I"8FUL,7,K;G(Q9FLV:4UW1DQ#13--3E,W2E4W9%=, M=R]'>6%+0T0S3TM7-C%,<T1N*W%!:%E(,W5#.&=D541C64)A5T-):EI&0V): M#0I'6%=#2DAS1DQJ0U4W>4AC0F=6439503,U54U$1UA$,$%50D%!06A464)R M:#-0-W4U1R\R>#508C,S1#8X1VMW661/:5DY:RLX:7=:#0I"6C):-3A::$5O M-5IX=S%N6%)Q.%-P3W4W=S%J2C4U,TA79C-92#EN-S=8,5ID0C5S.2]Q3T5N M,#A'3&U02E,V-75(;4%167=S4&%II5&1X>&A26E--1VI/,E1S-&0T17!Q M=$AU4#-N9G!63&U5-FY),4-)555)2C)W5F5A4FQ23W91.70Q.5E(67<V4$%# M0T]B>$9U0FIK#0I%;&(K:FY#9'="9FQI;78U<'!U>E5-*U1W941I135I1C!U M2G1%,7I#=THU:&1G0F=R4D4U-4-Z>$Y1=SAS1'9967IL9G%.9S1S>FTS#0HP M4T)-63%D14%3;S9F9')6369Z3VPK>FE!>&I/86-+.&="8TI70U57,41L3'A4 M04LY92]F<79M<TQ26'9R-RM323-G:65#,V@K:S=U#0IP>&A85VIK05%$94Q5 M159D15)S66(T;FHW,G%)9V)%,'!I+TE047)36G)K:V]:2#0U-V-S-4182S1M M,D)4<F0S+U!$3C-N-F9B-6MF#0I39TQT,TI+3V19>$MQ9VPY4CAG9U9Q36IX M8VAU<#)!54E5=THX071Z6$AY9FM"<W!'<VM)46=B,$=6>C=993!X<$LV1$)G M3V5)8UAV#0IV=E!(4$UE1F5A:%5Y175U1DU3,E P;$,Y5G-O07-:6FEH65%5 M-T=5=U)O63E#=S5S:D)L4'!$;41A*VE5*T5A4E9.<&MB;5(U83=4#0I)=&-$ M45=->DDQ64XR=7-I=$A09G8S:D%:62MC-&,V9U!A3T,X1U5C>F=4;38W3C-& M=&M5>4YT:U5Z24=%-2MM1$-63GEO2&5+<7-0#0IZ5VU9*VQ,5TAF1C=82$E: M5#E!>E9"8F5R=WHS-'IP5S%X*T1!,WI/>FEI=71Y1'HK2C0Q<$U&3FYC8EAO M23)91516,%5H060S2C=C#0I8<"]L=$Y59#=K33EL6G!L5%AK<5!0=71D44US M6CEL<&,U8G,W>#=S.79B5F%63D1H2W5,16-6.5IP=VYH>FA.>7,Q;6EG82M2 M-%IZ#0I2<$TV168U:3A6-3-E24DK<U9O9&E!5G-/9#,X1C4Y<'<W17ER;GAJ M<7E52'!564YA;U!L-5DP65%P0G1V83%6;E99-#,V02]O1'5T#0ID<S-R2V-7 M0W8O<C-H;3=89TY937)W1V%&>50V,4QN3&,K>54R8D9Z8C0X8S5L:%-Y47IT M8W S6%AY;$)X>G%7.$LY0WIA=6%88F97#0I,02]1=5ID15E52C5$;$EL,75! M<F]X1&MS2%!)435Y27A20D9J,T501FU5>#AM86=-1$%"2F1L15<R1W-/8T=0 M;C X6$IZ945J,S9B#0II1D8K=3-Q+W)I:FIF5')03TQ)15 W8G)*3WA15UAR M3&U7,W)73S Y=4-N2G=+8F=O3U-S6D]X9VQO4DE72&UU2496-7E216II56%O M#0I#=&PX,DTR1DE30CAO8T]014QY2U5#0W)&,WED=D)58VA50D)J1$ID84)3 M:E)K=758;E98<C(R95-7+U!5>7)15E=#331167=H1$E2#0IR22M%6E5R2$PR M835Z4#-80T]B<$IO1F%6,7I9:%0S>D5S1&A4:DXS55=Q-$M!5U0U-G!76C=" M,FEA3T]U-419:4-A62]C,55Q<VQ.#0I6<4HT1T%E63EN,TM'0S=M8D1&0S)0 M9$1(975X<%)3,&QD*TIJ56Y4=V=J5S1J:F%Z26Q"-7DR=2M-24IC:65--V%5 M0TM/2E8Q9VHU#0IV2UIL;S<V5FED4G!&9C5S6GAL35<R>BM3,F=A5S!:<3,Y M9%0U,5<Q5T4W57%Q6GA.9$U3=EDS.4EQ,VQ'1EE,=TTW5TY-63).33!F#0HU M04PX>GI(4G%K;DXU;&Q";DM6-V$Y3DA#=V4T9' K1&-U8TPP4'I*:W9P9F-H M,$9+,&1(>F%B9%E#1S9'4EES<E=6=U=#<W U45%"#0IO:C!+=U,O66](<W5X M0U0U02\T9%,W-D1"2FUT3# X-4YV9TXS=D538G)6+TY1;4]O;#AD9%5I4$-H M;2MR5%IA56IH-6=5-U=),E9K#0HR=$I+>$4O1E%-<#5&9C)R3'5385!U;4MR M+U-10BMD;49S<S%21U=2:S9,=W$Y>%=V:6U38FIX:49J<7%H:T$U,TQ'2DM3 M3F)&8D%J#0IS<3)P97@U4UES26HR,3%X655I,C(O:2\P=C4S164T<%0S-E1% M6FE"8G,R:7%'1D9G-3EY>4-132MY6C!V.$LO16Y/8D=L4F-R;&QW#0I642MY M:5HQ=&5-.&I.;51G6%1I:6XV9WIA;T$Q5S!)5#AA2T9'86A69F1X;TAK<TQE M:597>3)S-F%X;71A0W1A<DPP96E#5C=Q-%E9#0IH>F4O>6TQ.$]A:W-#365& M8FYW3V9+;&17:7EU*W%-;6HO3#DV94M"<'=K1#9M26-/9&-T2&5M65!/<'%9 M6G!W.$4X5F\U;C1&>%--#0I99&]J3T8U-VM34EIL-UA'9VTX4DQ+=U596EI: M-3AX:&=1;'9G5'0V675E1#%/+U4U06PX,E5Z6D5!1WI$0UDR1&)",%%%5&IM M4358#0HV6FEZ=30K:%4Y-&)&2DUB3V)S6EA*+VY1=%EA5G%2<V%03'@O6E5T M=F@X0DPY<U K+W5V,V9(93EG1DU903@Y6C-U4"\K-DYD=D@S#0IF-2]G>CEF M.#,Y=F)X8R],3GAZ<6=V*V)V.3(U-$9S4W!95C14;7,Q1&-S>D5K<6]7:"M8 M3'$Y>GEW5&%#:VU"53-&=5(W6'A::T]##0IS4VTU=4=2:6-F;6LT:F]*4E-6 M.6%H:D-O=G1'53%0<TTT=$]484]81%DX,E5Z471Z4G%J>596>55-85)Z83-Z M6&-P=TDO-55744%P#0I75#(Q0E%34CEF36-$=V8Q57!*669343-7<&-016<P M5&1A;6]X=RMD,&%)<RMI;T)O:4@P85%G239W3$)39T))+W%K+RLU>E%M0F9N M#0IN2V)J.7),3$EW3F=D95-74V]76&A*:GEE1V%T;TMF2U%%:VY3=G1D4D(P M>$1B055E5VLX-E)/8UEF-3EB<5!J1VEQ0EE(1W9R<3@K#0I8-RLO4&)9<6%F M<D]1*TY'6$DR=4PT;#=8<TQD-UA9-DA963<S9T=L;VAP>D=V;VHT:5)92%E, M;$M6:5IK;VDV,#1J1S9%1D9584)-#0IU86UO=5!014=H.4UW-E5X2U1+3E%' M5&UZ04=6.3E,,W-B5#)$;TYY0CAH3DEE3$19,49Q;4XS=&IT4$%:84MD*W)H M5T5L;W$T36=5#0IZ4F-:2&TV<W)9<&U'>'EX254Q9VU)0TXV9CE3.6Q24G9. M<'-R0U5/:C=!659V0VMU,5=K67)E-G!9,U-H5E8O945X3FI&2W8P>4]7#0IG M>E94<B])3$Y8:#EL:51A3'4W6F=$1RLY,$)8,W<S24)Z>2M11%8X3SEV8G4W M=VU!5C5N0E4Q9F]+;%1F=FDV4E8W4UE/;T5,:#(Y#0HW3#5K85%#+TY64U-D M1EE3555I07A'2$MS0F=00WDQ:S4W=49R15,Y<S19<4\R;$AW36912D]M;4%F M3T5F=$5!,5AA8RMN-&)28S=9#0IN37A39#!R16E4=VYL-#9':G1'14M25D]T M86Y*+TQ2>DY5<W4X;E-B;3)4:D=K=7)W3$-I345K.$9,;E-Q-'IX=C)X;T]I M:4ML4&=*#0I996PX9VY1,G!,161J=5=X3&IX;6U6560U465.-C=H64=J55A- M8E=&,E-A1S=43%)%0GE+4EAB23132#A-:DPR:794-&IR6#@S56<K#0I),6\U M2U<S;%<K2#A.4$Y(05%F-&9Q,6Y'44M3<D9',F)A-%%D,W@K64Y*3U=":')' M<5%F<S%--3!M9$UJ9T)0-%%$<%$U5W)43E16#0I5,C U36M&5#158G(Q5UE' M84I%=%9E;V%%3CA+,69&,6Y.14EY>6ET5G%M=D5Q-7HV5'540D99;T9P1EDK M25!F;D5396-T.&E#-5<T#0I29C5:;C!Z4SAE84AL449V-6)":3 T;DU.<$AN M<$4P-FTO6&Q,05,W:'(W541R.%<P;7)H=TY+:%A61FI,+W4Q34QR8FQ%=UEG M:75*#0I!9R]29DEG675#,V9!1E1B1W=0<V]R1G$Q=V5F:E=(9'%M56PU9T1V M5$5Y9&PT8E1V<71&>%AR;D1!1&Y(9UE-2T9D*S=U,V-'-#E4#0I0;S)T3U%9 M3EDW:2]V5$%G>FEV:GEE2FI.8SA73"]!5$="9W<X14UG5W1#44I5>4U/+VEI M5T5U569O<6MO6&EI1DAM<6HO3D5O<WE)#0IC3C95:E)*:G(K4U)5:S1J3WA6 M8U5->FHV>5(R,C)7-BMC=%)W=7%3:W!5;TA%8FE%*U922T4W-65)>$=8171% M;VI403AN4U-4<D19#0I(-V]$.#-**V]O<5AD8S="5EAM=6AS;TQ8;VQD<5)( M1DEL1F=R0G5I2FYL+T]$23)&559G<FLX9&U&-4E';6YH86U73'!T4D1B8F1' M#0IH2G@R9&1/;4](3VQ33$9P2#5!9DQ+=3<P2TAF1$MX9G0Y1W8S,V)I9DEP M3$YV5#=",&HY4C5X43,Y;7HV,V5M3791.#@X3'9K>')(#0HT57<P3T-Y,V(T M=D12+W%60B]"84Y#6DY'>&-#4F),,"]G6%IW:G-.-&M+,2M#4G1U-&1L;W1M M0F)+>4EJ9#-A6%%E=3%$5W9T0DE'#0IE-%,Q*V99-'%!12MR2BMG>2M,2T1+ M:&AG,&A8=V=B07,W3V%D.&17,50T6&):=TU9*W X<E=W4VQL5E1V>#%K9U(W M<F0W97-O368V#0IT4T1(=%I)1E%1,3-D>#9H>51Q0W%I<DPY,RMY3'5T569Y M>&PQ:5@R8C8W3BMG,"\O5E@Q0GAR,D1U<592-S<O:S562' O;VI+63EG#0I$ M2G5Z9C)D.7=B=%DY=F9.1'$R56].:C1(52MP3U5.=UEY44YE4#1/;E9W<#-6 M1'AH;71D47)29F9W:U)S2G-B3% K<S=I:U9&0U9IB+S9)-E$Y-%)W44-T M-$8T;G8V15@O;%9!<U5&5&10=VYP*S,U-6-#>DEL1%)"9$9N<W=*5%!G2V%F M+T8Y2'%X-5A7-VQU;FA%;4=)#0HQ=&QL1$9":4Y:=6=F3&US155R=W<Y;S-F M17A5:&%J,S1%5TQH5%I:9TIQ<U5R-61:2F9D-VA.635S2%-L:6QV<F5$2E%B M>5!"5E9-#0HV='EZ1T=J1$Q72$MF5D9R1RMJ0EEW,S!O3D9!;CET:41N-6MI M*VPR.51&87AM87=4859Z>78Q5S=156U7<$1R.3A693=N2DYF,WAB#0HU8W-# M9FQC2U=8:U=X6DYD2DEX:$],=FEI:TA-275$2C9156UA-U%A9'IB+V%G<F,K M4$XQ2C9S+S%89U54;CE%=7A%0R]G*UI9=FI3#0HY,D\R;D8Q;396<TAV141( M=&)T>D-6.$PQ,FHS0VY-:G-T3$1U2%4Q6&PU3W9C:S R,&IM.%994&<V;VXT M27!,<4-N2C%C0U9/3T5P#0HP9UE*6G=U9E!O1VMG2U@X3W5H1E$W>3-#=D-B M2G5!1G9C,#)+.%5O<DY40B]%<6A-;G)L,FEC=T]W2TXS4VMD9%):93EV5&18 M36%2#0IL=TEU<49*<VPV<BM:355F4$1'5493;TAP6EAY=S=B87E&:DAU3$-' M8U-%6&%X+S9(9T%(=D4W;TYK4FE7<49.45@P>DHY:FUT*TM5#0I4>E!7,6A: M>6A:26)!3TIO4TTP6FM.<D1J<DEA<G9B<VE+0E%/;VUZ5$=(=#AQ=S$W5D55 M2C-!5V1%0SE*66]Y0F1%04-W.#%01FE3#0I)>F5L3V1Z4S!L67%/6&U0:D-E M:&QQ+V%L2GI8;G%F<6%)945+>DMV6C9(;3-(2$=&0R]U56-Q4$9J1EEG9B]L M<49,071*8C@X:')P#0IJ4$U&:D949VQZ<'5Q475S:7%.0BLP5%!L,4Y!1%9: M2TM$3UET53=S,71B05 Q15IF861Y1'0Q8V1&-DPU2VY53$QS<GIV8D=L;&UH M#0IQ-FIA6DE.9DM38C9Z,G16.'1#8DXU3#=C=DEU4F=464E).&%"-C)G,S%Q M;"MN.49.83!N*VUH5C%34F1T45%D:'DU:79H5&E.*R]W#0IV.69%94]556HO M+WEI>EDU5$5N2V5Q1R\T5%E",'0S:79'-3$X-FMX=C)X-G1C=E!W;VIF9EIB M9E9L8CAF851Q0E=K3G0V4'11:VI-#0IB,&0W:55U-FPV3$DP9W-),V=#2'1X M8U!A87IC-E)G5#,P=G=N<"]S9&I18E9K:75J-6Q*0S54>%1H5#%T6$%22U<T M*WIU-4]3-FIJ#0I5+S)Y3U-K<DEI-5-X:4IJ8UI.4%<W,C=I>%(S=&]H8C%T M44Q*.'!53$AN9&-N-UAD1V%B6'!!0FEP1E16:UI+2T9P;7A+<3!Q,E13#0IL M6%9A8U4Y8UAJ*VU&1DQL.7@Y0F),2$95,C9T575(03DP=TY&9VXR.'9R;5EG M;7A9<FDQ:FQ$5GDS2555:&)"3#-O<U=33DAN5$QE#0HW35="87HO,55L>&)H M:3EQ>D58.#A94VXO=DY&,SE&*W%N.'$V9&M*5&8T54MV2G971#-$6'IR3#8U M64UF-$1T-34O*T@Q0DQ!=U%5#0I!04E!0T%!1T%(8S@Y8U(K3#0P1$%!0W9% M9T%!15%!04%'9'=8,T)Y85A::&1'5F9A5SAU84A"=WI69'1J.4I!15 U3W=N M*UEA1TDT#0IX6$HS1VLO4FU"=V-816=U;6YJ4E1Y86)P6C)75F)Q-S)3-V=A M9GIV>G)A;$9/9V1,-$MX2'E"<V0R865M6&XR5V%B5D]U>%1R.# O#0HT1W-O M>&=I4EIT<4E+8F9):%!*1U=M8W9N,6,O2F9-3U1X04=(,$9):7EB:U!S3#$Q M94%::49I4$U56G!U4E9+96E71')T2C-2:U%J#0I#=S,O0DLU57I#4#%$5S8U M150V8VXU-F1L=F9#-7=38D5+=$%H34I04%%'6$%146ES55E-2BMM0U-#0UI$ M3"MH8CA%<7-#3T5J;$M*#0IH5G-6,FAK,T-$9D-2*VXX9D5'5$])<WI,=SA# M,$QH1D)/-S=+=%IC,V=K6E%6<4YM,$<S.2M',G@X-UEQ5V0O5T9!1V9)24XS M3UHR#0I),G0Q=3E787I78F4P15AZ;$EL84LQ66YP550V-4-&5T)%8DE52FLT M5&%52D-15W8X<E%W4$AJ5&YX+S!Q9&-E83A/:FU)3U-0=$EV#0I%8V]!=S)5 M,DU72519>&5D8G4O1C8V<S,W3EA,+VE6-S)8,S%G<C-U6%!:678S9"MF;G!X M9&Y(5C9B=VA",E%T2D\W=C1!9UI#=6U0#0I*=TA#;WA+;TEB2&5N6DI(>#1G M;V59>4ID:V-P6E53.3EU=3154TEX4&YQ34%#,"]7<&@V5&-I>&\T,5=*15!N M-WA)8G1.=F%'<$M.#0IK3FXS64I!2$Q"06M2*S<X2C0P8U1B=$Y(4C!+1S-. M3G@Q=5-::G=H,V5)4G=G:U%4<41(;THP66UA,39%9'%Y;#5/,SED<G9064PW M#0I),C=Y944O>F)Y8S9R;%IR9V1E34,X4TYS;$5"<%8V>E--<$Q&258S.6LU M;C<W.$EN3#!V644V5D-$2R]5,6]V959Y=5%433%+.6)C#0HS9U<V<D(U3T5P M;%9U6CES>'AZ27IJ065Q37%$54MO>4MD96UU44MS171R03563T9,53(P<6MA M,&MP8W!T6%5R67-X5S)&37-E45HY#0HX;6-Z5CE6<V]U=$$O15%63G5!-D5( M;SA39')T>3 O6&YB>3=Q8G4U-F)Z=S)Q0VU'>31O9&%#>&A/3VAD;7I)3U5V M561E6'!O:$=P#0IJ4U!)8W9L6'$W4F-F>$9V=V,Y;3AA=F)R44I&,7HT:E-& M33!D;69E3G-K;BM0-#9F5$XS4W=X=7!H<S-S2&@S<TQU>&5W,W=P:$MS#0I% M,S0U:C4S3S0Y*U5E<7-A-S954T945W19;6DK-G)X54MS5D]29'A'3EAB:'=J M-7%S<V%&-#1L2S!A<$YU<DQX:T]X6FU98S%P-6M7#0HT=C4R8FQ+:$Q9-T5V M6G(T=#$S.'(Y<3,S-U=W83=V,F(Y4V@X148O8TY-:G9D5CEC<CEO:6=U=T)4 M6FY804)-6%)W65A9=S!%9#1X#0IF>E-2,S5L9%-+=&LK6G-636TR2D]Z965) M,3EX="]71G9*2T5L:$=B1U5':E0P<6YY=&%V4VTK0CER-B\R,TAP4&Y$-UEI M+VA5,'=P#0I,2TUY2WA:;T1Z.#@O06%A>CEC2&QA34AI=C5*;$AY0U!-2EEJ M2DEM2$)D<V)6878Q+S1!545S1$)"44%!9T%)04QH1V1J>DYV43!.#0I307-! M04-)-$%!05A!04%!6C-"9F-(2G!D;48P6E8Y<&,S4GE:5T9T8WDU;V-(1'1' M,FQZ,FMJ,G4V=CA(>G!*;%--8T1,85145'HT#0IM34EG2$=Q=WE11&5Q9%1U M;&MP241847-Q5%4V24(V4#4W9G8V,C1D<E%.345U>&MT;%EF8DY4<60O83=" M9E@V6G$O=')F9U K=F5%#0I70FA.6&,S,7E&=U!S16(X=TU/-C=D9&UR:74R M-TLR-DI&5'9S959I1#-72$A!16ET;71H1WIU0DAH1'$K1VA#4%538U!2=F(Q M3'1IU;4]I5')E;F]R2'59.51T,7E214QE<F5E;5$V0S5":59&0V(R=G%5 M9FM*1#-334=/='<O,DIF,V]M<V96-49.5%1):$)Q9D556G1-#0I$1$E/*U%, M>&M2*T]0,D5J44%&1G=1>6IC,'(Y04$S<$I&:F](:UDY66U#2#1F:VXY;G=' M8U9#3&E#0VM$1$9'=6U&43(Y5V17*TI-#0I%9&19<CET4W(T87%D<41T,31, M4$%13&A$1T%B-E5%14YW<T-T,4=V3'AA3#)P:%)Q,49V5W,Y0E934D)/;T%" M3DE.0E(V07!M-'13#0I25#113#A/54%M-V--4%DR96TQ=G9803EF5W)R:41O M1VAJ<WEC57<X2V)--$13>$\P-7!(-V8S1'<X-BMD;C=E85=P=C-V>C!6:G,V M#0HO365H9'12<$@S5&5.9RM0,G Q,V=!6G=%060O2S5P2&M*631H:%=A1THS M=W,V<#=U:E!&9%)*9U1W*V]P+T9B-6QP;C!T8FYD4'E*#0IU549T.6IY,U-K M=W)T>&<V3C@W0S19=6):.3=28F5Y-W5O15):,S4W-BLU>'%5>4HY96<P5$)Z M;VHP66UT5S9)27<T14)W5S5O5#E$#0IL6DE(14I,,'-956(V33-R9#8Y4D)3 M1G=E=&9$8S!*1$@X,48T4$52;F9!07AC24YH0FM0;T5Z:U5)9W9S34UJ64%' M3$=885%Q,W-G#0I)0F=6041J5TQE>6%43$-(5%13*T)604@W1S5/3%%G:$5+ M:"M$,U5,66E.<UAC;E1M-D]$:4-E2'=534TQ5#!4-&,X0D)%65=%54UF#0IM M-#)50SDO1D)S94M8<UIR3#5K-DAI8VMX8FY+<TA49E)Y2R]N25!$3$UL4&IX M66-T-V-%0C5P;5ES3FE/;$)!6&9/03920S!L>DM'#0I';4%(67=V>59:44YQ M,'ET3$5'=W)D=UDT,$(T,59B4')Y*S)T,7E00G!#:%%-=F)7=VEU1DIL4T%8 M465N;6E'13)G2UEU9#!D>3@R#0HO6EA:9%EE04]E=T93<DEB;EHV>2]C8TDY M<B]!1'!G2D\K1UE:2D=O>C5+,6=D-% Q3T8Q8CA1350P=E-/1&%6:71H,4HO M-GA+>6(T#0HW4&QW4FM.3#)/;U5".&I13%%U8GHU-$0X6%,S:#1046,U0W%8 M9E9(,V-S4'9E:E)V5T-&:"]%1UIX0U%32%1R1$MM2&9W.$I-,T=W#0HK>&LQ M+UIQ06I6:V1J='%8-G5H.78Y,7$Y;G%J:G@Y54Y-5$)K4'E"23E)2W5U-#%" M>&5Q,7(P87%29G%!3E8S3%1+*W=G=3):-V5/#0I.;FA656IE-6DP575A2DEF M>5=O0E=":S!O:6=224,V<V1O1C,Q=R]S,UAQ,4M*47A,;&YM14U:-&=(5GHK M9%!F4$)+070T375.:65!#0IB6DUG1F%$.5<S+U%";4I48GE)9613>#DV;3E7 M*U)S.6=114=.2DE!5#-:=%-O065.5S1'94UO0RM&268V13AM4&<U5T=&3CAB M3V%##0IO4G9D=6UV-'DV645U2%ES4UE3+V]1071I>F]9;%1G>#EZ<FAX:BM! M0V18<GDP6#1.8U1E8E)C079!:U5606]A<4HQ=6PK;51%0C5/#0HU:%)Q;$5I M965:+S-76G5285@P4E9Q65 Q<'4Y9$MN=FLW1C$K>DQZ0DUO;$5W36MF3U-: M2%0K8U9L9U%29$M"8W5N1GA657=&-&)9#0IV-W%1;VI'-WEW5&@W>&=45TIZ M2&511C0P8FEE04=M965)3&IF1$1*43A':7=(<'I.0G=X1&]58TQQ=&HO1T%A M=3<U66AB5$1T<D]K#0I)+T=Y=$M32FMF04MP=FA9>')B1$]E:C!M:&11,E9W M,4PY56-J0BM9:EEA3F)1:%1I<U1C4'94,U5(,U%I64HR53)O-5=#:EIO3'@V M#0IK0C9Q<$-#4TU&2E(Q*RMP<F9F3E%A44TQ:40Y-GHO;VQ#,%!2=TU&4&5C M>FMD<$9T-65T,F1G5DTW9#,U:31-+W=P04%60V<Q47ID#0I$,#5I,TQT;D-M M;S!7;E-K*WIE6#)'-6%%3#)64D5H1VLS1F%W0SEK3$M&4WEE-E1A:V<T8F\Q M1BMU1C%P.4YT9&17<C!A5C8R4CDX#0I033=,3&I2=G5,9$MI4FA6>FQ/,7=+ M1T4U5C0K:D)21$%&:T5L04)S:D0U<6]%0S%E6FLU='1W6EI"3U1/04EF-'AS M3C1H3&A1-G!4#0IC06]W:4@Q,&YX36A.=C9::"\S44-H:%)!1E-Y-$95,%9. M5F9.4%=Q6%55-TM:9D=M2F9!-$97>#)36EE!23-7+S96=T901S%$<E=H#0I/ M;4E-1B]X.&97<#58-',U<G8P839U64A(5W%V,T9(14@Y3E Y6&]+1$0U>5-5 M,U=F555Z33ES,VY:<$Y$22\V9$),56]+=759,F-V#0HY3W113FYI-F1W<V)J M;C0V3TAZ,W5Q8C<W;68U+T=)>D$V-VQ,;58Q3D9Q4TM31E!P;&MY>5I'<EET M0C5V>CAC86,S:%5",DU&0FYK#0IE3FME;TE'96Y52FY';V)%6DMB8W986G5( M3'!W-5!J-TIE0E)N9DQ6-$Y#=5%59VYU:%5H2W-3,7%533ER255/;7EX;V,Y M,&IR1%A7#0IK=$5%4V1+<51066AQ2WEQ4VIT4#5O4T14<D]L2&E0<%E,3592 M1'4P-U9V5U)735!/=UEB>#119T,U=CE1:3!"-6UB8SA,:S%L0F%C#0I71G<Q M:41X6G1)=6UA439G,59D5VY09TQ-<$=N05-54F(Q.5-W=W1S*U1I-TLS<V=Y M441G1$)W,#<S55)W;&5V-&PP6GI0:W!18V(R#0IL,<=T)95U$T:G9)3TA" M36=N,SER-6-1=4=N:4QP:5EO<V-V3T)L16MS4E=U<4)59&U88D1.0D%11E=9 M;D)H9F9K6D0W9&=*,$%3#0I6,%9U-V\K9F%P1%=)4EHK8TIJ,E!19'%746)4 M;UIR33E&,7AI<%5&53A2-W!H,W@S;V).,'1G2%19;G8W-S9S-$]46G-#>61M M-4)4#0I,<T@V<S!7;G5E:#=:17%C:W%L3%9+=4M-9%-(=4$U63151FI3<3!) M-G908DXR;&1"4S!M<7AS:'EC67)-4SE32',S-%-*>#-!43,V#0HX,#AK06)W M;C!X:TA!1W=13U99.#-4=DE)959S0U!9;V(X:T8O<#AZ;%-,8F1&8D]90TYD M-V1&1FMV,WI/6656=G0Q5T5G9FE3;U18#0I'3'=/,#5+;%ES27%!,C5D1"], M06)':SE92VDT.'-"<W%B>&Y50DIZ44=E;DME8U9T3$UJ4'IS-51815@P:6%% M1#9&:E56<6Q4-5)S#0I#05161GEU-VXV1T9G-4HT=#DU;V%"3E<P:$9M4GIV M8TEA<E)Q5E944FMR2S<P84MG4TU14&51-D=$2G!N0E@X0F-V4$Y2,UIX,W1N M#0II86UC1G1K<6QB66=C64%T4S5+-%1,-CAJ07A%;&I&,TA*2DPK<49H64XY M6%5&<GHW<&1.=C9..7=":W9I4G9W<CE0<T1D6'--1'=8#0HP9$E)>'!,1S V M64E.<D51-&92-W!O9W-*,FMU>4-C>&QG+S1%>6M:<$A$1EI*0E!&;"M61E)I M0DI09$AC6#!E>C S17941D\U>6I2#0I$:D5-5VUS5TUC.5E5;%-,4DAB2&)J M>D]!3SDR2BM)>F\S.5$U5U)J>7DQ>'=::49R0U!%8WEP,&UM279'<DM34&U4 M1V)O>4)W;DMJ#0IF;'%B-55/=4(T,S)A87A7-'583'I&64-F0U,W-5)2>4DX M079-3CEO1DQG4D,Q-$E83$523'=2;C8Q<'AW:VY2:T].2'!X:S93.#$U#0I% M5SEF,C9,6DM):%8K9&MV95IY16IG+V1+<'-S>C-1=C%U-%I%=#DO,&]X6C9. M>&]W9D=A-$I%-%HT:7AX,79E07 V;F-+,4Q4;E-T#0IN=4@W9%$Q-4IT9G5' M+TM!>6I*=%(V935!.599+TE462MJ47IR,GA)53A.5S9(;EE#94I30FYQ4$A' M0G1J2T9A9W4V-55K,T)-:E)I$6DMN;#E25U,O,G5W2T9C6G!4,7 S.%9T M0T(O<V%!9T-I=&M--'=M;VM"3E<Y>#EK=#A.-U,X5&4K:S-&2DEH8FA1>&10 M3E0V06-A#0IV-7-W6CA',E1T:G-2*TYF.3%%>6TY4'=!;6)"8G=P-FEO<WE0 M:6-M>F]M05!"4$)O1G)+-T8V2EA*5WER>DPX=C5F.&-8=DIB2&A.#0I&0V=5 M1$A:3T-2=FIC:$]J,%9R83%'4EE864IP<$AT5"]R;VY!;F]60UI+0DQ7<V9) M<VI6:FA8=%=E<$]U47=:.7AZ-49Q=&=X-F-X#0HV=4DW<4LY=C$P<F\W2EA, M5FIA>EAA9&9+:G5(<VE/5799;&U/;%1*3F9W1D-9=UHP-7!K83%+1$1Y6DA% M,$Y9*W-B2%E*:VY.-4)O#0IX1$ET13,T;&=T8C%)1491,4-H8T1Y1E%R.7!, M3T%#>F=F4U,U=T)39W<V9&)#3G@X66QU*V9X=&MQ8D)5;6IJ9$MN=VQQ83!J M>3!7#0I.8G9,5$1(0W5$;T1:>&%F=$1%5U=82W0Q=F=*2W%%.$XR;DI5-GI9 M.' Q1TAL6D(S,51S1DEU;S-3;7A)13EZ8C-40B],:$1A8V)*#0HV<4YL<C5* M,T-I5"]R<#,U9S)53#=Z57EM1$IV<F](;&=O9%5P9C5B:&EZ1VAL9FQF9GHO M-V=H04=/1V%1-$%N.#@O4U%C0S9$<&]:#0I";7EM3'EM-F%T2&8O=C=Z:$<Y M,79A3&)-5FMY<S1,,79+.#1E9F=2<&AF1DAZ0E%L>DAY1T0K6'5/92],>6HX M3D]04D-5,F9H17(P#0IM-6Q(*T4Q4C!H8W8K8FY4.71:+T%60DQ!=U%504%) M04-!1#%K6%DX:S<P65)Y04-!04)C0U%!049104%!1V1W6#-">6%86FAD1U9F M#0IC1S5N6#)L=DQM;'5B3%96,U=V8DU"0B].+V@O3T1O64183V1P23E:-E50 M5')G4DM.=VIR,#A!;SAT;359:W1#=6E13&\O+S=:0V1P#0HS03EV2U5N,$5* M0S4S.&5D-VDW9#=M1E!'1W@K-$9D1T)52G5%;4YP3&AG5&\O2T5D17EQ5T%7 M8W1:.$=Z6E9W0T0O=6(R2#!(56=X#0HR:WA):$YV<C!296<P:%)9;VU,0G!& M6&-!03(Q5U9R2W!W>6YS9U!8=6A3-69O4WAS0U1H=DYF=DY74&AP.$U)4W Q M4U)R2FU!<493#0I336UX<&-M<R]K04\S1WIY:4I+0DYF054T57!R>'I$5T=3 M*T528F=J:6%R:6551')+:U$O6&]S06Y)-%)156EP4WE056ML44]D5UAU#0I2 M<T]B*R]&3C!K.39-9CEM,$)A:W1W,D,Q-V=P<WAL,'4T=D9)<#5587)',F5F M8U9Q=$Y)-4IT;DM,53-1>7)4='%X5&EC0C4X9F59#0IT<T-$3CA$6E%5.%EF M0TEL:3%M2V-.3&]*=#E*53).3VIQ1VY226Y/5D<Q5U9Y<TTO:'A82F%F:5-" M<&AW3VE(>$YC3$QN:'!S3DPP#0I45'5Z16DO1'=%.&E+45-J+U9Y9%AZ:$]" M=U!$,7,Y0FQV06Q63TYQ56%22E-N-T=Q<5HR<#)U<V(Q5&QU+SAZ=4Y7,4$Y M-#DK1T]2#0I:,5I":6EY;T=!>F5W1&9X6#A09W%83#-R<CA(=VM517)88FYM M=$MT=6)K4&)R158Q57I02#9V27)D35A&;&-K1SE1<3A*.%=2,S9H#0HT331E M<5EP=4Y6;'HK8G9V9VQ6:VDX:S%Y=V)70U Y+TY:.79W*TA/<G8P4U1,>EA/ M5G(K64I5:DQW3E-T=51X;')D6BM+9T<W;$0X#0IF5E V-$M0<VYL4&)/-S-- M8D\K;3)I3UA06DIO4',S:#$Y550K3"MX5C-V>#9#<G)(6#DT;F(Y45-W345& M04%#04%G03 U3C)036YQ#0IM-$MQ0E%!04U",$%!06]!04%"=V)M9&9A5SAU M84A"=S-6;'14.71)15 V3WA(*UET:$M88TML1'548W!R4W$Q2$M)-4E49S%L M2#5"#0IS:'@W:RMZ2C)85C,Q,&QZ5F8O-WIC=S9X2&UT43E-94I93$ER2&9E M;G!L;EIR1V)H+W0W9THX5&Y5,DTW03AC2$(X9"]F655V+S9!#0I6-&YU0W5H M37)"3D1#,C!6835.<$5Z;5)S27=89D=D1D$T639K5#!:4C U<4):1DM)2DA7 M1V1N3B]925)94%!U4'E*,C1$4S1G6418#0I7;'-(2&0Q>EDW<#=,;4]H54I& M6&53,DU*8FQN=U9%0719-%%%35=X2&UA4FUK:E9H-35-56%*.6-N<E)/43)F M:%5E0BLK:$%'-&=X#0I"26EC,7I&=TQM<S%M*U!X3T]I4W)50V)F;DY"<4(W M<S<O;F1:2T]1,$)L-F]N351I>4-I*T%/,#-/>DQ&2'!O66MH94<T2$]/:&=6 M#0I8:V]6<#-L0VII539Z;V0T:3)&03-99$XP=#@X+TY99DYV3D4Y;%%I96Y$ M5U!G+R]V:F=,,C5F:$<Q>D9*86Y%=VEO-C%7>D-$449:#0I82&%.4D9N;S5" M;&TR2$=S4FM18T9A5GIB2U-J83%40CA&<W9.=C(X1E(Y>6%94T962&%Z4752 M9G9(-$5.5E(P.6UF-S5Z;THP0RLX#0I&,7=08U<T35%P5D])1$XV2DYK4T95 M6E!P-FME8S5P>D923U%T<U9Y;5IB2TAB*W=,;6TQ36UE=S-N<6AE,&Y7,%=* M27IO84I24%%P#0I*-UE7-#5E1&5"0UI1>EE.5TU*6FEQ54Q,.7=%37AW3D)6 M>$Q-55E&27DR5&U9-%),<&%L1R\V83EH-7-P,&M/;S<V654X57),,VAZ#0ID M5C!%=F9G<70U0TI/5$QV,6I(<FLO>3AU<&HS;U-X6&Q%,E5U=T9M*T4P:U4V M;F=,*VY*9C4U,SE606%*2&QU16I'0T=Z5F9,<'8V#0I#<71.>4-%;V1A26)" M96-2>'!T;F1#=$)V;5EO,GA51VIN.70P3#=F4%%766EH:$QJ1U=#;&8K>79% M64Y39E9F>FTQ.$A!4DXO148V#0IH=VAO5"]A1%%:63E8=#9!9E-X1D)G:&(S M3B]F2392<T9S54-U3#-!2C5I=%5,9C1D37-Y3D=P,&YO1VXS>'IF,V=Q6$<R M5S4X36-Y#0IC44]'8GE#-$0K<V5R,#AP:#4R3B\W85II3$A826=I<&IQ961H M;E)E1%EW95<R0T-31S-$8FU21G$Y6$0Q3U1)3BMM,5175W=6>49D#0IL8UIY M,&MH16TR:S!J3# U9VQ'55EU5DYR93=V<E-I441R9$A22$E.2C%C4G-H04-8 M-V-(54@O*U5!0U-+<55/=7=55TAG4&4V679Y#0IG1E52=&Y5<4A/2TDT8VA8 M:6LO,T)N1TDT<E4V469M-4-P<FY/:V\X;'1Y2E-K:#%*-WIC;'E00DYO<TY$ M0W5N2$=05'!3,U5J<6%O#0HT<6UH:C9-46MA15IZ66UW5G5!44M20VQV6&=R M>%0W:#9517!X0V%M;$5G:%%325!E0T%1,4572&U4;$5+3TUC35I'6C!)4796 M='9.#0I3>$%F;F-D:FTK4GE03DMN9%1'4D142T$K-E-Z8SDW4W=72VQS.31U M;C!U8S=+6E5O2&E8>D=I1G!434A,<EA5<V]&6DYR2$\Q13A/#0IH<$=,4SA* M-D)L,G=K;TIE-%1):E9W>7I"95DQ5TA:3$AU-CAC=&%.;E9S-G):,TM+,FQ4 M2&]D<S1P6D@X>6]7<6109W966#4X>7)L#0HW:4-O,6A6:39%361$-U%6-5EX M4V=35$-#5%!%4419:3%'075P3&9G6G9+:E-+,DA43'%Q0E!0-DMT6'-G>599 M;7I"65=66C@U.'15#0HX864Q2F$V=V1'5V%F4#A#5U)F=T]I2U9$-E=R;6-4 M:4(K:D1-;U<X.$)+2&-/=#-M14$X3F%H<VYQ3#,K3#A85G!&,&TK8E-,=70Q M#0HQ+S,V-4]43$99:T)H,%=O1E)P-4$S5BLK,F(K;TI+=T4Y>G9&*V)R9VDT M5C-R<D]S0E0R3G5/,F=C55AX.'-D63!N<'EG2&-13D8W#0HQ:T<R4$HY.$98 M:#-H93,O4$QF-&MB44,P9EA(;4LY=$)2=6TK-3,W-G5A<'8P5E!F9D%1-WA$ M5TAW6%-+=597<%-&<V-E87$P:V98#0IN<TLR86%0,T9T=V1!,W!(2T-V:C)) M;$=W<S1E8R]!1&]M>C9J<4PV8E!R0FYQ6&<R2U,O3$U58DDV<5EX;6QR=650 M2G$O4U5E>&9(#0IR9#)L<&9P0EE/;$(O4C)M9C!N2#5P2"]'5#1$64QW3&HV M1F)R8C5--E0V+T0T2D@O=3%056]0=V9F=FEL,D]O93%.4&-N-58Y4')Y#0IS M;DU6,'%U:&0U,U0X3TQ65F9V-FQ*1CA);%-#-'%I+VQQ=C9R2DE):5HT,E$X M<W9I0E0K5WHW0T-R<3A.8FA285=(83<O3"LK0U<O#0I02#-G,W,O0WI-9U)1 M:#1326Q)2$-05&I1<&HY.'1F:UI9<F1#<#,X;W-M<&)Q.'<Y1RMP0W(S;&%$ M8V]M<'(K1#%"3$%W455!04E!#0I#04)C0C-C.&15.%=Q47=&04%!=T=W04%% M44%!04A"=5HQ.7!B,3ES85=*=V)M8W5A5S5S-U9N+V$K33)&4#@Y:U O:&MC M1U=L2GID#0I/>&E$6$LO47DX;TE(3S(T6E!F5'=#:3)9;799;'!(:W!+2#!F M.3DW:W P-&%D<6TV4F4V36Q/85).3#<O=$AN2UEP+S%'-$)0:TY:#0I,2E=) M17=/9FIO.2\O640O9F]/>E-%-#5J2F9A.$5Z1$M!*VQ+<5)I:&MD5WAG;BMP M6&MF36AM2FU1:5I%5$E(;&MC44-7,E5M2EIU#0I12$A1-6919DAH;W=%:WI# M-&%U53)S0EEZ<WE#6G(K2FM/96]Y2VXX=UI5;759+V5S469D365F07=L0FU" M8W5826\Y:$IL2U5'03-0#0I,.&)N=V-F9S)$3EA"<5-#145-05IP>4]X2FAI M-%!U3'AC2V)K:3%0<71J9D5U<#4W6EIB5%19<4-6;6=*-TI5269C67AE*VA: M5#A7#0I+8WI14D5:94LT-T]'<&A86&]O.%1-=4E(271K5T=9-%ID3T%U;SDX M,'4X9G9F4FIZ9GIK+T]"=T5M;U1#6&YA2$M*:35$14\X4W9$#0I6439D65%E M=4=W<S924C4W4V%F9'5M;$LR8U0U;75)2D$V63%6.%I,:7%+<'5E3C50=C5H M9F]*435J35(P-$Q/-U%526A&45EW9E=T#0IE4T5$<G!2571Y8E%P44%N0WE8 M;4-,;'%U=#-+5V-:,7=524\Q:C(T:'9526QE;6%&;4A79E(O*WAP:59,078T M."M+4%E(4EI$5396#0HT1% T>FLR<&-M,T)U0D-24U-X<T4R-C-G2GI:8U)2 M>EE'4$=F=%E&1'A(;5!)2E5H;E=24V5C:U582VA!9DTK1T%I<&=Y;E1F1$-9 M#0I-6D=70T<W:'1.57E#0D]U25IC1T%A<U5E:3=234<T3$)N3U=I;6AL=&0S M0V)696M'1'5C;4-7:45S4$5(55!)>$%O555U5&TP-&LQ#0I74FE&,C(X5VU& M3V=P0VY/;VE!4VE%5$-P*S5746UG=7@S>CE$03=D,$M.545F9VIB=$)45D90 M2F-S4C4Q>3-Q9EA:3&Q-,%=:1C=-#0I45DTQ>F0O<VLK-V9/94EU17IL1W9K M9S1P:U!:;DU2:7IN3UE#-S1!0VA%14IR17-K1U-162MY1TDS.5$W8S5C+T5! M>'I!4FEU,%)I#0I7559E2V%I:BLS<#5/6C1%-#AN6EI$44UH<&-8*T\U:3!K M6'-P2#)H9S57,4PR-S$W<64W;F%*87)K8FXR<6MW65AN3S T04=4<7E(#0IG M=T<Y-SDK;B\K1FYR5BMM56=55S=R9',T17-Z<$8U9'9D,'!14'HP<'=,3'E1 M=51V2E!W5B](<T5B=%1264QV2E!H,5%!.45B.$90#0IB1E!Y3'AU06]D,SAE M6B]T+T4R>7E(1VYY1FIC6DUB<'-R1WA-5UA606MU:DYG:$UV9'IA*WI73#1V M:VIX<6%+5$5J9#-H2W9B5&\Q#0IG,7%E<T9'0S0S=6DW0W)P64UT=6IX<$5R M5W-7<5)W:59K,T961$<Q<$Q.0TY4<GE,-$9A;W%7>G@U0S5J56,T1W0X;3=J M-%IW2%A##0HV03%V-EEI>3 Q;&XQ-35W:DII;3%*0G=L<WA)27-Y3C5&3$IM M=V)76DEX.4IF+T9135I-,D)#5S8Y4C5D-TIO2#(T,VU,;D5K1F%9#0I*+VLW M1VMN9G%L9TXR:4PQ9'),=C)8:#@O;C-3,V0U24Y9>3-O8FAN8CAO.%9H5'!S M:W5'5B\S;UE1:69P8EEH8S1*8FII-#=N0S13#0IQ6&MZ<593:G%'-64Y.$LW M8BM'67)N6D=)834T<6@S96AD:U@T,#=F6')"-71X9V95434R9W183U!)>%=M M.%$W-%=Q5C1'95)04DMN#0IM,C1-0F]1-%!(43E!8FM.8C!8,D-002MG6#AT M6C%,1E!M0F4X1'--1FQ#62LQ:C5/84AY,T=W,4A$-$U"9W<T<45*.4I),S%5 M5"M%#0HT6#!N-6-!,3-5<B]Y6$(T=7%P>5!W>G9P86HO82]Y:VIN4C174CE2 M>C1J4%=*;6%Z5D=U1VM7*UDP5S,Y+V)A:S)T3D\W0GAD-V0V#0I+:3=U269' M1#DO0RLU4#9-=2]D46UN-S-26'E2=W(S,B]J>3!U;V9E85-Y54U0=F9A9$)Q M+W5+6$=H=%=8=3)B-U)U-C%N:FI#6&IP#0II-# S2'8T<EAM,DTR6GIR.5A7 M1'9:9W0V;#AD.6HK1"]C9G5.4$(T4THX,'A2<VE)4TEP,5<S:'=%3V%1.5)Z M,WAT<S1(5&9I=TUR#0IT4&9&=U$S8T%'1$]T;C5O1T%X:6MB6F(O=TI14W=% M0T9!055!04E!0T%#<T%N8SA8635*-DM)3$%!0D)604%!1&=!04%!04%!04%! M#0I!0T%!04%!04%!04%:6&@P6EA*=5@R>'!9:35O8TA"45-W14-&04%504%) M04-!06Y!,V,X1S!Q3'9L04I!040W2D%!049!04%!04%!#0I!04%!04-!04%! M1$]#=T%!6EAH,%I82G58,GAP66PY;F171GE:0S5O8TA"45-W14-&04%504%) M04-!0V-!6&,X44HO-D-Q,%A!04--#0IC04%!17=!04%!04%!04%!04-!04%! M0E%&44%!6C-"9F-(2G!D;48P6E8Y:5E83FQ,;6AW8T9"3$%1255!0E%!06=! M24%!64%D>GHQ#0IX2#1V:E%-04%+.%-!04%204%!04%!04%!04%!24%!04%# M-'1!04)N8T8Y=V-M;#)96%)L6#)L=DQM:'=C1D),05%)54%"44%!9T%)#0I! M3&A'9&IZ3G91,$Y307-!04-)-$%!05A!04%!04%!04%!04%)04%!04]O=T%! M0FYC1CEW8VUL,EE84FQ8,FQZ9$A*;%E7,7I,;6AW#0IC1D),05%)54%"44%! M9T%)05!74F1J>51V4FA(24%)04%&=TI!04%604%!04%!04%!04%!24%!04%' M8SA!04)N8T8Y=V-M;#)96%)L#0I8,T)U6C$Y<&)Y-7!B;7A14W=%0T9!055! M04E!0T%$5&LS63AY97%B9W%O1D%!07=(44%!0V=!04%!04%!04%!04-!04%! M0S909T%!#0IC1S5N6#)L=DQM:'=C1D),05%)54%"44%!9T%)049W2&1Z>#%4 M>&%P1$%504%$06)!04%204%!04%!04%!04%!24%!04%)>$5!04)W#0IB;61F M85<Y9F)';&EC1S5N3&UL=6)&0DQ"45E!04%!04-!04E!4#!"04%$2%-104%! E04$]#0HM+3 P-3 T-3 R8S,R,&,V,3DP83 T.#(V8S@R-#0M+0`` ` end begin 666 02. Re_ [gil] native image format loaders_savers.eml M1&5L:79E<F5D+51O.B!D<V%R:71Z0&=M86EL+F-O;0T*4F5C96EV960Z(&)Y M(#$P+C(P-"XU.2XQ-"!W:71H(%--5% @:60@:C$T8W,R-#,Q.3-B:V@[#0H@ M(" @(" @(%1U92P@,C,@36%R(#(P,3 @,#<Z-#<Z,S@@+3 W,# @*%!$5"D- M"E)E='5R;BU0871H.B \8VAH96YN:6YG0&=M86EL+F-O;3X-"E)E8V5I=F5D M+5-01CH@<&%S<R H9V]O9VQE+F-O;3H@9&]M86EN(&]F(&-H:&5N;FEN9T!G M;6%I;"YC;VT@9&5S:6=N871E<R Q,"XR,SDN,38U+C<S(&%S('!E<FUI='1E M9"!S96YD97(I(&-L:65N="UI<#TQ,"XR,SDN,38U+C<S.PT*075T:&5N=&EC M871I;VXM4F5S=6QT<SH@;7(N9V]O9VQE+F-O;3L@<W!F/7!A<W,@*&=O;V=L M92YC;VTZ(&1O;6%I;B!O9B!C:&AE;FYI;F= 9VUA:6PN8V]M(&1E<VEG;F%T M97,@,3 N,C,Y+C$V-2XW,R!A<R!P97)M:71T960@<V5N9&5R*2!S;71P+FUA M:6P]8VAH96YN:6YG0&=M86EL+F-O;3L@9&MI;3UP87-S(&AE861E<BYI/6-H M:&5N;FEN9T!G;6%I;"YC;VT-"E)E8V5I=F5D.B!F<F]M(&UR+F=O;V=L92YC M;VT@*%LQ,"XR,SDN,38U+C<S72D-"B @(" @(" @8GD@,3 N,C,Y+C$V-2XW M,R!W:71H(%--5% @:60@=SEM<C$W.3<U.3!H8F0N,30T+C$R-CDS-34V-38Y M,3@@*&YU;5]H;W!S(#T@,2D[#0H@(" @(" @(%1U92P@,C,@36%R(#(P,3 @ M,#<Z-#<Z,S8@+3 W,# @*%!$5"D-"D1+24TM4VEG;F%T=7)E.B!V/3$[(&$] M<G-A+7-H83(U-CL@8SUR96QA>&5D+W)E;&%X960[#0H@(" @(" @(&0]9VUA M:6PN8V]M.R!S/6=A;6UA.PT*(" @(" @("!H/61O;6%I;FME>2US:6=N871U M<F4Z;6EM92UV97)S:6]N.G)E8V5I=F5D.FEN+7)E<&QY+71O.G)E9F5R96YC M97,-"B @(" @(" @(#ID871E.FUE<W-A9V4M:60Z<W5B:F5C=#IF<F]M.G1O M.F-O;G1E;G0M='EP90T*(" @(" @(" @.F-O;G1E;G0M=')A;G-F97(M96YC M;V1I;F<[#0H@(" @(" @(&)H/3)N3W9:5W%M;S<T2G4Y,S)T<F=$=DQ3>4LW M3FA5;C@S63E-23 O5RLX>&\].PT*(" @(" @("!B/7)'2$Q25F9U;U9(3%), M2G9F.%)->F-G*S-0;'!#*T0Q8T1P5T)8-$EB17I(6'%$*TQ!6#9J5D],539! M:U9W:FU"2 T*(" @(" @(" @16=(,3)U07,Y<EHV9EE-='!J3TQ84WEM5S(Y M5T4X9V=X<EAR:%)!-TYR3&HR8T<S;G,U,55A1&%Y1&DP5%%A;V55,F@-"B @ M(" @(" @(')$,BMU35!3,S!5.%AD34@S,F=B=G9#<T<K6')K-6-)=C<U>G,] M#0I$;VUA:6Y+97DM4VEG;F%T=7)E.B!A/7)S82US:&$Q.R!C/6YO9G=S.PT* M(" @(" @("!D/6=M86EL+F-O;3L@<SUG86UM83L-"B @(" @(" @:#UM:6UE M+79E<G-I;VXZ:6XM<F5P;'DM=&\Z<F5F97)E;F-E<SID871E.FUE<W-A9V4M M:60Z<W5B:F5C=#IF<F]M.G1O#0H@(" @(" @(" Z8V]N=&5N="UT>7!E.F-O M;G1E;G0M=')A;G-F97(M96YC;V1I;F<[#0H@(" @(" @(&(]87EQ53)92$1( M<VE*<T)!,SA/=#961EA096=P1DIG27I/-V,V9S5E+RM#8WHV1#%E1BMQ859B M3'E20T4V5%@Y2$9.#0H@(" @(" @("!A.&9834](;7IY24YP=F$Q2T<U8E4Y M5DIE<DLX9FU80598,%-A4VIR3$=*,W5,;V=W83DQ>DMW22\Y6%)O>3!U:&PR M20T*(" @(" @(" @6E$K,G-.=G%T96%1*S9.,VM,:U%D-6E::7%8;WA522]1 M55 T,#T-"DU)344M5F5R<VEO;CH@,2XP#0I296-E:79E9#H@8GD@,3 N,C,Y M+C$V-2XW,R!W:71H(%--5% @:60@=SEM<C$W.3<U.3!H8F0N,30T+C$R-CDS M-34V-38Y,3$[(%1U92P@#0H),C,@36%R(#(P,3 @,#<Z-#<Z,S8@+3 W,# @ M*%!$5"D-"DEN+5)E<&QY+51O.B \-S8S.&4V93 Q,# S,C(Q-S Q:C9B-6%C M9C$S:C)D-V,W,V(U-# Q9# Q-#E ;6%I;"YG;6%I;"YC;VT^#0I2969E<F5N M8V5S.B \-S8S.&4V93 Q,# S,C(Q-S Q:C9B-6%C9C$S:C)D-V,W,V(U-# Q M9# Q-#E ;6%I;"YG;6%I;"YC;VT^#0I$871E.B!4=64L(#(S($UA<B R,#$P M(#$P.C0W.C,V("TP-# P#0I-97-S86=E+4E$.B \.30Y.# Q,S$Q,# S,C,P M-S0W>#<V,3$Y-&)P8C5E-V,W-C(P9CAC.3<P9D!M86EL+F=M86EL+F-O;3X- M"E-U8FIE8W0Z(%)E.B!;9VEL72!N871I=F4@:6UA9V4@9F]R;6%T(&QO861E M<G,O<V%V97)S#0I&<F]M.B!#:')I<W1I86X@2&5N;FEN9R \8VAH96YN:6YG M0&=M86EL+F-O;3X-"E1O.B ]/U541BTX/T(_4D<Y=%E79'9A:41&;T=&>6%C M4T@_/2 \9'-A<FET>D!G;6%I;"YC;VT^#0I#;VYT96YT+51Y<&4Z('1E>'0O M<&QA:6X[(&-H87)S970]551&+3@-"D-O;G1E;G0M5')A;G-F97(M16YC;V1I M;F<Z('%U;W1E9"UP<FEN=&%B;&4-"D]L9"U8+45S971)9#H@1#!%-3=#,C<Q M-C0S-S,R,CA"03D-"E@M17-E=%-C86YN97)"=6EL9#H@-C@Q,0T*6"U%<V5T M260Z($0P134W0S(W,38T,S<S,D0X,T$Q#0H-"DAI($1O;6%G;VHL(&YI8V4@ M=&\@:&5A<B!F<F]M('EO=2X@66]U(&AA=F4@<'5T(&$@;&]T(&]F(&EN9F]R M;6%T:6]N#0II;B!Y;W5R(&5M86EL(&%N9"!))VT@82!B:70@;W9E<G=H96QM M960N($QE="!M92!A<VL@>6]U+B!(879E('EO=0T*=&%K96X@82!L;V]K(&%T M('1H92!N97<@:6\@97AT96YS:6]N/R!9;W4@8V%N(&9I;F0@:70@:&5R93H- M"@T*:'1T<#HO+V=I;"UC;VYT<FEB=71I;VYS+F=O;V=L96-O9&4N8V]M+W-V M;B]T<G5N:R]G:6Q?,B\-"@T*270@8V]M97,@=VET:"!P;F<@86YD(&EN7VUE M;6]R>2!S=7!P;W)T+B!&;W(@:6YS=&%N8V4@>6]U(&-A;B!D;R!T:&4@9F]L M;&]W/0T*:6YG.@T*#0I"3T]35%]!551/7U1%4U1?0T%312@@<W1R96%M7W1E M<W0@*0T*>PT*(" @("\O(#$N(%)E860@86X@:6UA9V4N#0H@(" @:69S=')E M86T@:6XH('!N9U]F:6QE;F%M92YC7W-T<B@I+"!I;W,Z.F)I;F%R>2 I.PT* M#0H@(" @<F=B83A?:6UA9V5?="!I;6<[#0H@(" @<F5A9%]I;6%G92@@:6XL M(&EM9RP@<&YG7W1A9R@I("D[#0H-"B @(" O+R R+B!7<FET92!I;6%G92!T M;R!I;BUM96UO<GD@8G5F9F5R+@T*(" @('-T<FEN9W-T<F5A;2!O=71?8G5F M9F5R*"!I;W-?8F%S93HZ:6X@?"!I;W-?8F%S93HZ;W5T('P@:6]S7V)A<V4Z M.F)I;F%R/0T*>2 I.PT*(" @('=R:71E7W9I97<H(&]U=%]B=69F97(L('9I M97<H(&EM9R I+"!P;F=?=&%G*"D@*3L-"@T*(" @("\O(#,N($-O<'D@:6XM M;65M;W)Y(&)U9F9E<B!T;R!A;F]T:&5R+@T*(" @('-T<FEN9W-T<F5A;2!I M;E]B=69F97(H(&EO<U]B87-E.CII;B!\(&EO<U]B87-E.CIO=70@?"!I;W-? M8F%S93HZ8FEN87)Y/0T*("D[#0H@(" @:6Y?8G5F9F5R(#P\(&]U=%]B=69F M97(N<F1B=68H*3L-"@T*(" @("\O(#0N(%)E860@:6XM;65M;W)Y(&)U9F9E M<B!T;R!G:6P@:6UA9V4-"B @("!R9V)A.%]I;6%G95]T(&1S=#L-"B @("!R M96%D7VEM86=E*"!I;E]B=69F97(L(&1S="P@<&YG7W1A9R@I("D[#0H-"B @ M(" O+R U+B!7<FET92!O=70@:6UA9V4N#0H@(" @<W1R:6YG(&9I;&5N86UE M*"!P;F=?;W5T("L@(G-T<F5A;5]T97-T+G!N9R(@*3L-"B @("!O9G-T<F5A M;2!O=70H(&9I;&5N86UE+F-?<W1R*"DL(&EO<U]B87-E.CIB:6YA<GD@*3L- M"B @("!W<FET95]V:65W*"!O=70L('9I97<H(&1S=" I+"!P;F=?=&%G*"D@ M*3L-"GT-"@T*22!T;V]K('1H:7,@97AA;7!L92!F<F]M(&UY('5N:70@=&5S M=',N(%!L96%S92!H879E(&QO;VL@870@=&AI<R!N97<-"FEO(&5X=&5N<VEO M;BX@22!G;&%C960@;W9E<B!Y;W5R(&-O9&4@82!B:70@86YD(&ET(&QO;VMS M(&=O;V0N($)U="!T;PT*:&%V92!I="!I;F-L=61E9"!I;G1O(&)O;W-T('EO M=2!N965D('1O(&UA:V4@<&]R=&%B;&4@=&\@;W1H97(-"G!L871F;W)M<RX- M"@T*3&5T(&UE(&MN;W<@=VAA="!Y;W4@=&AI;FLL#0I#:')I<W1I86X-"@T* M3VX@36]N+"!-87(@,C(L(#(P,3 @870@.#HP,2!032P@1&]M86=O:B ]0S4] M03!A<FD]0S0].#<@/&1S87)I='I 9VUA:6PN8V]M/0T*/B!W<F]T93H-"CX@ M2&D@0VAR:7-T:6%N+ T*/B!)(&1O;B=T(&MN;W<@:68@>6]U(')E;65M8F5R M('1H:7,@<VAO<G0@=&AR96%D.@T*/B!H='1P.B\O;VQD+FYA8F)L92YC;VTO M+6=I;"TM;F%T:79E+6EM86=E+69O<FUA="UL;V%D97)S+7-A=F5R<RUT9#(W M,C W-#DQ/0T*+FAT;6P-"CX-"CX@+BXN(&%N>7=A>7,@22=V92!G;W0@82!F M:7)S="!D<F%F="!V97)S:6]N(')E861Y(&EF('EO=2=D(&QI:V4@=&\@=&%K M92!A(#T-"FQO;VLN+BX-"CX-"CX-"CX@22=V92!I;7!L96UE;G1E9"!T:&4@ M8F%S92!'1$DK(&)A8VME;F0@86YD+"!W:71H(&ET+"!T:&4@4$Y'($E/#0H^ M(&EN=&5R9F%C92X@06QL(&]T:&5R(&EN=&5R9F%C97,@<VAO=6QD(&)E(')E M86QL>2!T<FEV:6%L('1O(&EM<&QE;65N= T*/B!B96-A=7-E('1H97D@=VEL M;"!A;&P@=7-E('1H92!S86UE(&)A<V4@9G5N8W1I;VYA;&ET>2 H=&AE(&]N M;'D-"CX@<VEG;FEF:6-A;G0@9&EF9F5R96YC92!W:6QL('!R;V)A8FQY(&)E M(')E9V%R9&EN9R!T:&4@96YC;V1I;F<-"CX@<&%R86UE=&5R<R!F;W(@=&AE M("IW<FET92H@;65T:&]D<RXN+F%N9"!O9B!C;W5R<V4@=&AE(&1Y;F%M:6,@ M24\-"CX@=F5R<VEO;G,I+"!M;W-T;'D@82!M871T97(@;V8@9')O;F4@8V]P M>2]P87-T:6YG(&%N9"!R96YA;6EN9R!O9@T*/B!F;W)W87)D97)S+BXN#0H^ M($%L;VYG('=I=&@@=&AE(&-U<G)E;G0@:6YT97)F86-E($DG=F4@861D960@ M<W5P<&]R="!F;W(@:6XM;65M;W)Y+ T*/B!&24Q%(&%N9"!W8VAA<E]T+69I M;&4M;F%M92!S;W5R8V5S+B!4:&5R92!I<R!A;'-O(&$@=&5S="UT<GD@;V8@ M=&AE#0H^(&YE=R!'1$DK(#$N,2 H=VAI8V@@:7,@;F]T(')E9&ES=')I8G5T M86)L92!A;F0@:7,@879A:6QA8FQE(&]N;'D@=VET: T*/B!/9F9I8V4@,C P M,R!O<B!7:6YD;W=S(%9I<W1A(&%N9"!A8F]V92D@:6UA9V4@8V]N=F5R<VEO M;@T*/B!F=6YC=&EO;F%L:71Y+B!)('=A<R!U;F%B;&4@=&\@9FEN9"!S=7!P M;W)T(&9O<B!I;F1E>&5D(&EM86=E<R!I;B!'24P-"CX@<V\@22!H860@=&\@ M=&5S="!I="!T:')O=6=H("=M86YU86P@=')I8VME<GDG("AB>2!F;W)C:6YG M('1H92!C;V1E('1O#0H^(&=O('1H<F]U9V@@=&AE(&-O;G9E<G-I;VX@979E M;B!I9B!I="!W87,@;F]T(&YE8V5S<V%R>2D@86YD(&ET#0H^('-U8V-E<V9U M;&QY(&-O;G9E<G1E9"!A(#,R8FET(%!.1R!W:71H(&%L<&AA('1O(&$@,C4V M('!A;&5T=&5I>F5D#0H^(&EM86=E(&%N9"!S879E9"!I="!T;R!A(#(T8FET M(%!.1R H=VET:"!T:&4@97AP96-T960@<F5S=6QT<RDN($D@86QS;PT*/B!T M<FEE9"!T;R!A9&0@<W5P<&]R="!F;W(@<&%C:V5D7W!I>&5L('9I97=S("AT M:&%T('-E96US('1O('=O<FL@=VET: T*/B!T:&4@9&5F875L="!L:6)P;F<@ M8F%S960@:6UP;&5M96YT871I;VX@8G5T(&ET('5S97,@86X@:6YE9F9I8VEE M;G0-"CX@;65T:&]D('=I=&@@;&]T<R!O9B!C;W!Y:6YG(&%N9"!M96UO<GD@ M86QL;V-A=&EO;BD@8G5T(&9A:6QE9"XN+FET#0H^('-E96US(&EN=&5R;&5A M=F5D7W9I97=?9V5T7W)A=U]D871A*"D@9&]E<R!N;W0@<W5P<&]R="!P86-K M961?<&EX96P-"CX@=FEE=W,@*$D@9&]N)W0@=6YD97)S=&%N9"!W:'DN+BX- M"CX@)V)E=V%R92<@=&AA="!M>2!P<FEM87)Y(&-O;F-E<FX@=V%S+VES('!L M86EN+V-O<F4@:6UA9V4@24\@86YD('1H870-"CX@;7D@97AP97)I96YC92!A M;F0@:VYO=VQE9&=E(&EN("=I;6%G92!T:&5O<GDG(&ES(&YO="!D965P(&5N M;W5G:"!F;W(-"CX@<')O<&5R("='24P@8F]W96P@961I=&EN9R<@.RD-"CX@ M22=M('-U<F4@>6]U)VQL(&)E(&%B;&4@=&\@=&5L;"!R:6=H="!A=V%Y('=H M870G<R!W<F]N9R H=&AE<F4@=V5R92!A#0H^(&9E=R!M;W)E("=D96%D(&5N M9',G($D@<F5A8VAE9"P@>6]U(&-A;B!S96%R8V@@=&AR;W5G:"!T:&4@8V]D M92!F;W(-"CX@(E=H870@86)O=70N+BXB('1O(&9I;F0@=&AO<V4I+BXN#0H^ M#0H^($]N92!M;W)E(&EM<&]R=&%N="!T:&EN9R!I<R!T:&4@861D:71I;VX@ M;V8@=&AE("=M86-H:6YE<GDG(&EN#0H^(")E>'1E<FY?;&EB+FAP<"(N+BY7 M:71H(&ET($D@=')I960@=&\@861D(&UO<F4@8V]N9FEG=7)A=&EO;B!S=7!P M;W)T#0H^('-O('1H870@=7-E<G,@8V%N(&-H;V]S92!E>&%C=&QY(&AO=R!A M;F0@=VAE;B!T:&5Y('=A;G0@=&\@;&EN:R!A;F0-"CX@:6YI=&EA;&EZ92!T M:&4@97AT97)N86P@;&EB("AT:&4@<W1A='5S('%U;RP@049!24-4(&ES('1O M(&%S<W5M90T*/B!S=&%T:6,@;W(@;&]A9"!T:6UE(&QI;FMI;F<@86YD(&%U M=&]M871I8R!I;FET:6%L:7IA=&EO;B!B>2!'24P@;VX-"CX@979E<GD@05!) M(&-A;&PI+B!.;W<L(&EF('EO=2!H879E(&$@=7-E(&-A<V4@;&EK92!M:6YE M+"!W:&5R92!Y;W4@;&]A9 T*/B!A(&)U;F-H(&]F(&EM86=E<R!O;B!S=&%R M='5P("AL:6ME(&QO861I;F<@82!S:VEN*2!A;F0@:&%V92!N;R!M;W)E#0H^ M(&YE960@9F]R('1H92!I;6%G92!)3R!L:6(L('EO=2!C86X@8V]N9FEG=7)E M('1H92!L:6YK)FEN:70@;W!T:6]N<R!T;PT*/B!B92!M;W-T(&5F9FEC:65N M="!F;W(@<W5C:"!A('5S92!C87-E+BXN9F]R(&5X86UP;&4Z#0H^#0H^("-I M;F-L=61E(")B;V]S="]G:6PO97AT96YS:6]N+VEO+V5X=&5R;E]L:6(N:'!P M(@T*/B C9&5F:6YE($)/3U-47T=)3%]54T5?3D%4259%7TE/#0H^("-D969I M;F4@0D]/4U1?1TE,7T585$523D%,7TQ)0B H($)/3U-47TQ)0E],24Y+7U)5 M3E1)345?05-354U%7TQ/041%1"P-"CX@0D]/4U1?3$E"7TQ/041)3D=?4D5, M3T%$04),12P@0D]/4U1?3$E"7TE.251?05-354U%("D-"CX@(VEN8VQU9&4@ M(F)O;W-T+V=I;"]E>'1E;G-I;VXO:6\O<&YG7VEO+FAP<"(-"CX-"CX@>PT* M/B ]0S(]03 O+R!T:&ES(&=U87)D(&-L87-S(&ES(&%U=&]M871I8V%L;'D@ M:6UP;&5M96YT960@8GD@=&AE#0H^(#U#,CU!,"\O(&5X=&5R;E]L:6(@;6%C M:&EN97)Y(&%C8V]R9&EN9R!T;R!C:&]S96X@;W!T:6]N<PT*/B ]0S(]03!B M;V]S=#HZ9VEL.CIG:6Q?:6]?;&EB7V=U87)D(&-O;G-T(&EO7VQI8E]G=6%R M9#L-"CX-"CX@/4,R/4$P+R\@9&\@<V]M971H:6YG+BXN#0H^#0H^(#U#,CU! M,'1Y<&5D968@:6UA9V4\<&EX96P\8FET<S@L(&)G<E]L87EO=71?=#XL(&9A M;'-E/B!'24Q);6%G93L-"CX@/4,R/4$P1TE,26UA9V4@=&EM86=E.PT*/B ] M0S(]03!P;F=?<F5A9%]A;F1?8V]N=F5R=%]I;6%G92@@(F)O;W-T+G!N9R(L M('1I;6%G92 I.PT*/B ]0S(]03!P;F=?=W)I=&5?=FEE=R@@(F)O;W-T,BYP M;F<B+"!G:6PZ.G9I97<H('1I;6%G92 I("D[#0H^('T-"CX-"CX-"CX@07,@ M82!S=&%R=&EN9R!P;VEN="!)(&-H;W-E('1H92!'24PN24\@9G)O;2!";V]S M=" Q+C0P+"!B96-A=7-E('1H870-"CX@:7,@=&AE('9E<G-I;VX@22!S=&EL M;"!U<V4@*$%&04E#5"!N;W1H:6YG(&-H86YG960@:6X@,2XT,B!I;B!'24PN M24\I+ T*/B!A(&UO<G!H960@=&AA="XN+G-O('1H92!F:6QE<R!))VT@<V5N M9&EN9R!Y;W4@9V\@<W1R86EG:'0-"CX@*&]V97)W<FET:6YG*2!I;G1O('1H M92!G:6PO97AT96YS:6]N<R]I;R!F;VQD97(N+BX@268@:70@='5R;G,@;W5T M#0H^('1H870@=&AE('1H:6YG<R!A<F4@)VUO=FEN9R!I;B!T:&4@<FEG:'0G M(&1I<F5C=&EO;BP@=VET:"!Y;W5R(&AE;' N($D-"CX@8V%N(&UO=F4@=&\@ M=&AE(&YE=R!'24PN24\@>6]U(&UE;G1I;VYE9"XN+@T*/@T*/B!)(&AA=F5N M)W0@<G5N(&%N>2!O9F9I8VEA;"!T97-T<R H:68@>6]U(&-O=6QD('!O:6YT M(&UE('1O(&$@='5T;W)I86P-"CX@;VX@:&]W('1O(&1O('1H;W-E*2P@:G5S M="!M>2!O=VX@<&5R<V]N86P@=&5S=&EN9R H8G5T(&]F(&-O=7)S92!T:&ES M#0H^(&ES(&IU<W0@82!F:7)S="!D<F%F="!V97)S:6]N(&%N9" G=&AE(&AO M=7(@:7,@;&%T92<@<V\@8F5A<B!W:71H(&UE#0H^(#LI("XN+B!)="!C;VUP M:6QE<R!W:71H;W5T('=A<FYI;F=S(&]N($U35D,K*R Y+C @4U Q('=I=&@@ M+U<T+BXN#0H^($5X=')A(&-A<F4@=V%S(&%L<V\@=&%K96X@9F]R(&5F9FEC M:65N8WD@86YD(')E9'5C:6YG('1E;7!L871E(&)L;V%T+@T*/B!4:&5R92!A M<F4@<75I=&4@82!F97<@35-60RLK('-P96-I9FEC<R]N;VX@<W1A;F1A<F0@ M8V]N<W1R=6-T<R!T:&%T#0H^('=I;&P@8F4@8VQE86YE9"!U<"XN+@T*/@T* M/@T*/B!H;6T@=&EM92!T;R!G;R!T;R!S;&5E<"XN+F=O;V0@;6]R;FEN9R [ M*0T*/@T*/@T*/B M+0T*/B B5VAA="!(=7AL97D@=&5A8VAE<R!I<R!T:&%T M(&EN('1H92!A9V4@;V8@861V86YC960@=&5C:&YO;&]G>2P@<W!I<FET=6%L M#0H^(&1E=F%S=&%T:6]N(&ES(&UO<F4@;&EK96QY('1O(&-O;64@9G)O;2!A M;B!E;F5M>2!W:71H(&$@<VUI;&EN9R!F86-E('1H86X]#0H@9G)O;0T*/B!O M;F4@=VAO<V4@8V]U;G1E;F%N8V4@97AU9&5S('-U<W!I8VEO;B!A;F0@:&%T 692XB#0H^($YE:6P@4&]S=&UA;@T*/@`` ` end begin 666 03. Re_ [gil] native image format loaders_savers.eml M34E-12U697)S:6]N.B Q+C -"E)E8V5I=F5D.B!B>2 Q,"XR,#0N-3DN,30@ M=VET:"!(5%10.R!4=64L(#(S($UA<B R,#$P(# Y.C$Q.C$P("TP-S P("A0 M1%0I#0I);BU297!L>2U4;SH@/#DT.3@P,3,Q,3 P,S(S,#<T-W@W-C$Q.31B M<&(U93=C-S8R,&8X8SDW,&9 ;6%I;"YG;6%I;"YC;VT^#0I2969E<F5N8V5S M.B \-S8S.&4V93 Q,# S,C(Q-S Q:C9B-6%C9C$S:C)D-V,W,V(U-# Q9# Q M-#E ;6%I;"YG;6%I;"YC;VT^#0H)(#PY-#DX,#$S,3$P,#,R,S W-#=X-S8Q M,3DT8G!B-64W8S<V,C!F.&,Y-S!F0&UA:6PN9VUA:6PN8V]M/@T*1&%T93H@ M5'5E+" R,R!-87(@,C Q," Q-SHQ,3HQ," K,#$P, T*1&5L:79E<F5D+51O M.B!D<V%R:71Z0&=M86EL+F-O;0T*365S<V%G92U)1#H@/#<V,SAE-F4P,3 P M,S(S,#DQ,7(V8C$U8F0Q.')B-#)B,C0U9#$X-3 P,38W0&UA:6PN9VUA:6PN M8V]M/@T*4W5B:F5C=#H@4F4Z(%MG:6Q=(&YA=&EV92!I;6%G92!F;W)M870@ M;&]A9&5R<R]S879E<G,-"D9R;VTZ(#T_551&+3@_0C]21SET65=D=F%I1$9O M1T9Y86-32#\](#QD<V%R:71Z0&=M86EL+F-O;3X-"E1O.B!#:')I<W1I86X@ M2&5N;FEN9R \8VAH96YN:6YG0&=M86EL+F-O;3X-"D-O;G1E;G0M5'EP93H@ M=&5X="]P;&%I;CL@8VAA<G-E=#U)4T\M.#@U.2TQ#0I/;&0M6"U%<V5T260Z M($0P134W0S(W,38T,S<S,C(X0D$Y#0I8+45S97138V%N;F5R0G5I;&0Z(#8X M,3$-"D]L9"U8+45S971)9#H@1#!%-3=#,C<Q-C0S-S,R1#@R034-"E@M17-E M=$ED.B!$,$4U-T,R-S$V-#,W,S)$.#-!,0T*#0HR,#$P+S,O,C,@0VAR:7-T M:6%N($AE;FYI;F<@/&-H:&5N;FEN9T!G;6%I;"YC;VT^.@T*/B!(:2!$;VUA M9V]J+"!N:6-E('1O(&AE87(@9G)O;2!Y;W4N(%EO=2!H879E('!U="!A(&QO M="!O9B!I;F9O<FUA=&EO;@T*/B!I;B!Y;W5R(&5M86EL(&%N9"!))VT@82!B M:70@;W9E<G=H96QM960N#0H-"CHI#0I3;W)R>2!I9B!S;VUE=&AI;F<@=V%S M(&YO="!E>'!L86EN960@=V5L;"P@:70@=V%S(&QA=&4@86YD($D@=V%S#0IR M96%L;'D@=&ER960@*&9I<G-T+R=H=6=E)R G8V]M;6ET<R<@87)E('5S=6%L M;'D@;&EK92!T:&%T(#HI("XN+@T*5V]U;&0@>6]U(&QI:V4@;64@=&\@9V\@ M:6YT;R!M;W)E(&1E=&%I;"!A8F]U="!S;VUE=&AI;F<_#0H-"@T*/B!,970@ M;64@87-K('EO=2X@2&%V92!Y;W4-"CX@=&%K96X@82!L;V]K(&%T('1H92!N M97<@:6\@97AT96YS:6]N/PT*#0I.;W0@>65T+"!)('-T87)T960@=VET:"!C M=7)R96YT($=)3"Y)3R!T;R!S=&%R="!F<F]M(&$@<W1A8FQE(&)A<V4@:6X- M"F]R9&5R('1O(&=E="!T;R!F=6YC=&EO;F%L(')E<W5L=',@9F%S=&5R(&%N M9"!S;R!T:&%T(&UY#0IA9&1I=&EO;B]C:&%N9V5S(&-A;B!B92!R979I97=E M9"!I;F1E<&5N9&5N=&QY(&]F('1H92!I;U]N97<-"F-H86YG97,N+BX@5&AE M;B!L871E<B]N;W<L(&EF(&ET(&ES('-E96X@=&AA="!T:&4@<')O<&]S960@ M8V]D92!I<PT*9V]O9"!E;F]U9V@O:7,@86-T=6%L;'D@=V%N=&5D+V=O97,@ M:6X@=&AE(')I9VAT(&1I<F5C=&EO;BP@>6]U(&-A;@T*9VEV92!M92!S=FX@ M86-C97-S('-O($D@8V%N('-T87)T(&1E=F5L;W!I;F<@<')O<&5R;'D@=VET M:"!S;W5R8V4-"F-O;G1R;VP@86YD(&=R861U86QL>2!M;W)P:"!T:&4@8V]D M92!T;R!F:70@=&AE(&YE=R!I;U]N97<@9&5S:6=N(&%N9 T*:6YT97)F86-E M+BXN#0H-"@T*/B!)="!C;VUE<R!W:71H('!N9PT*#0I"=70@:70@<W1I;&P@ M<F5Q=6ER97,@=&AI<F0@<&%R='D@;&EB<RXN+FUY(&ED96$@=V%S('1O('!R M;W9I9&4@;F%T:79E#0II;6QP96UE;G1A=&EO;BAS*2]B86-K(&5N9"AS*2!F M;W(@<W5P<&]R=&5D('!L871F;W)M<R H;65A;FEN9R!T:&%T#0IT:&4@3U,@ M:6UA9V4@9G5N8W1I;VYA;&ET>2!B92!U<V5D('=H97)E(&%V86EL86)L92P@ M=&\@<')O=FED92!F;W(-"G-I;7!L97(@8G5I;&1S+"!L96%N97(@8FEN87)I M97,@86YD('!O<W-I8FQY(&%D9&ET:6]N86P@:6UA9V4@9F]R;6%T<RP-"F9O M<B!E>&%M<&QE($=$22L@<W5P<&]R=',@0DU0+"!'248L($I014<L($5X:68L M(%!.1RP@5$E&1BP@24-/3BP@5TU&+ T*14U&("DN+BX-"@T*#0H^(&%N9"!I M;E]M96UO<GD@<W5P<&]R="X-"@T*268@22!C86X@=&5L;"!C;W)R96-T;'D@ M<W1D.CIS=')E86US(&%R92!U<V5D(&9O<B!T:&%T+BXN22!H;W!E('1H870- M"FES(&]N;'D@9F]R(&%N(&5X86UP;&4O=&5S="!A;F0@;F]T(&$@<W1R:6-T M(')E<75I<F5M96YT(&]F('1H90T*9&5S:6=N+VEN=&5R9F%C92XN+F)E8V%U M<V4@<W1D.CIS=')E86US(&%R92!A8FAO<G)E;G1L>2!B;&]A=&5D(&%N9 T* M:6YE9F9I8VEE;G0@86YD(&1O(&YO="!F:70@<V\@;FEC96QY('=I=&@@86QL M('!O<W-I8FQE(&EN7VUE;6]R>0T*<V]U<F-E<RXN+GEO=2!C86X@:&%V92!A M(&9I;&4@;6%P<&5D(&EN=&\@;65M;W)Y+"!A('-T871I8R!B=69F97(@=VET M: T*82!H87)D8V]D960@:6UA9V4@;&EK92!A("=R97-O=7)C92<L(&$@5VEN M9&]W<R!R97-O=7)C92P@82!F:6QE('-I;7!L>0T*9G)E860H*2!I;G1O(&$@ M8G5F9F5R+"!A('9O:60@*B!P<F]V:61E9"!B>2!S;VUE=&AI;F<@96QS92P@ M82!P87)T:6%L#0IC:'5N:R!O9B!A;GD@;V8@=&AO<V4L(&5T8RXN+DD@=7-E M(&$@<&QA:6X-"F)O;W-T.CII=&5R871O<E]R86YG93QU;G-I9VYE9"!C:&%R M(&-O;G-T("H^('1O(&UO9&5L(&%N(&EN+6UE;6]R>0T*:6UA9V4N+BYP;&%I M;BP@969F:6-I96YT(&%N9"!S=69F:6-I96YT(&9O<B!A;GET:&EN9R!))W9E M(&-O;64@86-R;W-S#0IY970N+BX-"@T*#0H^+BXN#0H^($D@=&]O:R!T:&ES M(&5X86UP;&4@9G)O;2!M>2!U;FET('1E<W1S+@T*#0I)('=E;&-O;64@=&AE M(&-H86YG92!T;R!U<V4@=&%G<R!I;G-T96%D(&]F(&1I9F9E<F5N="!F=6YC M=&EO;B!N86UE<RX-"D5V96X@;6]R92!T:&%N('1H870L(&9R;VT@;7D@97AP M97)I96YC92!W:71H($=$22LL(&ET('=O=6QD(&)E(&5V96X-"F5A<VEE<B!A M;F0@8VQE86YE<B H86YD(&UO<F4@969F:6-I96YT*2!I9B!W96YT(&9U<G1H M97(@86YD(&-H86YG960-"F5V97)Y=&AI;F<@=&\@;V)J96-T<R]C;&%S<V5S M('=I=&@@;65M8F5R(&9U;F-T:6]N<RXN+BYT:&%T('=A>2P@87,@80T*<VEM M<&QE(&5X86UP;&4L('EO=2!W;W5L9"!N;W0@;&]A9"!A;F0@8W)E871E(&%N M(&]B:F5C="!T=VEC92P@9FER<W0-"G1O(&=E="!I=',@9&EM96YS:6]N<R!A M;F0@=&AE;B!T;R!R96%D(&ET+BXN>6]U)V0@8W)E871E(&ET(&]N8V4@86YD M#0IT:&5N(&-A;&P@:71S(&UE;6)E<B!F=6YC=&EO;G,@=6YT:6P@>6]U)W)E M(&1O;F4@=VET:"!I="XN+@T*#0H-"CX@22!G;&%C960@;W9E<B!Y;W5R(&-O M9&4@82!B:70@86YD(&ET(&QO;VMS(&=O;V0N($)U="!T;PT*/B!H879E(&ET M(&EN8VQU9&5D(&EN=&\@8F]O<W0@>6]U(&YE960@=&\@;6%K92!P;W)T86)L M92!T;R!O=&AE<@T*/B!P;&%T9F]R;7,N#0H-"D)U="!T:&4@=F5R>2!I9&5A M(&]F(")N871I=F4B(&EM86=E(&QO861I;F<@:7,@;F]T('!O<G1A8FQE+BXN M=&AE(&ED96$-"FES('1O(&EM<&QE;65N="!N871I=F4@8F%C:V5N9',@=VAI M8V@@=&AE('5S97(@8V%N(&-H;V]S92!T;R!U<V4@8GDL#0IA<R!I;B!M>2!E M>&%M<&QE+"!D969I;FEN9R!"3T]35%]'24Q?55-%7TY!5$E615])3RXN+F%N M9"!I9B!F;W(@80T*<&%R=&EC=6QA<B!P;&%T9F]R;2!T:&5R92!I<R!N;R!N M871I=F4@8F%C:V5N9"!Y970L('1H92!D969A=6QT(&QI8BH-"F)A<V5D(&)A M8VME;F0O:6UP;&5M96YT871I;VX@=VEL;"!B92!U<V5D+BXN82!R871H97(@ M<W1A;F1A<F0-"F%P<')O86-H+BXN#0H-"DEN(&$@9F5W(&UO;G1H<R!)(&5X M<&5C="!T;R!S=&%R="!D979E;&]P:6YG(&9O<B!-86,@3U-8('-O('1H96X@ M22=D#0IW;W)K(&]N(&$@0V]R94=R87!H:6-S(&)A8VME;F0@86QS;RXN+@T* M#0H-"DD@:&]P92!)(&UA9&4@=&AI;F=S(&$@;&ET=&QE(&-L96%R97(@.RD- M"@T*#0H-"BTM#0HB5VAA="!(=7AL97D@=&5A8VAE<R!I<R!T:&%T(&EN('1H M92!A9V4@;V8@861V86YC960@=&5C:&YO;&]G>2P@<W!I<FET=6%L#0ID979A M<W1A=&EO;B!I<R!M;W)E(&QI:V5L>2!T;R!C;VUE(&9R;VT@86X@96YE;7D@ M=VET:"!A('-M:6QI;F<@9F%C92!T:&%N(&9R;VT-"F]N92!W:&]S92!C;W5N M=&5N86YC92!E>'5D97,@<W5S<&EC:6]N(&%N9"!H871E+B(-"DYE:6P@4&]S $=&UA;@`` ` end begin 666 04. Re_ [gil] native image format loaders_savers.eml M1&5L:79E<F5D+51O.B!D<V%R:71Z0&=M86EL+F-O;0T*4F5C96EV960Z(&)Y M(#$P+C(P-"XU.2XQ-"!W:71H(%--5% @:60@:C$T8W,S,38R,C-B:V@[#0H@ M(" @(" @(%=E9"P@,C0@36%R(#(P,3 @,#@Z,30Z-#<@+3 W,# @*%!$5"D- M"E)E='5R;BU0871H.B \8VAH96YN:6YG0&=M86EL+F-O;3X-"E)E8V5I=F5D M+5-01CH@<&%S<R H9V]O9VQE+F-O;3H@9&]M86EN(&]F(&-H:&5N;FEN9T!G M;6%I;"YC;VT@9&5S:6=N871E<R Q,"XR,SDN,3@X+C$S.2!A<R!P97)M:71T M960@<V5N9&5R*2!C;&EE;G0M:7 ],3 N,C,Y+C$X."XQ,SD[#0I!=71H96YT M:6-A=&EO;BU297-U;'1S.B!M<BYG;V]G;&4N8V]M.R!S<&8]<&%S<R H9V]O M9VQE+F-O;3H@9&]M86EN(&]F(&-H:&5N;FEN9T!G;6%I;"YC;VT@9&5S:6=N M871E<R Q,"XR,SDN,3@X+C$S.2!A<R!P97)M:71T960@<V5N9&5R*2!S;71P M+FUA:6P]8VAH96YN:6YG0&=M86EL+F-O;3L@9&MI;3UP87-S(&AE861E<BYI M/6-H:&5N;FEN9T!G;6%I;"YC;VT-"E)E8V5I=F5D.B!F<F]M(&UR+F=O;V=L M92YC;VT@*%LQ,"XR,SDN,3@X+C$S.5TI#0H@(" @(" @(&)Y(#$P+C(S.2XQ M.#@N,3,Y('=I=&@@4TU44"!I9"!P,3%M<C<V,SDP-FAB:"XQ,#(N,3(V.30T M,S8X-C(V." H;G5M7VAO<',@/2 Q*3L-"B @(" @(" @5V5D+" R-"!-87(@ M,C Q," P.#HQ-#HT-B M,#<P," H4$14*0T*1$M)32U3:6=N871U<F4Z('8] M,3L@83UR<V$M<VAA,C4V.R!C/7)E;&%X960O<F5L87AE9#L-"B @(" @(" @ M9#UG;6%I;"YC;VT[(',]9V%M;6$[#0H@(" @(" @(&@]9&]M86EN:V5Y+7-I M9VYA='5R93IM:6UE+79E<G-I;VXZ<F5C96EV960Z:6XM<F5P;'DM=&\Z<F5F M97)E;F-E<PT*(" @(" @(" @.F1A=&4Z;65S<V%G92UI9#IS=6)J96-T.F9R M;VTZ=&\Z8V]N=&5N="UT>7!E.PT*(" @(" @("!B:#UF,&=/3B]84WDU9G4R M,D)!5W%73&Q'3D=N0EAY-6MW.%9Y;F<Y9T%*<T)W/3L-"B @(" @(" @8CUL M-T<P*W%F2G8Y=G1Y;VUE;7=O67HW.3518E)02G!W06]5=45A.%AJ;%<W5D52 M;&AL>%AT9D(W.#=14'IW>D<V86D-"B @(" @(" @(&IV2#%:55=M569$=4Y* M5C0Q;F5P>79.<T(S96=.:6=12C@O>$YP9$YP>DLQ,VII8CEV1D0T<&QM4&AD M3$,K=6I53$IG#0H@(" @(" @("!03UEN:'9(:3E'3FMA.'="2'9M555.:U8O M2E!63TIM1W%8:'(P/0T*1&]M86EN2V5Y+5-I9VYA='5R93H@83UR<V$M<VAA M,3L@8SUN;V9W<SL-"B @(" @(" @9#UG;6%I;"YC;VT[(',]9V%M;6$[#0H@ M(" @(" @(&@];6EM92UV97)S:6]N.FEN+7)E<&QY+71O.G)E9F5R96YC97,Z M9&%T93IM97-S86=E+6ED.G-U8FIE8W0Z9G)O;3IT;PT*(" @(" @(" @.F-O M;G1E;G0M='EP93L-"B @(" @(" @8CUK*U<X:&)):TAT86,V8FU#0F0V;#)R M.$9M.&XQ,%A2>59X:FUS+S9P*T%C>45Q:'0V4'A';FQ83E!V3D5,2%5F,V\- M"B @(" @(" @(%!,;GI(57=R;#8X155O2&Q!4&0R,#A%<$9C5DU2;6)#5D-5 M<VXT:5A4=G-B:T]U,UIE5#(Q;W%99%)T;2MQ8D-P,VIV#0H@(" @(" @("!1 M2F9$6E)V:5%22#9X,E!24U5E1C9A4EED<3=53SE(6&E2:45W/0T*34E-12U6 M97)S:6]N.B Q+C -"E)E8V5I=F5D.B!B>2 Q,"XR,SDN,3@X+C$S.2!W:71H M(%--5% @:60@<#$Q;7(W-C,Y,#9H8F@N,3 R+C$R-CDT-#,V.#8R-C [( T* M"5=E9"P@,C0@36%R(#(P,3 @,#@Z,30Z-#8@+3 W,# @*%!$5"D-"DEN+5)E M<&QY+51O.B \-S8S.&4V93 Q,# S,C,P.3$Q<C9B,35B9#$X<F(T,F(R-#5D M,3@U,# Q-C= ;6%I;"YG;6%I;"YC;VT^#0I2969E<F5N8V5S.B \-S8S.&4V M93 Q,# S,C(Q-S Q:C9B-6%C9C$S:C)D-V,W,V(U-# Q9# Q-#E ;6%I;"YG M;6%I;"YC;VT^#0H)(#PY-#DX,#$S,3$P,#,R,S W-#=X-S8Q,3DT8G!B-64W M8S<V,C!F.&,Y-S!F0&UA:6PN9VUA:6PN8V]M/@T*"2 \-S8S.&4V93 Q,# S M,C,P.3$Q<C9B,35B9#$X<F(T,F(R-#5D,3@U,# Q-C= ;6%I;"YG;6%I;"YC M;VT^#0I$871E.B!7960L(#(T($UA<B R,#$P(#$Q.C$T.C0V("TP-# P#0I- M97-S86=E+4E$.B \.30Y.# Q,S$Q,# S,C0P.#$T=C9E8SEB.39Y-S8Y93,U M9C1F.&5D9F,V8T!M86EL+F=M86EL+F-O;3X-"E-U8FIE8W0Z(%)E.B!;9VEL M72!N871I=F4@:6UA9V4@9F]R;6%T(&QO861E<G,O<V%V97)S#0I&<F]M.B!# M:')I<W1I86X@2&5N;FEN9R \8VAH96YN:6YG0&=M86EL+F-O;3X-"E1O.B ] M/U541BTX/T(_4D<Y=%E79'9A:41&;T=&>6%C4T@_/2 \9'-A<FET>D!G;6%I M;"YC;VT^#0I#;VYT96YT+51Y<&4Z('1E>'0O<&QA:6X[(&-H87)S970]25-/ M+3@X-3DM,0T*6"U%<V5T260Z($0P134W0S(W,38T,S<S,D0X,T$Q#0I8+45S M97138V%N;F5R0G5I;&0Z(#8X,3$-"@T*2&D@1&]M86=O:BP-"@T*/CX@270@ M8V]M97,@=VET:"!P;F<-"CX-"CX@0G5T(&ET('-T:6QL(')E<75I<F5S('1H M:7)D('!A<G1Y(&QI8G,N+BYM>2!I9&5A('=A<R!T;R!P<F]V:61E(&YA=&EV M90T*/B!I;6QP96UE;G1A=&EO;BAS*2]B86-K(&5N9"AS*2!F;W(@<W5P<&]R M=&5D('!L871F;W)M<R H;65A;FEN9R!T:&%T#0H^('1H92!/4R!I;6%G92!F M=6YC=&EO;F%L:71Y(&)E('5S960@=VAE<F4@879A:6QA8FQE+"!T;R!P<F]V M:61E(&9O<@T*/B!S:6UP;&5R(&)U:6QD<RP@;&5A;F5R(&)I;F%R:65S(&%N M9"!P;W-S:6)L>2!A9&1I=&EO;F%L(&EM86=E(&9O<FUA=',L#0H^(&9O<B!E M>&%M<&QE($=$22L@<W5P<&]R=',@0DU0+"!'248L($I014<L($5X:68L(%!. M1RP@5$E&1BP@24-/3BP@5TU&+ T*/B!%348@*2XN+@T*#0I4:&ES('=O=6QD M(&)E(&]N;'D@=FEA8FQE(&EF('EO=2!C86X@96YS=7)E('1H870@>6]U)VQL M(&-O=F5R(&%L; T*9F5A='5R97,@;V8@<&YG+B!.;W1H:6YG(&QE<W,@:7,@ M<&]S<VEB;&4N($EF('EO=2!T:&EN:R!Y;W4@:&%V92!T:&%T#0IH;W<@:&%R M9"!T;R!Y;W4@=&AI;FL@=V]U;&0@:70@8F4@861D(&ET('1O(&UY(&5X=&5N M<VEO;C\@66]U(&-O=6QD#0IF;W(@:6YS=&%N8V4@861D(&$@;F5W(&9O<FUA M="!C86QL960@(G!N9U]N871I=F4B(&%N9"!S=&%R="!A9&1I;F<-"GEO=7(@ M<V]U<F-E(&-O9&4N#0H-"CX-"CX-"CX^(&%N9"!I;E]M96UO<GD@<W5P<&]R M="X-"CX-"CX@268@22!C86X@=&5L;"!C;W)R96-T;'D@<W1D.CIS=')E86US M(&%R92!U<V5D(&9O<B!T:&%T+BXN22!H;W!E('1H870-"CX@:7,@;VYL>2!F M;W(@86X@97AA;7!L92]T97-T(&%N9"!N;W0@82!S=')I8W0@<F5Q=6ER96UE M;G0@;V8@=&AE#0H^(&1E<VEG;B]I;G1E<F9A8V4N+BYB96-A=7-E('-T9#HZ M<W1R96%M<R!A<F4@86)H;W)R96YT;'D@8FQO871E9"!A;F0-"CX@:6YE9F9I M8VEE;G0@86YD(&1O(&YO="!F:70@<V\@;FEC96QY('=I=&@@86QL('!O<W-I M8FQE(&EN7VUE;6]R>0T*/B!S;W5R8V5S+BXN>6]U(&-A;B!H879E(&$@9FEL M92!M87!P960@:6YT;R!M96UO<GDL(&$@<W1A=&EC(&)U9F9E<B!W:71H#0H^ M(&$@:&%R9&-O9&5D(&EM86=E(&QI:V4@82 G<F5S;W5R8V4G+"!A(%=I;F1O M=W,@<F5S;W5R8V4L(&$@9FEL92!S:6UP;'D-"CX@9G)E860H*2!I;G1O(&$@ M8G5F9F5R+"!A('9O:60@*B!P<F]V:61E9"!B>2!S;VUE=&AI;F<@96QS92P@ M82!P87)T:6%L#0H^(&-H=6YK(&]F(&%N>2!O9B!T:&]S92P@971C+BXN22!U M<V4@82!P;&%I;@T*/B!B;V]S=#HZ:71E<F%T;W)?<F%N9V4\=6YS:6=N960@ M8VAA<B!C;VYS=" J/B!T;R!M;V1E;"!A;B!I;BUM96UO<GD-"CX@:6UA9V4N M+BYP;&%I;BP@969F:6-I96YT(&%N9"!S=69F:6-I96YT(&9O<B!A;GET:&EN M9R!))W9E(&-O;64@86-R;W-S#0H^('EE="XN+@T*#0I9;W4@8V]U;&0@=7-E M('=H871E=F5R(&)U9F9E<B!Y;W4@=V%N="!"550@>6]U(&AA=F4@=&\@;6%K M92!S=7)E(&ET)W,-"F1E<FEV960@9G)O;2!S=&0Z.FES=')E86T@86YD+V]R M('-T9#HZ;W-T<F5A;2X@2&%V92!A(&QO;VL@870-"FEO7V1E=FEC92YH<' N M#0H-"CX-"CX-"CX^+BXN#0H^/B!)('1O;VL@=&AI<R!E>&%M<&QE(&9R;VT@ M;7D@=6YI="!T97-T<RX-"CX-"CX@22!W96QC;VUE('1H92!C:&%N9V4@=&\@ M=7-E('1A9W,@:6YS=&5A9"!O9B!D:69F97)E;G0@9G5N8W1I;VX@;F%M97,N M#0H^($5V96X@;6]R92!T:&%N('1H870L(&9R;VT@;7D@97AP97)I96YC92!W M:71H($=$22LL(&ET('=O=6QD(&)E(&5V96X-"CX@96%S:65R(&%N9"!C;&5A M;F5R("AA;F0@;6]R92!E9F9I8VEE;G0I(&EF('=E;G0@9G5R=&AE<B!A;F0@ M8VAA;F=E9 T*/B!E=F5R>71H:6YG('1O(&]B:F5C=',O8VQA<W-E<R!W:71H M(&UE;6)E<B!F=6YC=&EO;G,N+BXN=&AA="!W87DL(&%S(&$-"CX@<VEM<&QE M(&5X86UP;&4L('EO=2!W;W5L9"!N;W0@;&]A9"!A;F0@8W)E871E(&%N(&]B M:F5C="!T=VEC92P@9FER<W0-"CX@=&\@9V5T(&ET<R!D:6UE;G-I;VYS(&%N M9"!T:&5N('1O(')E860@:70N+BYY;W4G9"!C<F5A=&4@:70@;VYC92!A;F0- M"CX@=&AE;B!C86QL(&ET<R!M96UB97(@9G5N8W1I;VYS('5N=&EL('EO=2=R M92!D;VYE('=I=&@@:70N+BX-"@T*5&AE(&=O86P@:7,@<')O=FED92!A;B!U M;FEF:65D(&EN=&5R9F%C92!T:&%T(&%L;"!F;W)M870@<VAA<F4N#0I5;F1E M<FYE871H('1H870@:6YT97)F86-E('=E(&%R92!B86-K('1O(&-L87-S97,N M#0H-"D)45RP@>6]U(&1O;B=T(&YE960@=&\@<F5A9"!T:&4@9&EM96YS:6]N M<R!F:7)S="!A;F0@=&AE;B!R96%D('1H90T*9&%T82X@5&AA="!W:&%T(')E M861?:6UA9V4H("XN("D@:7,@9F]R+B!)="!W:6QL('1A:V4@8V%R92!O9@T* M86QL;V-A=&EN9R!M96UO<GD@86YD(')E861I;F<@=&AE(&1A=&$N#0H-"CX^ M($D@9VQA8V5D(&]V97(@>6]U<B!C;V1E(&$@8FET(&%N9"!I="!L;V]K<R!G M;V]D+B!"=70@=&\-"CX^(&AA=F4@:70@:6YC;'5D960@:6YT;R!B;V]S="!Y M;W4@;F5E9"!T;R!M86ME('!O<G1A8FQE('1O(&]T:&5R#0H^/B!P;&%T9F]R M;7,N#0H^#0H^($)U="!T:&4@=F5R>2!I9&5A(&]F(")N871I=F4B(&EM86=E M(&QO861I;F<@:7,@;F]T('!O<G1A8FQE+BXN=&AE(&ED96$-"CX@:7,@=&\@ M:6UP;&5M96YT(&YA=&EV92!B86-K96YD<R!W:&EC:"!T:&4@=7-E<B!C86X@ M8VAO;W-E('1O('5S92!B>2P-"CX@87,@:6X@;7D@97AA;7!L92P@9&5F:6YI M;F<@0D]/4U1?1TE,7U5315].051)5D5?24\N+BYA;F0@:68@9F]R(&$-"CX@ M<&%R=&EC=6QA<B!P;&%T9F]R;2!T:&5R92!I<R!N;R!N871I=F4@8F%C:V5N M9"!Y970L('1H92!D969A=6QT(&QI8BH-"CX@8F%S960@8F%C:V5N9"]I;7!L M96UE;G1A=&EO;B!W:6QL(&)E('5S960N+BYA(')A=&AE<B!S=&%N9&%R9 T* M/B!A<'!R;V%C:"XN+@T*#0I);G-T96%D(&]F('5S:6YG(&$@8V]M<&EL97(@ M<WEM8F]L($D@=V]U;&0@<W5G9V5S="!A(&YE=R!F;W)M870@='EP90T*;&EK M92 B<&YG7VYA=&EV92(N#0H-"CX@22!H;W!E($D@;6%D92!T:&EN9W,@82!L M:71T;&4@8VQE87)E<B [*0T*#0I997,L('EO=2!D:60N(%1H86YK<R!F;W(@ A>6]U<B!W;W)K(0T*#0I296=A<F1S+ T*0VAR:7-T:6%N ` end

"Domagoj Saric" <dsaritz@gmail.com> wrote in message news:hof9fl$1qj$1@dough.gmane.org...
----------------------- ps. Just about parallel to this discussion I finished a first version of my 'native GIL IO implementation' and sent it to Christian for comments/inspection. Now we've decided that it would perhaps be better to make our discussion public on boost.devel considering there is an ongoing related discussion. I've attached the few emails already exchanged and below you can find my response to Christian's latest mail. Anyways I would be glad if others would be interested to look at/comment/test my proposed code (if by some chance it, in its current unfinished/limited form, applies to their platform and needs)...
I appologize for the trash in the previous post, it seems OE trampled on itself...I'm resending the attachments (code with the discussion) zipped... -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

"Domagoj Saric" <dsaritz@gmail.com> wrote in message news:hofacd$4tu$1@dough.gmane.org...
"Domagoj Saric" <dsaritz@gmail.com> wrote in message news:hof9fl$1qj$1@dough.gmane.org... I appologize for the trash in the previous post, it seems OE trampled on itself...I'm resending the attachments (code with the discussion) zipped...
I forgot, boost.devel (server) somehow filters any zip (or rar or tgz for that matter) I try to attach... Here it is, then, in the vault: http://www.boostpro.com/vault/index.php?&direction=0&order=&directory=Graphical -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman
participants (8)
-
Christian Henning
-
Domagoj Saric
-
Felipe Magno de Almeida
-
John Bytheway
-
Mariusz Kwiczala
-
Mateusz Loskot
-
Phil Endecott
-
Tom Brinkman