├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── app
└── uti_exporter.app
│ └── Contents
│ ├── Info.plist
│ ├── MacOS
│ └── Application Stub
│ ├── Resources
│ └── English.lproj
│ │ └── ApplicationStub.nib
│ └── document.wflow
├── common
├── bpg_decode.h
├── bpg_decode.m
├── netpbm_decode.h
├── netpbm_decode.m
├── tools.h
├── tools.m
├── webp_decode.h
└── webp_decode.m
├── deps
├── libbpg
│ ├── libbpg.a
│ └── libbpg.h
└── libwebp
│ ├── decode.h
│ ├── demux.h
│ ├── encode.h
│ ├── format_constants.h
│ ├── libwebp.a
│ ├── mux.h
│ ├── mux_types.h
│ └── types.h
├── images-samples.txz
├── mdimporter
├── rsrc
│ └── Info.plist
└── src
│ ├── GetMetadataForFile.m
│ └── main.c
├── qlImageSize.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
│ └── xcuserdata
│ │ └── nyxouf.xcuserdatad
│ │ └── WorkspaceSettings.xcsettings
└── xcuserdata
│ ├── benjamin.xcuserdatad
│ └── xcschemes
│ │ ├── mdImageSize.xcscheme
│ │ ├── qlImageSize.xcscheme
│ │ └── xcschememanagement.plist
│ └── nyxouf.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints.xcbkptlist
│ └── xcschemes
│ ├── mdImageSize.xcscheme
│ ├── qlImageSize.xcscheme
│ └── xcschememanagement.plist
└── qlgenerator
├── rsrc
└── Info.plist
└── src
├── GeneratePreviewForURL.m
├── GenerateThumbnailForURL.m
└── main.m
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xccheckout
23 | *.xcscmblueprint
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 | *.ipa
28 | *.dSYM.zip
29 | *.dSYM
30 |
31 | # CocoaPods
32 | #
33 | # We recommend against adding the Pods directory to your .gitignore. However
34 | # you should judge for yourself, the pros and cons are mentioned at:
35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
36 | #
37 | # Pods/
38 |
39 | # Carthage
40 | #
41 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
42 | # Carthage/Checkouts
43 |
44 | Carthage/Build
45 |
46 | # fastlane
47 | #
48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
49 | # screenshots whenever they are needed.
50 | # For more information about the recommended setup visit:
51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
52 |
53 | fastlane/report.xml
54 | fastlane/Preview.html
55 | fastlane/screenshots
56 | fastlane/test_output
57 |
58 | # Code Injection
59 | #
60 | # After new code Injection tools there's a generated folder /iOSInjectionProject
61 | # https://github.com/johnno1962/injectionforxcode
62 |
63 | iOSInjectionProject/
64 |
65 | mdimporter/.DS_Store
66 |
67 | qlgenerator/.DS_Store
68 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | script:
3 | - xcodebuild -project qlImageSize.xcodeproj -target qlImageSize -target mdImageSize
4 | - mv build/Release/qlImageSize.qlgenerator .
5 | - mv build/Release/mdImageSize.mdimporter .
6 | - zip -r qlImageSize.qlgenerator.zip qlImageSize.qlgenerator
7 | - zip -r mdImageSize.mdimporter.zip mdImageSize.mdimporter
8 | deploy:
9 | provider: releases
10 | api_key:
11 | secure: "M2Y26YDsPqMt5MERoMHIVojR/lwp6dnvnKbqg37nT+74InQ/SNpxDbYg0weOdPm/ostV4a7YYGoTwlE5VrA3VOIPwVWUC5jcGB3H7VwENO1brBXUEM2DI6X/2Kr0bRzcL6Qnoqw8i8hD892bbsVyqE1teEpaTOuGUXXRE3lnB4EdfLVb4Jbl1k96rQGpUPpXr2d2OpusFeK0no2ysjdW50dR39yrwEqca9uKhRk3FwacbYahnujGnzWW/sMvnoh75n32ZWFdgiGTRoetJ2zHdh158wAWrWgLkBlr0WnqQDkQBoVeZ1K+iZtoXkpcuqdGa8mGABl1pEQTsVMlyriG6bZ67BLvJIzMZhwD2jgKoWpQSRiu42UnmKR9zBG5zUfpmOvVw79QKl5DBRt6hwQI+mKvDwHv68Q9pC3/eMKKCbmxU0tsXOyR3mDQzB1Nr2b4KJVyj/vRe1YhTORzTXIxL/cJz3mUdG3WYHFdBmFNLIutsnl4Xm/qDS0nxL0H6HcYGNddHkcMGfkIJYo5gZozyo6GeF9hu0EEUZ4DvG6gGl0KeW1DGA9ASDyrcHvmkiuiM8xtmMND9NCbH1kLWvgrqJpTUG48w1UWC+M4YL/MLK1NNdogSNiPs+07aHF8m9mPLYwGf4Aag9971D1oWaiiYvoQGLZDnUepD3791i/ow0E="
12 | file:
13 | - qlImageSize.qlgenerator.zip
14 | - mdImageSize.mdimporter.zip
15 | skip_cleanup: true
16 | on:
17 | tags: true
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018 Nyx0uf
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # This project is not maintained anymore, it has been killed by macOS 10.15, see issues for details.
2 |
3 |  [](https://travis-ci.com/Nyx0uf/qlImageSize)
4 |
5 | This project is composed of both a **QuickLook** plugin and a **Spotlight** plugin. Both are independant and can be built separately.
6 | They require at least *macOS High Sierra (10.13)*.
7 |
8 | # qlImageSize
9 |
10 | This is the **QuickLook** plugin, it displays the dimensions, DPI and file size of an image in the title bar.
11 |
12 | 
13 |
14 | This plugin can also preview and generate *Finder* thumbnails for natively unsupported images formats [bpg](http://bellard.org/bpg/ "bpg") and [WebP](https://developers.google.com/speed/webp/ "WebP").
15 |
16 | 
17 |
18 | 
19 |
20 |
21 | # mdImageSize
22 |
23 | This is the **Spotlight** plugin, it displays informations of unsupported images (**WebP**, **bpg**) in the Finder's inspector window.
24 |
25 | 
26 |
27 |
28 | # Install
29 |
30 | 3 choices :
31 |
32 | 1. Using [Homebrew Cask](https://brew.sh/):
33 | ```
34 | brew install --cask qlimagesize mdimagesizemdimporter
35 | ```
36 | 2. Download the latest build from https://github.com/Nyx0uf/qlImageSize/releases/latest and save it to your `~/Library/QuickLook` and/or `~/Library/Spotlight` folder.
37 | 3. Build from sources using Xcode. (just have to hit the build button).
38 |
39 |
40 | # Uninstall
41 |
42 | 2 choices :
43 |
44 | 1. Using [Homebrew Cask](https://brew.sh/):
45 | ```
46 | brew uninstall --cask qlimagesize mdimagesizemdimporter
47 | ```
48 | 2. Manually :
49 | - Launch *Terminal.app* in `/Applications/Utilities`
50 | - Copy and paste the following line:
51 | ```
52 | rm -rf ~/Library/QuickLook/qlImageSize.qlgenerator ~/Library/Spotlight/mdImageSize.mdimporter
53 | ```
54 | - Press Enter.
55 |
56 |
57 | # Limitations
58 |
59 | If you are a **Pixelmator** user, its own QuickLook plugin might get in the way when previewing **WebP** files. To fix this you need to edit the file `/Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator/Contents/Info.plist` and remove the dict entry that handles **webp**.
60 |
61 | After editing the `Info.plist`, QuickLook for the Pixelmator file format (such as `.pxm`) might not work due to Code Signing. You can unsign Pixelmator's QuickLook binary using the tool [unsign](https://github.com/steakknife/unsign). After downloading and building it, just run :
62 |
63 | unsign /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator/Contents/MacOS/PixelmatorLook`.
64 |
65 | It will create another binary with the extension **unsigned**, rename the orignal binary for backup then remove the extension for the unsigned binary, ex :
66 |
67 | mv /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator/Contents/MacOS/PixelmatorLook /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator/Contents/MacOS/PixelmatorLook.bak
68 | mv /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator/Contents/MacOS/PixelmatorLook.unsigned /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator/Contents/MacOS/PixelmatorLook
69 |
70 |
71 | # Upgrading dependencies
72 |
73 | ### libwbep
74 |
75 | Grab the [latest version](https://github.com/webmproject/libwebp/releases). Decompress the archive and simply run :
76 |
77 | ./autogen.sh
78 | CFLAGS="-mmacosx-version-min=10.13" ./configure --disable-shared
79 | make
80 |
81 | The resulting library can be found in *src/.libs/libwebp.a*.
82 |
83 | ### libbpg
84 |
85 | Grab the [latest version](https://bellard.org/bpg/). Decompress the archive and edit the `Makefile` with the following changes :
86 |
87 | - Uncomment the line which reads `CONFIG_APPLE=y`
88 | - Comment both lines `USE_X265=y` and `USE_BPGVIEW=y`
89 |
90 | And replace the following
91 |
92 | ifdef CONFIG_APPLE
93 | LDFLAGS+=-Wl,-dead_strip
94 |
95 | with
96 |
97 | ifdef CONFIG_APPLE
98 | LDFLAGS+=-Wl,-dead_strip
99 | CFLAGS+=-mmacosx-version-min=10.13
100 |
101 | Then simply run `make`. The resulting library will be in the project directory.
102 |
103 | # License
104 |
105 | This project is released under the *MIT license*, see **LICENSE**.
106 |
--------------------------------------------------------------------------------
/app/uti_exporter.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMIsApplet
6 |
7 | AMStayOpen
8 |
9 | BuildMachineOSBuild
10 | 13A563a
11 | CFBundleDevelopmentRegion
12 | English
13 | CFBundleDocumentTypes
14 |
15 |
16 | CFBundleTypeExtensions
17 |
18 | *
19 |
20 | CFBundleTypeName
21 | Automator workflow file
22 | CFBundleTypeOSTypes
23 |
24 | ****
25 |
26 | CFBundleTypeRole
27 | Viewer
28 |
29 |
30 | CFBundleExecutable
31 | Application Stub
32 | CFBundleIconFile
33 | AutomatorApplet
34 | CFBundleIdentifier
35 | com.apple.automator.uti_exporter
36 | CFBundleInfoDictionaryVersion
37 | 6.0
38 | CFBundleName
39 | uti_exporter
40 | CFBundlePackageType
41 | APPL
42 | CFBundleShortVersionString
43 | 1.2
44 | CFBundleSignature
45 | ????
46 | CFBundleURLTypes
47 |
48 | CFBundleVersion
49 | 381
50 | DTCompiler
51 | com.apple.compilers.llvm.clang.1_0
52 | DTPlatformBuild
53 | 5A11344p
54 | DTPlatformVersion
55 | GM
56 | DTSDKBuild
57 | 13A563a
58 | DTSDKName
59 |
60 | DTXcode
61 | 0500
62 | DTXcodeBuild
63 | 5A11344p
64 | LSMinimumSystemVersion
65 | 10.5
66 | LSMinimumSystemVersionByArchitecture
67 |
68 | x86_64
69 | 10.6
70 |
71 | LSUIElement
72 |
73 | NSAppleScriptEnabled
74 | YES
75 | NSMainNibFile
76 | ApplicationStub
77 | NSPrincipalClass
78 | NSApplication
79 | NSServices
80 |
81 | UTExportedTypeDeclarations
82 |
83 |
84 | UTTypeConformsTo
85 |
86 | public.image
87 |
88 | UTTypeDescription
89 | Netpbm bi-level image format
90 | UTTypeIdentifier
91 | fr.whine.pbm
92 | UTTypeReferenceURL
93 | http://netpbm.sourceforge.net/doc/pbm.html
94 | UTTypeTagSpecification
95 |
96 | public.filename-extension
97 |
98 | pbm
99 | PBM
100 |
101 |
102 |
103 |
104 | UTTypeConformsTo
105 |
106 | public.image
107 |
108 | UTTypeDescription
109 | Netpbm grayscale image format
110 | UTTypeIdentifier
111 | fr.whine.pgm
112 | UTTypeReferenceURL
113 | http://netpbm.sourceforge.net/doc/pgm.html
114 | UTTypeTagSpecification
115 |
116 | public.filename-extension
117 |
118 | pgm
119 | PGM
120 |
121 |
122 |
123 |
124 | UTTypeConformsTo
125 |
126 | public.image
127 |
128 | UTTypeDescription
129 | Netpbm color image format
130 | UTTypeIdentifier
131 | fr.whine.ppm
132 | UTTypeReferenceURL
133 | http://netpbm.sourceforge.net/doc/ppm.html
134 | UTTypeTagSpecification
135 |
136 | public.filename-extension
137 |
138 | ppm
139 | PPM
140 |
141 |
142 |
143 |
144 | UTTypeConformsTo
145 |
146 | public.image
147 |
148 | UTTypeDescription
149 | BPG
150 | UTTypeIdentifier
151 | fr.whine.bpg
152 | UTTypeReferenceURL
153 | http://bellard.org/bpg/
154 | UTTypeTagSpecification
155 |
156 | public.filename-extension
157 |
158 | bpg
159 | BPG
160 |
161 |
162 |
163 |
164 | UTTypeConformsTo
165 |
166 | public.image
167 |
168 | UTTypeDescription
169 | WebP
170 | UTTypeIdentifier
171 | fr.whine.webp
172 | UTTypeReferenceURL
173 | https://developers.google.com/speed/webp/docs/riff_container
174 | UTTypeTagSpecification
175 |
176 | public.filename-extension
177 |
178 | webp
179 | WEBP
180 |
181 |
182 |
183 |
184 | UTImportedTypeDeclarations
185 |
186 |
187 | UTTypeConformsTo
188 |
189 | public.image
190 |
191 | UTTypeDescription
192 | Netpbm bi-level image format
193 | UTTypeIdentifier
194 | fr.whine.pbm
195 | UTTypeReferenceURL
196 | http://netpbm.sourceforge.net/doc/pbm.html
197 | UTTypeTagSpecification
198 |
199 | public.filename-extension
200 |
201 | pbm
202 | PBM
203 |
204 |
205 |
206 |
207 | UTTypeConformsTo
208 |
209 | public.image
210 |
211 | UTTypeDescription
212 | Netpbm grayscale image format
213 | UTTypeIdentifier
214 | fr.whine.pgm
215 | UTTypeReferenceURL
216 | http://netpbm.sourceforge.net/doc/pgm.html
217 | UTTypeTagSpecification
218 |
219 | public.filename-extension
220 |
221 | pgm
222 | PGM
223 |
224 |
225 |
226 |
227 | UTTypeConformsTo
228 |
229 | public.image
230 |
231 | UTTypeDescription
232 | Netpbm color image format
233 | UTTypeIdentifier
234 | fr.whine.ppm
235 | UTTypeReferenceURL
236 | http://netpbm.sourceforge.net/doc/ppm.html
237 | UTTypeTagSpecification
238 |
239 | public.filename-extension
240 |
241 | ppm
242 | PPM
243 |
244 |
245 |
246 |
247 | UTTypeConformsTo
248 |
249 | public.image
250 |
251 | UTTypeDescription
252 | BPG
253 | UTTypeIdentifier
254 | fr.whine.bpg
255 | UTTypeReferenceURL
256 | http://bellard.org/bpg/
257 | UTTypeTagSpecification
258 |
259 | public.filename-extension
260 |
261 | bpg
262 | BPG
263 |
264 |
265 |
266 |
267 | UTTypeConformsTo
268 |
269 | public.image
270 |
271 | UTTypeDescription
272 | WebP
273 | UTTypeIdentifier
274 | fr.whine.webp
275 | UTTypeReferenceURL
276 | https://developers.google.com/speed/webp/docs/riff_container
277 | UTTypeTagSpecification
278 |
279 | public.filename-extension
280 |
281 | webp
282 | WEBP
283 |
284 |
285 |
286 |
287 |
288 |
289 |
--------------------------------------------------------------------------------
/app/uti_exporter.app/Contents/MacOS/Application Stub:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nyx0uf/qlImageSize/41082059f6b0d57609a60aa27b7127552e17708f/app/uti_exporter.app/Contents/MacOS/Application Stub
--------------------------------------------------------------------------------
/app/uti_exporter.app/Contents/Resources/English.lproj/ApplicationStub.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nyx0uf/qlImageSize/41082059f6b0d57609a60aa27b7127552e17708f/app/uti_exporter.app/Contents/Resources/English.lproj/ApplicationStub.nib
--------------------------------------------------------------------------------
/app/uti_exporter.app/Contents/document.wflow:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMApplicationBuild
6 | 381
7 | AMApplicationVersion
8 | 2.4
9 | AMDocumentVersion
10 | 2
11 | actions
12 |
13 | connectors
14 |
15 | workflowMetaData
16 |
17 | workflowTypeIdentifier
18 | com.apple.Automator.application
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/common/bpg_decode.h:
--------------------------------------------------------------------------------
1 | //
2 | // bpg_decode.h
3 | // qlImageSize
4 | //
5 | // Created by @Nyx0uf on 30/12/14.
6 | // Copyright (c) 2014 Nyx0uf. All rights reserved.
7 | //
8 |
9 |
10 | #import "tools.h"
11 |
12 |
13 | #ifdef NYX_QL_SUPPORT_BPG_DECODE
14 | CF_RETURNS_RETAINED CGImageRef decode_bpg_at_path(CFStringRef filepath, image_infos* infos);
15 | #endif
16 |
17 | #ifdef NYX_MD_SUPPORT_BPG_DECODE
18 | bool get_bpg_informations_for_filepath(CFStringRef filepath, image_infos* infos);
19 | #endif
20 |
--------------------------------------------------------------------------------
/common/bpg_decode.m:
--------------------------------------------------------------------------------
1 | //
2 | // bpg_decode.m
3 | // qlImageSize
4 | //
5 | // Created by @Nyx0uf on 30/12/14.
6 | // Copyright (c) 2014 Nyx0uf. All rights reserved.
7 | //
8 |
9 |
10 | #import "bpg_decode.h"
11 | #import "libbpg.h"
12 |
13 |
14 | #ifdef NYX_QL_SUPPORT_BPG_DECODE
15 | CF_RETURNS_RETAINED CGImageRef decode_bpg_at_path(CFStringRef filepath, image_infos* infos)
16 | {
17 | // Read file
18 | uint8_t* buffer = NULL;
19 | const size_t file_size = read_file(filepath, &buffer);
20 | if (0 == file_size)
21 | {
22 | free(buffer);
23 | return NULL;
24 | }
25 |
26 | // Decode image
27 | BPGDecoderContext* bpg_ctx = bpg_decoder_open();
28 | int ret = bpg_decoder_decode(bpg_ctx, buffer, (int)file_size);
29 | free(buffer);
30 | if (ret < 0)
31 | {
32 | bpg_decoder_close(bpg_ctx);
33 | return NULL;
34 | }
35 |
36 | // Get image infos
37 | BPGImageInfo img_info_s, *img_info = &img_info_s;
38 | bpg_decoder_get_info(bpg_ctx, img_info);
39 | const size_t w = (size_t)img_info->width;
40 | const size_t h = (size_t)img_info->height;
41 |
42 | // Choose output colorspace (RGB / RGBA)
43 | const size_t num_c = img_info->has_alpha ? 4 : 3;
44 | const size_t stride = num_c * w;
45 | const size_t img_size = stride * h;
46 | uint8_t* rgb_buffer = (uint8_t*)malloc(img_size);
47 | size_t idx = 0;
48 | bpg_decoder_start(bpg_ctx, img_info->has_alpha ? BPG_OUTPUT_FORMAT_RGBA32 : BPG_OUTPUT_FORMAT_RGB24);
49 | for (size_t y = 0; y < h; y++)
50 | {
51 | bpg_decoder_get_line(bpg_ctx, rgb_buffer + idx);
52 | idx += stride;
53 | }
54 | bpg_decoder_close(bpg_ctx);
55 |
56 | if (infos != NULL)
57 | {
58 | infos->width = w;
59 | infos->height = h;
60 | infos->filesize = file_size;
61 | }
62 |
63 | // Create CGImage
64 | CGDataProviderRef data_provider = CGDataProviderCreateWithData(NULL, rgb_buffer, img_size, NULL);
65 | if (data_provider == NULL)
66 | {
67 | free(rgb_buffer);
68 | return NULL;
69 | }
70 | CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB();
71 | CGImageRef img_ref = CGImageCreate(w, h, 8, 8 * num_c, stride, color_space, kCGBitmapByteOrderDefault | ((img_info->has_alpha) ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNone), data_provider, NULL, true, kCGRenderingIntentDefault);
72 | CGColorSpaceRelease(color_space);
73 | CGDataProviderRelease(data_provider);
74 | free(rgb_buffer);
75 | return img_ref;
76 | }
77 | #endif /* NYX_QL_SUPPORT_BPG_DECODE */
78 |
79 | #ifdef NYX_MD_SUPPORT_BPG_DECODE
80 | bool get_bpg_informations_for_filepath(CFStringRef filepath, image_infos* infos)
81 | {
82 | // Read file
83 | uint8_t* buffer = NULL;
84 | const size_t size = read_file(filepath, &buffer);
85 | if (0 == size)
86 | {
87 | free(buffer);
88 | return false;
89 | }
90 |
91 | // Decode image
92 | BPGDecoderContext* bpg_ctx = bpg_decoder_open();
93 | int ret = bpg_decoder_decode(bpg_ctx, buffer, (int)size);
94 | free(buffer);
95 | if (ret < 0)
96 | {
97 | bpg_decoder_close(bpg_ctx);
98 | return false;
99 | }
100 |
101 | // Get image infos
102 | BPGImageInfo img_info_s, *img_info = &img_info_s;
103 | bpg_decoder_get_info(bpg_ctx, img_info);
104 | infos->width = (size_t)img_info->width;
105 | infos->height = (size_t)img_info->height;
106 | infos->has_alpha = (uint8_t)img_info->has_alpha;
107 | infos->bit_depth = (uint8_t)img_info->bit_depth;
108 | colorspace_t cs = colorspace_unknown;
109 | const BPGColorSpaceEnum color_space = (BPGColorSpaceEnum)img_info->color_space;
110 | switch (color_space)
111 | {
112 | case BPG_CS_RGB:
113 | cs = colorspace_rgb;
114 | break;
115 | case BPG_CS_YCbCr:
116 | cs = colorspace_ycbcr;
117 | break;
118 | case BPG_CS_YCgCo:
119 | cs = colorspace_ycgco;
120 | break;
121 | case BPG_CS_YCbCr_BT709:
122 | cs = colorspace_bt709;
123 | break;
124 | case BPG_CS_YCbCr_BT2020:
125 | cs = colorspace_bt2020;
126 | break;
127 | default:
128 | cs = colorspace_unknown;
129 | }
130 | infos->colorspace = cs;
131 | bpg_decoder_close(bpg_ctx);
132 |
133 | return true;
134 | }
135 | #endif /* NYX_MD_SUPPORT_BPG_DECODE */
136 |
--------------------------------------------------------------------------------
/common/netpbm_decode.h:
--------------------------------------------------------------------------------
1 | //
2 | // netpbm_decode.h
3 | // qlImageSize
4 | //
5 | // Created by @Nyx0uf on 30/12/14.
6 | // Copyright (c) 2014 Nyx0uf. All rights reserved.
7 | //
8 |
9 |
10 | #import "tools.h"
11 |
12 |
13 | #ifdef NYX_QL_SUPPORT_NETPBM_DECODE
14 | CF_RETURNS_RETAINED CGImageRef decode_netpbm_at_path(CFStringRef filepath, image_infos* infos);
15 | #endif
16 |
17 | #ifdef NYX_MD_SUPPORT_NETPBM_DECODE
18 | bool get_netpbm_informations_for_filepath(CFStringRef filepath, image_infos* infos);
19 | #endif
20 |
--------------------------------------------------------------------------------
/common/netpbm_decode.m:
--------------------------------------------------------------------------------
1 | //
2 | // netpbm_decode.m
3 | // qlImageSize
4 | //
5 | // Created by @Nyx0uf on 30/12/14.
6 | // Copyright (c) 2014 Nyx0uf. All rights reserved.
7 | //
8 |
9 |
10 | #import "netpbm_decode.h"
11 |
12 | #ifdef NYX_MD_SUPPORT_NETPBM_DECODE
13 | bool get_netpbm_informations_for_filepath(CFStringRef filepath, image_infos* infos)
14 | {
15 | // Read file
16 | uint8_t* buffer = NULL;
17 | const size_t size = read_file(filepath, &buffer);
18 | if (size <= 2)
19 | {
20 | free(buffer);
21 | return false;
22 | }
23 |
24 | // Check if Portable Pixmap
25 | // Luckily '0'-'9' are always sequential in C, so the code below should work
26 | if ((char)buffer[0] != 'P' && ((char)buffer[1] < '1' || (char)buffer[1] > '6'))
27 | {
28 | free(buffer);
29 | return false;
30 | }
31 |
32 | // Get width and height
33 | size_t index = 3, i = 0;
34 | char ctmp[8] = {0x00};
35 | char c;
36 | // The dimension we're finished reading; 0 if width, 1 if height, 2 if done
37 | int status = 0;
38 | while (status < 2 && index < size)
39 | {
40 | c = (char)buffer[index++];
41 |
42 | // Ignore whitespace
43 | if (isblank(c)) continue;
44 |
45 | // Ignore comments, which are from a '#' to the end of the line
46 | if (c == '#')
47 | {
48 | while (buffer[index++] != '\n');
49 | continue;
50 | }
51 |
52 | // Read width/height
53 | if (isnumber(c))
54 | {
55 | index--; // Push back number
56 | while (isnumber(c = (char)buffer[index++]))
57 | {
58 | ctmp[i++] = c;
59 | }
60 | switch (status)
61 | {
62 | case 0: // width
63 | infos->width = (size_t)atol(ctmp);
64 | case 1: // height
65 | infos->height = (size_t)atol(ctmp);
66 | }
67 |
68 | // Clean up
69 | status++;
70 | i = 0;
71 | memset(ctmp, 0x00, 8);
72 | }
73 | }
74 |
75 | infos->has_alpha = 0;
76 | infos->bit_depth = 8;
77 | infos->colorspace = colorspace_rgb;
78 |
79 | free(buffer);
80 |
81 | return true;
82 | }
83 | #endif /* NYX_MD_SUPPORT_NETPBM_DECODE */
84 |
85 | #ifdef NYX_QL_SUPPORT_NETPBM_DECODE
86 |
87 | #import
88 |
89 | typedef struct _nyx_rgb_pixel_struct {
90 | uint8_t r;
91 | uint8_t g;
92 | uint8_t b;
93 | } rgb_pixel;
94 |
95 | /* Private functions declarations */
96 | static void* _decode_pbm(const uint8_t* bytes, const size_t size, size_t* width, size_t* height);
97 | static void* _decode_pgm(const uint8_t* bytes, const size_t size, size_t* width, size_t* height);
98 | static void* _decode_ppm(const uint8_t* bytes, const size_t size, size_t* width, size_t* height);
99 |
100 | CF_RETURNS_RETAINED CGImageRef decode_netpbm_at_path(CFStringRef filepath, image_infos* infos)
101 | {
102 | // Read file
103 | uint8_t* buffer = NULL;
104 | const size_t file_size = read_file(filepath, &buffer);
105 | if (0 == file_size)
106 | {
107 | free(buffer);
108 | return NULL;
109 | }
110 |
111 | // Identify type (handle binary only)
112 | if ((char)buffer[0] != 'P')
113 | {
114 | free(buffer);
115 | return NULL;
116 | }
117 |
118 | // Only handle binary version for now
119 | uint8_t* rgb_buffer = NULL;
120 | size_t width = 0, height = 0;
121 | const char idd = (char)buffer[1];
122 | if (idd == '4'/* || idd == '1'*/) // pbm
123 | rgb_buffer = _decode_pbm(buffer, file_size, &width, &height);
124 | else if (idd == '5'/* || idd == '2'*/) // pgm
125 | rgb_buffer = _decode_pgm(buffer, file_size, &width, &height);
126 | else if (idd == '6'/* || idd == '3'*/) // ppm
127 | rgb_buffer = _decode_ppm(buffer, file_size, &width, &height);
128 | else
129 | {
130 | free(buffer);
131 | return NULL;
132 | }
133 | free(buffer);
134 |
135 | if (infos != NULL)
136 | {
137 | infos->width = width;
138 | infos->height = height;
139 | infos->filesize = file_size;
140 | }
141 |
142 | // Create CGImage
143 | CGDataProviderRef data_provider = CGDataProviderCreateWithData(NULL, rgb_buffer, width * height * 3, NULL);
144 | CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB();
145 | CGImageRef img_ref = CGImageCreate(width, height, 8, 24, 3 * width, color_space, kCGBitmapByteOrderDefault | kCGImageAlphaNone, data_provider, NULL, true, kCGRenderingIntentDefault);
146 | CGColorSpaceRelease(color_space);
147 | CGDataProviderRelease(data_provider);
148 | free(rgb_buffer);
149 | return img_ref;
150 | }
151 |
152 | #pragma mark - Private
153 | static void* _decode_pbm(const uint8_t* bytes, const size_t size, size_t* width, size_t* height)
154 | {
155 | // TODO: FIX cause it's bugged :>
156 | // format, where • is a separator (space, tab, newline)
157 | // P4•WIDTH•HEIGHT
158 |
159 | // Get width
160 | size_t index = 3, i = 0;
161 | char ctmp[8] = {0x00};
162 | char c = 0x00;
163 | while ((c = (char)bytes[index++]) && (!isspace(c)))
164 | ctmp[i++] = c;
165 | *width = (size_t)atol(ctmp);
166 |
167 | // Get height
168 | i = 0;
169 | memset(ctmp, 0x00, 8);
170 | while ((c = (char)bytes[index++]) && (!isspace(c)))
171 | ctmp[i++] = c;
172 | *height = (size_t)atol(ctmp);
173 |
174 | // 1 byte = 8 px
175 | //rgb_pixel* rgb_buffer = (rgb_pixel*)malloc(((size - index + 1) * 8) * 3);
176 | rgb_pixel* rgb_buffer = (rgb_pixel*)malloc((*width) * (*height) * 3);
177 | i = 0;
178 | while (index < size)
179 | {
180 | uint8_t b = bytes[index++];
181 | for (int a = 8; a >= 1; a--)
182 | {
183 | uint8_t tmp = ((b >> a) & 0x01);
184 | tmp = (0 == tmp) ? 255 : 0;
185 | rgb_buffer[i++] = (rgb_pixel){tmp, tmp, tmp};
186 | }
187 | }
188 |
189 | return rgb_buffer;
190 | }
191 |
192 | static void* _decode_pgm(const uint8_t* bytes, const size_t size, size_t* width, size_t* height)
193 | {
194 | // format, where • is a separator (space, tab, newline)
195 | // P5•WIDTH•HEIGHT•MAX_GRAY_VAL
196 |
197 | // Get width
198 | size_t index = 3, i = 0;
199 | char ctmp[8] = {0x00};
200 | char c = 0x00;
201 | while ((c = (char)bytes[index++]) && (!isspace(c)))
202 | ctmp[i++] = c;
203 | *width = (size_t)atol(ctmp);
204 |
205 | // Get height
206 | i = 0;
207 | memset(ctmp, 0x00, 8);
208 | while ((c = (char)bytes[index++]) && (!isspace(c)))
209 | ctmp[i++] = c;
210 | *height = (size_t)atol(ctmp);
211 |
212 | // Get max gray value (max is 65535), but we only handle 8-bit so over 255 is a no-no
213 | i = 0;
214 | memset(ctmp, 0x00, 8);
215 | while ((c = (char)bytes[index++]) && (!isspace(c)))
216 | ctmp[i++] = c;
217 | const size_t max_val = (size_t)atol(ctmp);
218 | if (max_val > 255)
219 | return NULL; // 16-bit, ignore.
220 |
221 | // Convert to RGB
222 | const size_t actual_size = (size - index + 1);
223 | rgb_pixel* rgb_buffer = (rgb_pixel*)malloc(sizeof(rgb_pixel) * actual_size);
224 | const float ratio = (float)max_val / 255.0f;
225 | i = 0;
226 | if ((int)ratio == 1)
227 | {
228 | while (index < size)
229 | {
230 | const uint8_t b = bytes[index++];
231 | rgb_buffer[i++] = (rgb_pixel){b, b, b};
232 | }
233 | }
234 | else
235 | {
236 | while (index < size)
237 | {
238 | const uint8_t b = (uint8_t)((float)bytes[index++] / ratio);
239 | rgb_buffer[i++] = (rgb_pixel){b, b, b};
240 | }
241 | }
242 |
243 | return rgb_buffer;
244 | }
245 |
246 | static void* _decode_ppm(const uint8_t* bytes, const size_t size, size_t* width, size_t* height)
247 | {
248 | // format, where • is a separator (space, tab, newline)
249 | // P6•WIDTH•HEIGHT•MAX_VAL
250 |
251 | // Get width
252 | size_t index = 3, i = 0;
253 | char ctmp[8] = {0x00};
254 | char c = 0x00;
255 | while ((c = (char)bytes[index++]) && (!isspace(c)))
256 | ctmp[i++] = c;
257 | *width = (size_t)atol(ctmp);
258 |
259 | // Get height
260 | i = 0;
261 | memset(ctmp, 0x00, 8);
262 | while ((c = (char)bytes[index++]) && (!isspace(c)))
263 | ctmp[i++] = c;
264 | *height = (size_t)atol(ctmp);
265 |
266 | // Get max component value (max is 65535), but we only handle 8-bit so over 255 is a no-no
267 | i = 0;
268 | memset(ctmp, 0x00, 8);
269 | while ((c = (char)bytes[index++]) && (!isspace(c)))
270 | ctmp[i++] = c;
271 | const size_t max_val = (size_t)atol(ctmp);
272 | if (max_val > 255)
273 | return NULL; // 16-bit, ignore.
274 |
275 | void* buffer = NULL;
276 | const size_t actual_size = (size - index + 1);
277 | const float ratio = (float)max_val / 255.0f;
278 | if ((int)ratio == 1)
279 | {
280 | // Got the same ratio, just have to make a copy
281 | buffer = (uint8_t*)malloc(sizeof(uint8_t) * actual_size);
282 | memcpy(buffer, &(bytes[index]), actual_size);
283 | }
284 | else
285 | {
286 | // Moronic case, whoever does this deserve to die
287 | float* data_as_float = (float*)malloc(sizeof(float) * actual_size);
288 | buffer = (uint8_t*)malloc(sizeof(uint8_t) * actual_size);
289 | vDSP_vfltu8(&(bytes[index]), 1, data_as_float, 1, actual_size);
290 | vDSP_vsdiv(data_as_float, 1, &ratio, data_as_float, 1, actual_size);
291 | vDSP_vfixu8(data_as_float, 1, buffer, 1, actual_size);
292 | free(data_as_float);
293 | }
294 |
295 | return buffer;
296 | }
297 |
298 | #endif /* NYX_QL_SUPPORT_NETPBM_DECODE */
299 |
--------------------------------------------------------------------------------
/common/tools.h:
--------------------------------------------------------------------------------
1 | //
2 | // tools.h
3 | // qlImageSize
4 | //
5 | // Created by @Nyx0uf on 02/02/12.
6 | // Copyright (c) 2012 Nyx0uf. All rights reserved.
7 | //
8 |
9 |
10 | #import
11 |
12 | #define NYX_QL_SUPPORT_BPG_DECODE
13 | #define NYX_MD_SUPPORT_BPG_DECODE
14 | #define NYX_QL_SUPPORT_WEBP_DECODE
15 | #define NYX_MD_SUPPORT_WEBP_DECODE
16 | //#define NYX_QL_SUPPORT_NETPBM_DECODE
17 | #define NYX_MD_SUPPORT_NETPBM_DECODE
18 |
19 | #define SAFE_CFRelease(ptr) do { if (ptr != NULL){ CFRelease(ptr); ptr = NULL;}} while(0)
20 |
21 |
22 | typedef enum _nyx_colorspace_t {
23 | colorspace_unknown = 0,
24 | colorspace_rgb = 1,
25 | colorspace_ycbcr,
26 | colorspace_ycgco,
27 | colorspace_bt709,
28 | colorspace_bt2020,
29 | } colorspace_t;
30 |
31 |
32 | typedef struct _nyx_image_infos_struct {
33 | size_t width;
34 | size_t height;
35 | uint8_t has_alpha;
36 | uint8_t bit_depth;
37 | size_t filesize;
38 | colorspace_t colorspace;
39 | size_t dpi;
40 | } image_infos;
41 |
42 |
43 | void properties_for_file(CFURLRef url, size_t* width, size_t* height, size_t* dpi, size_t* file_size);
44 |
45 | size_t read_file(CFStringRef filepath, uint8_t** buffer);
46 |
47 | const char* colorspace_string(const colorspace_t cs);
48 |
--------------------------------------------------------------------------------
/common/tools.m:
--------------------------------------------------------------------------------
1 | //
2 | // tools.m
3 | // qlImageSize
4 | //
5 | // Created by @Nyx0uf on 02/02/12.
6 | // Copyright (c) 2012 Nyx0uf. All rights reserved.
7 | //
8 |
9 |
10 | #import "tools.h"
11 | #import
12 | #import
13 | #import
14 |
15 |
16 | static size_t _get_file_size(CFURLRef url);
17 |
18 |
19 | #pragma mark - Public
20 | void properties_for_file(CFURLRef url, size_t* width, size_t* height, size_t* dpi, size_t* file_size)
21 | {
22 | // Create the image source
23 | *width = 0, *height = 0, *dpi = 0, *file_size = 0;
24 | CGImageSourceRef img_src = CGImageSourceCreateWithURL(url, NULL);
25 | if (NULL == img_src)
26 | return;
27 |
28 | // Copy images properties
29 | CFDictionaryRef img_properties = CGImageSourceCopyPropertiesAtIndex(img_src, 0, NULL);
30 | if (NULL == img_properties)
31 | {
32 | CFRelease(img_src);
33 | return;
34 | }
35 |
36 | // Get image width
37 | CFNumberRef w = CFDictionaryGetValue(img_properties, kCGImagePropertyPixelWidth);
38 | CFNumberGetValue(w, kCFNumberSInt64Type, width);
39 | // Get image height
40 | CFNumberRef h = CFDictionaryGetValue(img_properties, kCGImagePropertyPixelHeight);
41 | CFNumberGetValue(h, kCFNumberSInt64Type, height);
42 | // Get DPI
43 | CFNumberRef d = CFDictionaryGetValue(img_properties, kCGImagePropertyDPIWidth);
44 | if (d != NULL)
45 | CFNumberGetValue(d, kCFNumberSInt64Type, dpi);
46 | CFRelease(img_properties);
47 | CFRelease(img_src);
48 |
49 | // Get the filesize, because it's not always present in the image properties dictionary :/
50 | *file_size = _get_file_size(url);
51 | }
52 |
53 | size_t read_file(CFStringRef filepath, uint8_t** buffer)
54 | {
55 | // Open the file, get its size and read it
56 | FILE* f = fopen([(__bridge NSString*)filepath UTF8String], "rb");
57 | if (NULL == f)
58 | return 0;
59 |
60 | fseek(f, 0, SEEK_END);
61 | const size_t file_size = (size_t)ftell(f);
62 | fseek(f, 0, SEEK_SET);
63 |
64 | *buffer = (uint8_t*)malloc(file_size);
65 | if (NULL == (*buffer))
66 | {
67 | fclose(f);
68 | return 0;
69 | }
70 | const size_t read_size = fread(*buffer, 1, file_size, f);
71 | fclose(f);
72 | if (read_size != file_size)
73 | {
74 | free(*buffer), *buffer = NULL;
75 | return 0;
76 | }
77 |
78 | return file_size;
79 | }
80 |
81 | const char* colorspace_string(const colorspace_t cs)
82 | {
83 | switch (cs)
84 | {
85 | case colorspace_unknown:
86 | return "Unknown";
87 | case colorspace_rgb:
88 | return "RGB";
89 | case colorspace_ycbcr:
90 | return "Y'CbCr";
91 | case colorspace_ycgco:
92 | return "Y'CgCo";
93 | case colorspace_bt709:
94 | return "BT.709";
95 | case colorspace_bt2020:
96 | return "BT.2020";
97 | default:
98 | return "Unknown";
99 | }
100 | }
101 |
102 | #pragma mark - Private
103 | static size_t _get_file_size(CFURLRef url)
104 | {
105 | UInt8 buf[4096] = {0x00};
106 | CFURLGetFileSystemRepresentation(url, true, buf, 4096);
107 | struct stat st;
108 | stat((const char*)buf, &st);
109 | return (size_t)st.st_size;
110 | }
111 |
--------------------------------------------------------------------------------
/common/webp_decode.h:
--------------------------------------------------------------------------------
1 | //
2 | // webp_decode.h
3 | // qlImageSize
4 | //
5 | // Created by @Nyx0uf on 30/12/14.
6 | // Copyright (c) 2014 Nyx0uf. All rights reserved.
7 | //
8 |
9 |
10 | #import "tools.h"
11 |
12 |
13 | #ifdef NYX_QL_SUPPORT_WEBP_DECODE
14 | CF_RETURNS_RETAINED CGImageRef decode_webp_at_path(CFStringRef filepath, image_infos* infos);
15 | #endif
16 |
17 | #ifdef NYX_MD_SUPPORT_WEBP_DECODE
18 | bool get_webp_informations_for_filepath(CFStringRef filepath, image_infos* infos);
19 | #endif
20 |
--------------------------------------------------------------------------------
/common/webp_decode.m:
--------------------------------------------------------------------------------
1 | //
2 | // webp_decode.m
3 | // qlImageSize
4 | //
5 | // Created by @Nyx0uf on 30/12/14.
6 | // Copyright (c) 2014 Nyx0uf. All rights reserved.
7 | //
8 |
9 |
10 | #import "webp_decode.h"
11 | #import "decode.h"
12 |
13 |
14 | #ifdef NYX_QL_SUPPORT_WEBP_DECODE
15 | CF_RETURNS_RETAINED CGImageRef decode_webp_at_path(CFStringRef filepath, image_infos* infos)
16 | {
17 | // Init WebP decoder
18 | WebPDecoderConfig webp_cfg;
19 | if (!WebPInitDecoderConfig(&webp_cfg))
20 | return NULL;
21 |
22 | // Read file
23 | uint8_t* buffer = NULL;
24 | const size_t file_size = read_file(filepath, &buffer);
25 | if (0 == file_size)
26 | {
27 | free(buffer);
28 | return NULL;
29 | }
30 |
31 | // Get image infos
32 | if (WebPGetFeatures(buffer, file_size, &webp_cfg.input) != VP8_STATUS_OK)
33 | {
34 | free(buffer);
35 | return NULL;
36 | }
37 |
38 | // Decode image, always RGBA
39 | webp_cfg.output.colorspace = webp_cfg.input.has_alpha ? MODE_rgbA : MODE_RGB;
40 | webp_cfg.options.use_threads = 1;
41 | WebPIDecoder* const idec = WebPIDecode(buffer, file_size, &webp_cfg);
42 | if (idec == NULL)
43 | {
44 | free(buffer);
45 | return NULL;
46 | }
47 | else
48 | {
49 | VP8StatusCode status = VP8_STATUS_OK;
50 | size_t done_size = 0;
51 | const size_t incr = 25165824; // 24MB, arbitrary chosen
52 | while (done_size < file_size)
53 | {
54 | size_t next_size = done_size + incr;
55 | if (next_size > file_size)
56 | next_size = file_size;
57 | status = WebPIUpdate(idec, buffer, next_size);
58 | if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED)
59 | break;
60 | done_size = next_size;
61 | }
62 | WebPIDelete(idec);
63 | }
64 | free(buffer);
65 |
66 | const size_t width = (size_t)webp_cfg.input.width;
67 | const size_t height = (size_t)webp_cfg.input.height;
68 | if (infos != NULL)
69 | {
70 | infos->width = width;
71 | infos->height = height;
72 | infos->filesize = (size_t)file_size;
73 | }
74 |
75 | // Create CGImage
76 | CGDataProviderRef data_provider = CGDataProviderCreateWithData(NULL, webp_cfg.output.u.RGBA.rgba, webp_cfg.output.u.RGBA.size, NULL);
77 | if (data_provider == NULL)
78 | return NULL;
79 | CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB();
80 | CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Big | (webp_cfg.input.has_alpha ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNone);
81 | const size_t components = webp_cfg.input.has_alpha ? 4 : 3;
82 | CGImageRef img_ref = CGImageCreate(width, height, 8, components * 8, components * width, color_space, bitmapInfo, data_provider, NULL, false, kCGRenderingIntentDefault);
83 |
84 | CGColorSpaceRelease(color_space);
85 | CGDataProviderRelease(data_provider);
86 |
87 | return img_ref;
88 | }
89 | #endif /* NYX_QL_SUPPORT_WEBP_DECODE */
90 |
91 | #ifdef NYX_MD_SUPPORT_WEBP_DECODE
92 | bool get_webp_informations_for_filepath(CFStringRef filepath, image_infos* infos)
93 | {
94 | WebPDecoderConfig webp_cfg;
95 | if (!WebPInitDecoderConfig(&webp_cfg))
96 | return false;
97 |
98 | // Read file
99 | uint8_t* buffer = NULL;
100 | const size_t size = read_file(filepath, &buffer);
101 | if (0 == size)
102 | {
103 | free(buffer);
104 | return false;
105 | }
106 |
107 | // Get file informations
108 | if (WebPGetFeatures(buffer, size, &webp_cfg.input) != VP8_STATUS_OK)
109 | {
110 | free(buffer);
111 | return false;
112 | }
113 | free(buffer);
114 |
115 | infos->width = (size_t)webp_cfg.input.width;
116 | infos->height = (size_t)webp_cfg.input.height;
117 | infos->has_alpha = (uint8_t)webp_cfg.input.has_alpha;
118 | infos->bit_depth = 8;
119 | infos->colorspace = (webp_cfg.input.format == 2) ? colorspace_rgb : colorspace_ycbcr; // lossy WebP, always YUV 4:2:0 | lossless WebP, always ARGB
120 |
121 | return true;
122 | }
123 | #endif /* NYX_MD_SUPPORT_WEBP_DECODE */
124 |
--------------------------------------------------------------------------------
/deps/libbpg/libbpg.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nyx0uf/qlImageSize/41082059f6b0d57609a60aa27b7127552e17708f/deps/libbpg/libbpg.a
--------------------------------------------------------------------------------
/deps/libbpg/libbpg.h:
--------------------------------------------------------------------------------
1 | /*
2 | * BPG decoder
3 | *
4 | * Copyright (c) 2014 Fabrice Bellard
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | #ifndef _LIBBPG_H
25 | #define _LIBBPG_H
26 |
27 | #include
28 |
29 | typedef struct BPGDecoderContext BPGDecoderContext;
30 |
31 | typedef enum {
32 | BPG_FORMAT_GRAY,
33 | BPG_FORMAT_420, /* chroma at offset (0.5, 0.5) (JPEG) */
34 | BPG_FORMAT_422, /* chroma at offset (0.5, 0) (JPEG) */
35 | BPG_FORMAT_444,
36 | BPG_FORMAT_420_VIDEO, /* chroma at offset (0, 0.5) (MPEG2) */
37 | BPG_FORMAT_422_VIDEO, /* chroma at offset (0, 0) (MPEG2) */
38 | } BPGImageFormatEnum;
39 |
40 | typedef enum {
41 | BPG_CS_YCbCr,
42 | BPG_CS_RGB,
43 | BPG_CS_YCgCo,
44 | BPG_CS_YCbCr_BT709,
45 | BPG_CS_YCbCr_BT2020,
46 |
47 | BPG_CS_COUNT,
48 | } BPGColorSpaceEnum;
49 |
50 | typedef struct {
51 | uint32_t width;
52 | uint32_t height;
53 | uint8_t format; /* see BPGImageFormatEnum */
54 | uint8_t has_alpha; /* TRUE if an alpha plane is present */
55 | uint8_t color_space; /* see BPGColorSpaceEnum */
56 | uint8_t bit_depth;
57 | uint8_t premultiplied_alpha; /* TRUE if the color is alpha premultiplied */
58 | uint8_t has_w_plane; /* TRUE if a W plane is present (for CMYK encoding) */
59 | uint8_t limited_range; /* TRUE if limited range for the color */
60 | uint8_t has_animation; /* TRUE if the image contains animations */
61 | uint16_t loop_count; /* animations: number of loop, 0 = infinity */
62 | } BPGImageInfo;
63 |
64 | typedef enum {
65 | BPG_EXTENSION_TAG_EXIF = 1,
66 | BPG_EXTENSION_TAG_ICCP = 2,
67 | BPG_EXTENSION_TAG_XMP = 3,
68 | BPG_EXTENSION_TAG_THUMBNAIL = 4,
69 | BPG_EXTENSION_TAG_ANIM_CONTROL = 5,
70 | } BPGExtensionTagEnum;
71 |
72 | typedef struct BPGExtensionData {
73 | BPGExtensionTagEnum tag;
74 | uint32_t buf_len;
75 | uint8_t *buf;
76 | struct BPGExtensionData *next;
77 | } BPGExtensionData;
78 |
79 | typedef enum {
80 | BPG_OUTPUT_FORMAT_RGB24,
81 | BPG_OUTPUT_FORMAT_RGBA32, /* not premultiplied alpha */
82 | BPG_OUTPUT_FORMAT_RGB48,
83 | BPG_OUTPUT_FORMAT_RGBA64, /* not premultiplied alpha */
84 | BPG_OUTPUT_FORMAT_CMYK32,
85 | BPG_OUTPUT_FORMAT_CMYK64,
86 | } BPGDecoderOutputFormat;
87 |
88 | #define BPG_DECODER_INFO_BUF_SIZE 16
89 |
90 | BPGDecoderContext *bpg_decoder_open(void);
91 |
92 | /* If enable is true, extension data are kept during the image
93 | decoding and can be accessed after bpg_decoder_decode() with
94 | bpg_decoder_get_extension(). By default, the extension data are
95 | discarded. */
96 | void bpg_decoder_keep_extension_data(BPGDecoderContext *s, int enable);
97 |
98 | /* return 0 if 0K, < 0 if error */
99 | int bpg_decoder_decode(BPGDecoderContext *s, const uint8_t *buf, int buf_len);
100 |
101 | /* Return the first element of the extension data list */
102 | BPGExtensionData *bpg_decoder_get_extension_data(BPGDecoderContext *s);
103 |
104 | /* return 0 if 0K, < 0 if error */
105 | int bpg_decoder_get_info(BPGDecoderContext *s, BPGImageInfo *p);
106 |
107 | /* return 0 if 0K, < 0 if error */
108 | int bpg_decoder_start(BPGDecoderContext *s, BPGDecoderOutputFormat out_fmt);
109 |
110 | /* return the frame delay for animations as a fraction (*pnum) / (*pden)
111 | in seconds. In case there is no animation, 0 / 1 is returned. */
112 | void bpg_decoder_get_frame_duration(BPGDecoderContext *s, int *pnum, int *pden);
113 |
114 | /* return 0 if 0K, < 0 if error */
115 | int bpg_decoder_get_line(BPGDecoderContext *s, void *buf);
116 |
117 | void bpg_decoder_close(BPGDecoderContext *s);
118 |
119 | /* only useful for low level access to the image data */
120 | uint8_t *bpg_decoder_get_data(BPGDecoderContext *s, int *pline_size, int plane);
121 |
122 | /* Get information from the start of the image data in 'buf' (at least
123 | min(BPG_DECODER_INFO_BUF_SIZE, file_size) bytes must be given).
124 |
125 | If pfirst_md != NULL, the extension data are also parsed and the
126 | first element of the list is returned in *pfirst_md. The list must
127 | be freed with bpg_decoder_free_extension_data().
128 |
129 | BPGImageInfo.loop_count is only set if extension data are parsed.
130 |
131 | Return 0 if OK, < 0 if unrecognized data. */
132 | int bpg_decoder_get_info_from_buf(BPGImageInfo *p,
133 | BPGExtensionData **pfirst_md,
134 | const uint8_t *buf, int buf_len);
135 | /* Free the extension data returned by bpg_decoder_get_info_from_buf() */
136 | void bpg_decoder_free_extension_data(BPGExtensionData *first_md);
137 |
138 | #endif /* _LIBBPG_H */
139 |
--------------------------------------------------------------------------------
/deps/libwebp/decode.h:
--------------------------------------------------------------------------------
1 | // Copyright 2010 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // Main decoding functions for WebP images.
11 | //
12 | // Author: Skal (pascal.massimino@gmail.com)
13 |
14 | #ifndef WEBP_WEBP_DECODE_H_
15 | #define WEBP_WEBP_DECODE_H_
16 |
17 | #include "./types.h"
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif
22 |
23 | #define WEBP_DECODER_ABI_VERSION 0x0208 // MAJOR(8b) + MINOR(8b)
24 |
25 | // Note: forward declaring enumerations is not allowed in (strict) C and C++,
26 | // the types are left here for reference.
27 | // typedef enum VP8StatusCode VP8StatusCode;
28 | // typedef enum WEBP_CSP_MODE WEBP_CSP_MODE;
29 | typedef struct WebPRGBABuffer WebPRGBABuffer;
30 | typedef struct WebPYUVABuffer WebPYUVABuffer;
31 | typedef struct WebPDecBuffer WebPDecBuffer;
32 | typedef struct WebPIDecoder WebPIDecoder;
33 | typedef struct WebPBitstreamFeatures WebPBitstreamFeatures;
34 | typedef struct WebPDecoderOptions WebPDecoderOptions;
35 | typedef struct WebPDecoderConfig WebPDecoderConfig;
36 |
37 | // Return the decoder's version number, packed in hexadecimal using 8bits for
38 | // each of major/minor/revision. E.g: v2.5.7 is 0x020507.
39 | WEBP_EXTERN int WebPGetDecoderVersion(void);
40 |
41 | // Retrieve basic header information: width, height.
42 | // This function will also validate the header, returning true on success,
43 | // false otherwise. '*width' and '*height' are only valid on successful return.
44 | // Pointers 'width' and 'height' can be passed NULL if deemed irrelevant.
45 | WEBP_EXTERN int WebPGetInfo(const uint8_t* data, size_t data_size,
46 | int* width, int* height);
47 |
48 | // Decodes WebP images pointed to by 'data' and returns RGBA samples, along
49 | // with the dimensions in *width and *height. The ordering of samples in
50 | // memory is R, G, B, A, R, G, B, A... in scan order (endian-independent).
51 | // The returned pointer should be deleted calling WebPFree().
52 | // Returns NULL in case of error.
53 | WEBP_EXTERN uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size,
54 | int* width, int* height);
55 |
56 | // Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data.
57 | WEBP_EXTERN uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size,
58 | int* width, int* height);
59 |
60 | // Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data.
61 | WEBP_EXTERN uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size,
62 | int* width, int* height);
63 |
64 | // Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data.
65 | // If the bitstream contains transparency, it is ignored.
66 | WEBP_EXTERN uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
67 | int* width, int* height);
68 |
69 | // Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data.
70 | WEBP_EXTERN uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size,
71 | int* width, int* height);
72 |
73 |
74 | // Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer
75 | // returned is the Y samples buffer. Upon return, *u and *v will point to
76 | // the U and V chroma data. These U and V buffers need NOT be passed to
77 | // WebPFree(), unlike the returned Y luma one. The dimension of the U and V
78 | // planes are both (*width + 1) / 2 and (*height + 1)/ 2.
79 | // Upon return, the Y buffer has a stride returned as '*stride', while U and V
80 | // have a common stride returned as '*uv_stride'.
81 | // Return NULL in case of error.
82 | // (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr
83 | WEBP_EXTERN uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
84 | int* width, int* height,
85 | uint8_t** u, uint8_t** v,
86 | int* stride, int* uv_stride);
87 |
88 | // Releases memory returned by the WebPDecode*() functions above.
89 | WEBP_EXTERN void WebPFree(void* ptr);
90 |
91 | // These five functions are variants of the above ones, that decode the image
92 | // directly into a pre-allocated buffer 'output_buffer'. The maximum storage
93 | // available in this buffer is indicated by 'output_buffer_size'. If this
94 | // storage is not sufficient (or an error occurred), NULL is returned.
95 | // Otherwise, output_buffer is returned, for convenience.
96 | // The parameter 'output_stride' specifies the distance (in bytes)
97 | // between scanlines. Hence, output_buffer_size is expected to be at least
98 | // output_stride x picture-height.
99 | WEBP_EXTERN uint8_t* WebPDecodeRGBAInto(
100 | const uint8_t* data, size_t data_size,
101 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
102 | WEBP_EXTERN uint8_t* WebPDecodeARGBInto(
103 | const uint8_t* data, size_t data_size,
104 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
105 | WEBP_EXTERN uint8_t* WebPDecodeBGRAInto(
106 | const uint8_t* data, size_t data_size,
107 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
108 |
109 | // RGB and BGR variants. Here too the transparency information, if present,
110 | // will be dropped and ignored.
111 | WEBP_EXTERN uint8_t* WebPDecodeRGBInto(
112 | const uint8_t* data, size_t data_size,
113 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
114 | WEBP_EXTERN uint8_t* WebPDecodeBGRInto(
115 | const uint8_t* data, size_t data_size,
116 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
117 |
118 | // WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly
119 | // into pre-allocated luma/chroma plane buffers. This function requires the
120 | // strides to be passed: one for the luma plane and one for each of the
121 | // chroma ones. The size of each plane buffer is passed as 'luma_size',
122 | // 'u_size' and 'v_size' respectively.
123 | // Pointer to the luma plane ('*luma') is returned or NULL if an error occurred
124 | // during decoding (or because some buffers were found to be too small).
125 | WEBP_EXTERN uint8_t* WebPDecodeYUVInto(
126 | const uint8_t* data, size_t data_size,
127 | uint8_t* luma, size_t luma_size, int luma_stride,
128 | uint8_t* u, size_t u_size, int u_stride,
129 | uint8_t* v, size_t v_size, int v_stride);
130 |
131 | //------------------------------------------------------------------------------
132 | // Output colorspaces and buffer
133 |
134 | // Colorspaces
135 | // Note: the naming describes the byte-ordering of packed samples in memory.
136 | // For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,...
137 | // Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels.
138 | // RGBA-4444 and RGB-565 colorspaces are represented by following byte-order:
139 | // RGBA-4444: [r3 r2 r1 r0 g3 g2 g1 g0], [b3 b2 b1 b0 a3 a2 a1 a0], ...
140 | // RGB-565: [r4 r3 r2 r1 r0 g5 g4 g3], [g2 g1 g0 b4 b3 b2 b1 b0], ...
141 | // In the case WEBP_SWAP_16BITS_CSP is defined, the bytes are swapped for
142 | // these two modes:
143 | // RGBA-4444: [b3 b2 b1 b0 a3 a2 a1 a0], [r3 r2 r1 r0 g3 g2 g1 g0], ...
144 | // RGB-565: [g2 g1 g0 b4 b3 b2 b1 b0], [r4 r3 r2 r1 r0 g5 g4 g3], ...
145 |
146 | typedef enum WEBP_CSP_MODE {
147 | MODE_RGB = 0, MODE_RGBA = 1,
148 | MODE_BGR = 2, MODE_BGRA = 3,
149 | MODE_ARGB = 4, MODE_RGBA_4444 = 5,
150 | MODE_RGB_565 = 6,
151 | // RGB-premultiplied transparent modes (alpha value is preserved)
152 | MODE_rgbA = 7,
153 | MODE_bgrA = 8,
154 | MODE_Argb = 9,
155 | MODE_rgbA_4444 = 10,
156 | // YUV modes must come after RGB ones.
157 | MODE_YUV = 11, MODE_YUVA = 12, // yuv 4:2:0
158 | MODE_LAST = 13
159 | } WEBP_CSP_MODE;
160 |
161 | // Some useful macros:
162 | static WEBP_INLINE int WebPIsPremultipliedMode(WEBP_CSP_MODE mode) {
163 | return (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb ||
164 | mode == MODE_rgbA_4444);
165 | }
166 |
167 | static WEBP_INLINE int WebPIsAlphaMode(WEBP_CSP_MODE mode) {
168 | return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB ||
169 | mode == MODE_RGBA_4444 || mode == MODE_YUVA ||
170 | WebPIsPremultipliedMode(mode));
171 | }
172 |
173 | static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) {
174 | return (mode < MODE_YUV);
175 | }
176 |
177 | //------------------------------------------------------------------------------
178 | // WebPDecBuffer: Generic structure for describing the output sample buffer.
179 |
180 | struct WebPRGBABuffer { // view as RGBA
181 | uint8_t* rgba; // pointer to RGBA samples
182 | int stride; // stride in bytes from one scanline to the next.
183 | size_t size; // total size of the *rgba buffer.
184 | };
185 |
186 | struct WebPYUVABuffer { // view as YUVA
187 | uint8_t* y, *u, *v, *a; // pointer to luma, chroma U/V, alpha samples
188 | int y_stride; // luma stride
189 | int u_stride, v_stride; // chroma strides
190 | int a_stride; // alpha stride
191 | size_t y_size; // luma plane size
192 | size_t u_size, v_size; // chroma planes size
193 | size_t a_size; // alpha-plane size
194 | };
195 |
196 | // Output buffer
197 | struct WebPDecBuffer {
198 | WEBP_CSP_MODE colorspace; // Colorspace.
199 | int width, height; // Dimensions.
200 | int is_external_memory; // If non-zero, 'internal_memory' pointer is not
201 | // used. If value is '2' or more, the external
202 | // memory is considered 'slow' and multiple
203 | // read/write will be avoided.
204 | union {
205 | WebPRGBABuffer RGBA;
206 | WebPYUVABuffer YUVA;
207 | } u; // Nameless union of buffer parameters.
208 | uint32_t pad[4]; // padding for later use
209 |
210 | uint8_t* private_memory; // Internally allocated memory (only when
211 | // is_external_memory is 0). Should not be used
212 | // externally, but accessed via the buffer union.
213 | };
214 |
215 | // Internal, version-checked, entry point
216 | WEBP_EXTERN int WebPInitDecBufferInternal(WebPDecBuffer*, int);
217 |
218 | // Initialize the structure as empty. Must be called before any other use.
219 | // Returns false in case of version mismatch
220 | static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) {
221 | return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION);
222 | }
223 |
224 | // Free any memory associated with the buffer. Must always be called last.
225 | // Note: doesn't free the 'buffer' structure itself.
226 | WEBP_EXTERN void WebPFreeDecBuffer(WebPDecBuffer* buffer);
227 |
228 | //------------------------------------------------------------------------------
229 | // Enumeration of the status codes
230 |
231 | typedef enum VP8StatusCode {
232 | VP8_STATUS_OK = 0,
233 | VP8_STATUS_OUT_OF_MEMORY,
234 | VP8_STATUS_INVALID_PARAM,
235 | VP8_STATUS_BITSTREAM_ERROR,
236 | VP8_STATUS_UNSUPPORTED_FEATURE,
237 | VP8_STATUS_SUSPENDED,
238 | VP8_STATUS_USER_ABORT,
239 | VP8_STATUS_NOT_ENOUGH_DATA
240 | } VP8StatusCode;
241 |
242 | //------------------------------------------------------------------------------
243 | // Incremental decoding
244 | //
245 | // This API allows streamlined decoding of partial data.
246 | // Picture can be incrementally decoded as data become available thanks to the
247 | // WebPIDecoder object. This object can be left in a SUSPENDED state if the
248 | // picture is only partially decoded, pending additional input.
249 | // Code example:
250 | //
251 | // WebPInitDecBuffer(&output_buffer);
252 | // output_buffer.colorspace = mode;
253 | // ...
254 | // WebPIDecoder* idec = WebPINewDecoder(&output_buffer);
255 | // while (additional_data_is_available) {
256 | // // ... (get additional data in some new_data[] buffer)
257 | // status = WebPIAppend(idec, new_data, new_data_size);
258 | // if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) {
259 | // break; // an error occurred.
260 | // }
261 | //
262 | // // The above call decodes the current available buffer.
263 | // // Part of the image can now be refreshed by calling
264 | // // WebPIDecGetRGB()/WebPIDecGetYUVA() etc.
265 | // }
266 | // WebPIDelete(idec);
267 |
268 | // Creates a new incremental decoder with the supplied buffer parameter.
269 | // This output_buffer can be passed NULL, in which case a default output buffer
270 | // is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer'
271 | // is kept, which means that the lifespan of 'output_buffer' must be larger than
272 | // that of the returned WebPIDecoder object.
273 | // The supplied 'output_buffer' content MUST NOT be changed between calls to
274 | // WebPIAppend() or WebPIUpdate() unless 'output_buffer.is_external_memory' is
275 | // not set to 0. In such a case, it is allowed to modify the pointers, size and
276 | // stride of output_buffer.u.RGBA or output_buffer.u.YUVA, provided they remain
277 | // within valid bounds.
278 | // All other fields of WebPDecBuffer MUST remain constant between calls.
279 | // Returns NULL if the allocation failed.
280 | WEBP_EXTERN WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer);
281 |
282 | // This function allocates and initializes an incremental-decoder object, which
283 | // will output the RGB/A samples specified by 'csp' into a preallocated
284 | // buffer 'output_buffer'. The size of this buffer is at least
285 | // 'output_buffer_size' and the stride (distance in bytes between two scanlines)
286 | // is specified by 'output_stride'.
287 | // Additionally, output_buffer can be passed NULL in which case the output
288 | // buffer will be allocated automatically when the decoding starts. The
289 | // colorspace 'csp' is taken into account for allocating this buffer. All other
290 | // parameters are ignored.
291 | // Returns NULL if the allocation failed, or if some parameters are invalid.
292 | WEBP_EXTERN WebPIDecoder* WebPINewRGB(
293 | WEBP_CSP_MODE csp,
294 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
295 |
296 | // This function allocates and initializes an incremental-decoder object, which
297 | // will output the raw luma/chroma samples into a preallocated planes if
298 | // supplied. The luma plane is specified by its pointer 'luma', its size
299 | // 'luma_size' and its stride 'luma_stride'. Similarly, the chroma-u plane
300 | // is specified by the 'u', 'u_size' and 'u_stride' parameters, and the chroma-v
301 | // plane by 'v' and 'v_size'. And same for the alpha-plane. The 'a' pointer
302 | // can be pass NULL in case one is not interested in the transparency plane.
303 | // Conversely, 'luma' can be passed NULL if no preallocated planes are supplied.
304 | // In this case, the output buffer will be automatically allocated (using
305 | // MODE_YUVA) when decoding starts. All parameters are then ignored.
306 | // Returns NULL if the allocation failed or if a parameter is invalid.
307 | WEBP_EXTERN WebPIDecoder* WebPINewYUVA(
308 | uint8_t* luma, size_t luma_size, int luma_stride,
309 | uint8_t* u, size_t u_size, int u_stride,
310 | uint8_t* v, size_t v_size, int v_stride,
311 | uint8_t* a, size_t a_size, int a_stride);
312 |
313 | // Deprecated version of the above, without the alpha plane.
314 | // Kept for backward compatibility.
315 | WEBP_EXTERN WebPIDecoder* WebPINewYUV(
316 | uint8_t* luma, size_t luma_size, int luma_stride,
317 | uint8_t* u, size_t u_size, int u_stride,
318 | uint8_t* v, size_t v_size, int v_stride);
319 |
320 | // Deletes the WebPIDecoder object and associated memory. Must always be called
321 | // if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded.
322 | WEBP_EXTERN void WebPIDelete(WebPIDecoder* idec);
323 |
324 | // Copies and decodes the next available data. Returns VP8_STATUS_OK when
325 | // the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more
326 | // data is expected. Returns error in other cases.
327 | WEBP_EXTERN VP8StatusCode WebPIAppend(
328 | WebPIDecoder* idec, const uint8_t* data, size_t data_size);
329 |
330 | // A variant of the above function to be used when data buffer contains
331 | // partial data from the beginning. In this case data buffer is not copied
332 | // to the internal memory.
333 | // Note that the value of the 'data' pointer can change between calls to
334 | // WebPIUpdate, for instance when the data buffer is resized to fit larger data.
335 | WEBP_EXTERN VP8StatusCode WebPIUpdate(
336 | WebPIDecoder* idec, const uint8_t* data, size_t data_size);
337 |
338 | // Returns the RGB/A image decoded so far. Returns NULL if output params
339 | // are not initialized yet. The RGB/A output type corresponds to the colorspace
340 | // specified during call to WebPINewDecoder() or WebPINewRGB().
341 | // *last_y is the index of last decoded row in raster scan order. Some pointers
342 | // (*last_y, *width etc.) can be NULL if corresponding information is not
343 | // needed. The values in these pointers are only valid on successful (non-NULL)
344 | // return.
345 | WEBP_EXTERN uint8_t* WebPIDecGetRGB(
346 | const WebPIDecoder* idec, int* last_y,
347 | int* width, int* height, int* stride);
348 |
349 | // Same as above function to get a YUVA image. Returns pointer to the luma
350 | // plane or NULL in case of error. If there is no alpha information
351 | // the alpha pointer '*a' will be returned NULL.
352 | WEBP_EXTERN uint8_t* WebPIDecGetYUVA(
353 | const WebPIDecoder* idec, int* last_y,
354 | uint8_t** u, uint8_t** v, uint8_t** a,
355 | int* width, int* height, int* stride, int* uv_stride, int* a_stride);
356 |
357 | // Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the
358 | // alpha information (if present). Kept for backward compatibility.
359 | static WEBP_INLINE uint8_t* WebPIDecGetYUV(
360 | const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v,
361 | int* width, int* height, int* stride, int* uv_stride) {
362 | return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height,
363 | stride, uv_stride, NULL);
364 | }
365 |
366 | // Generic call to retrieve information about the displayable area.
367 | // If non NULL, the left/right/width/height pointers are filled with the visible
368 | // rectangular area so far.
369 | // Returns NULL in case the incremental decoder object is in an invalid state.
370 | // Otherwise returns the pointer to the internal representation. This structure
371 | // is read-only, tied to WebPIDecoder's lifespan and should not be modified.
372 | WEBP_EXTERN const WebPDecBuffer* WebPIDecodedArea(
373 | const WebPIDecoder* idec, int* left, int* top, int* width, int* height);
374 |
375 | //------------------------------------------------------------------------------
376 | // Advanced decoding parametrization
377 | //
378 | // Code sample for using the advanced decoding API
379 | /*
380 | // A) Init a configuration object
381 | WebPDecoderConfig config;
382 | CHECK(WebPInitDecoderConfig(&config));
383 |
384 | // B) optional: retrieve the bitstream's features.
385 | CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
386 |
387 | // C) Adjust 'config', if needed
388 | config.no_fancy_upsampling = 1;
389 | config.output.colorspace = MODE_BGRA;
390 | // etc.
391 |
392 | // Note that you can also make config.output point to an externally
393 | // supplied memory buffer, provided it's big enough to store the decoded
394 | // picture. Otherwise, config.output will just be used to allocate memory
395 | // and store the decoded picture.
396 |
397 | // D) Decode!
398 | CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
399 |
400 | // E) Decoded image is now in config.output (and config.output.u.RGBA)
401 |
402 | // F) Reclaim memory allocated in config's object. It's safe to call
403 | // this function even if the memory is external and wasn't allocated
404 | // by WebPDecode().
405 | WebPFreeDecBuffer(&config.output);
406 | */
407 |
408 | // Features gathered from the bitstream
409 | struct WebPBitstreamFeatures {
410 | int width; // Width in pixels, as read from the bitstream.
411 | int height; // Height in pixels, as read from the bitstream.
412 | int has_alpha; // True if the bitstream contains an alpha channel.
413 | int has_animation; // True if the bitstream is an animation.
414 | int format; // 0 = undefined (/mixed), 1 = lossy, 2 = lossless
415 |
416 | uint32_t pad[5]; // padding for later use
417 | };
418 |
419 | // Internal, version-checked, entry point
420 | WEBP_EXTERN VP8StatusCode WebPGetFeaturesInternal(
421 | const uint8_t*, size_t, WebPBitstreamFeatures*, int);
422 |
423 | // Retrieve features from the bitstream. The *features structure is filled
424 | // with information gathered from the bitstream.
425 | // Returns VP8_STATUS_OK when the features are successfully retrieved. Returns
426 | // VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the
427 | // features from headers. Returns error in other cases.
428 | static WEBP_INLINE VP8StatusCode WebPGetFeatures(
429 | const uint8_t* data, size_t data_size,
430 | WebPBitstreamFeatures* features) {
431 | return WebPGetFeaturesInternal(data, data_size, features,
432 | WEBP_DECODER_ABI_VERSION);
433 | }
434 |
435 | // Decoding options
436 | struct WebPDecoderOptions {
437 | int bypass_filtering; // if true, skip the in-loop filtering
438 | int no_fancy_upsampling; // if true, use faster pointwise upsampler
439 | int use_cropping; // if true, cropping is applied _first_
440 | int crop_left, crop_top; // top-left position for cropping.
441 | // Will be snapped to even values.
442 | int crop_width, crop_height; // dimension of the cropping area
443 | int use_scaling; // if true, scaling is applied _afterward_
444 | int scaled_width, scaled_height; // final resolution
445 | int use_threads; // if true, use multi-threaded decoding
446 | int dithering_strength; // dithering strength (0=Off, 100=full)
447 | int flip; // flip output vertically
448 | int alpha_dithering_strength; // alpha dithering strength in [0..100]
449 |
450 | uint32_t pad[5]; // padding for later use
451 | };
452 |
453 | // Main object storing the configuration for advanced decoding.
454 | struct WebPDecoderConfig {
455 | WebPBitstreamFeatures input; // Immutable bitstream features (optional)
456 | WebPDecBuffer output; // Output buffer (can point to external mem)
457 | WebPDecoderOptions options; // Decoding options
458 | };
459 |
460 | // Internal, version-checked, entry point
461 | WEBP_EXTERN int WebPInitDecoderConfigInternal(WebPDecoderConfig*, int);
462 |
463 | // Initialize the configuration as empty. This function must always be
464 | // called first, unless WebPGetFeatures() is to be called.
465 | // Returns false in case of mismatched version.
466 | static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) {
467 | return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION);
468 | }
469 |
470 | // Instantiate a new incremental decoder object with the requested
471 | // configuration. The bitstream can be passed using 'data' and 'data_size'
472 | // parameter, in which case the features will be parsed and stored into
473 | // config->input. Otherwise, 'data' can be NULL and no parsing will occur.
474 | // Note that 'config' can be NULL too, in which case a default configuration
475 | // is used. If 'config' is not NULL, it must outlive the WebPIDecoder object
476 | // as some references to its fields will be used. No internal copy of 'config'
477 | // is made.
478 | // The return WebPIDecoder object must always be deleted calling WebPIDelete().
479 | // Returns NULL in case of error (and config->status will then reflect
480 | // the error condition, if available).
481 | WEBP_EXTERN WebPIDecoder* WebPIDecode(const uint8_t* data, size_t data_size,
482 | WebPDecoderConfig* config);
483 |
484 | // Non-incremental version. This version decodes the full data at once, taking
485 | // 'config' into account. Returns decoding status (which should be VP8_STATUS_OK
486 | // if the decoding was successful). Note that 'config' cannot be NULL.
487 | WEBP_EXTERN VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size,
488 | WebPDecoderConfig* config);
489 |
490 | #ifdef __cplusplus
491 | } // extern "C"
492 | #endif
493 |
494 | #endif // WEBP_WEBP_DECODE_H_
495 |
--------------------------------------------------------------------------------
/deps/libwebp/demux.h:
--------------------------------------------------------------------------------
1 | // Copyright 2012 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // Demux API.
11 | // Enables extraction of image and extended format data from WebP files.
12 |
13 | // Code Example: Demuxing WebP data to extract all the frames, ICC profile
14 | // and EXIF/XMP metadata.
15 | /*
16 | WebPDemuxer* demux = WebPDemux(&webp_data);
17 |
18 | uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
19 | uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
20 | // ... (Get information about the features present in the WebP file).
21 | uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
22 |
23 | // ... (Iterate over all frames).
24 | WebPIterator iter;
25 | if (WebPDemuxGetFrame(demux, 1, &iter)) {
26 | do {
27 | // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
28 | // ... and get other frame properties like width, height, offsets etc.
29 | // ... see 'struct WebPIterator' below for more info).
30 | } while (WebPDemuxNextFrame(&iter));
31 | WebPDemuxReleaseIterator(&iter);
32 | }
33 |
34 | // ... (Extract metadata).
35 | WebPChunkIterator chunk_iter;
36 | if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
37 | // ... (Consume the ICC profile in 'chunk_iter.chunk').
38 | WebPDemuxReleaseChunkIterator(&chunk_iter);
39 | if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
40 | // ... (Consume the EXIF metadata in 'chunk_iter.chunk').
41 | WebPDemuxReleaseChunkIterator(&chunk_iter);
42 | if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
43 | // ... (Consume the XMP metadata in 'chunk_iter.chunk').
44 | WebPDemuxReleaseChunkIterator(&chunk_iter);
45 | WebPDemuxDelete(demux);
46 | */
47 |
48 | #ifndef WEBP_WEBP_DEMUX_H_
49 | #define WEBP_WEBP_DEMUX_H_
50 |
51 | #include "./decode.h" // for WEBP_CSP_MODE
52 | #include "./mux_types.h"
53 |
54 | #ifdef __cplusplus
55 | extern "C" {
56 | #endif
57 |
58 | #define WEBP_DEMUX_ABI_VERSION 0x0107 // MAJOR(8b) + MINOR(8b)
59 |
60 | // Note: forward declaring enumerations is not allowed in (strict) C and C++,
61 | // the types are left here for reference.
62 | // typedef enum WebPDemuxState WebPDemuxState;
63 | // typedef enum WebPFormatFeature WebPFormatFeature;
64 | typedef struct WebPDemuxer WebPDemuxer;
65 | typedef struct WebPIterator WebPIterator;
66 | typedef struct WebPChunkIterator WebPChunkIterator;
67 | typedef struct WebPAnimInfo WebPAnimInfo;
68 | typedef struct WebPAnimDecoderOptions WebPAnimDecoderOptions;
69 |
70 | //------------------------------------------------------------------------------
71 |
72 | // Returns the version number of the demux library, packed in hexadecimal using
73 | // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.
74 | WEBP_EXTERN int WebPGetDemuxVersion(void);
75 |
76 | //------------------------------------------------------------------------------
77 | // Life of a Demux object
78 |
79 | typedef enum WebPDemuxState {
80 | WEBP_DEMUX_PARSE_ERROR = -1, // An error occurred while parsing.
81 | WEBP_DEMUX_PARSING_HEADER = 0, // Not enough data to parse full header.
82 | WEBP_DEMUX_PARSED_HEADER = 1, // Header parsing complete,
83 | // data may be available.
84 | WEBP_DEMUX_DONE = 2 // Entire file has been parsed.
85 | } WebPDemuxState;
86 |
87 | // Internal, version-checked, entry point
88 | WEBP_EXTERN WebPDemuxer* WebPDemuxInternal(
89 | const WebPData*, int, WebPDemuxState*, int);
90 |
91 | // Parses the full WebP file given by 'data'. For single images the WebP file
92 | // header alone or the file header and the chunk header may be absent.
93 | // Returns a WebPDemuxer object on successful parse, NULL otherwise.
94 | static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) {
95 | return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION);
96 | }
97 |
98 | // Parses the possibly incomplete WebP file given by 'data'.
99 | // If 'state' is non-NULL it will be set to indicate the status of the demuxer.
100 | // Returns NULL in case of error or if there isn't enough data to start parsing;
101 | // and a WebPDemuxer object on successful parse.
102 | // Note that WebPDemuxer keeps internal pointers to 'data' memory segment.
103 | // If this data is volatile, the demuxer object should be deleted (by calling
104 | // WebPDemuxDelete()) and WebPDemuxPartial() called again on the new data.
105 | // This is usually an inexpensive operation.
106 | static WEBP_INLINE WebPDemuxer* WebPDemuxPartial(
107 | const WebPData* data, WebPDemuxState* state) {
108 | return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION);
109 | }
110 |
111 | // Frees memory associated with 'dmux'.
112 | WEBP_EXTERN void WebPDemuxDelete(WebPDemuxer* dmux);
113 |
114 | //------------------------------------------------------------------------------
115 | // Data/information extraction.
116 |
117 | typedef enum WebPFormatFeature {
118 | WEBP_FF_FORMAT_FLAGS, // bit-wise combination of WebPFeatureFlags
119 | // corresponding to the 'VP8X' chunk (if present).
120 | WEBP_FF_CANVAS_WIDTH,
121 | WEBP_FF_CANVAS_HEIGHT,
122 | WEBP_FF_LOOP_COUNT, // only relevant for animated file
123 | WEBP_FF_BACKGROUND_COLOR, // idem.
124 | WEBP_FF_FRAME_COUNT // Number of frames present in the demux object.
125 | // In case of a partial demux, this is the number
126 | // of frames seen so far, with the last frame
127 | // possibly being partial.
128 | } WebPFormatFeature;
129 |
130 | // Get the 'feature' value from the 'dmux'.
131 | // NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial()
132 | // returned a state > WEBP_DEMUX_PARSING_HEADER.
133 | // If 'feature' is WEBP_FF_FORMAT_FLAGS, the returned value is a bit-wise
134 | // combination of WebPFeatureFlags values.
135 | // If 'feature' is WEBP_FF_LOOP_COUNT, WEBP_FF_BACKGROUND_COLOR, the returned
136 | // value is only meaningful if the bitstream is animated.
137 | WEBP_EXTERN uint32_t WebPDemuxGetI(
138 | const WebPDemuxer* dmux, WebPFormatFeature feature);
139 |
140 | //------------------------------------------------------------------------------
141 | // Frame iteration.
142 |
143 | struct WebPIterator {
144 | int frame_num;
145 | int num_frames; // equivalent to WEBP_FF_FRAME_COUNT.
146 | int x_offset, y_offset; // offset relative to the canvas.
147 | int width, height; // dimensions of this frame.
148 | int duration; // display duration in milliseconds.
149 | WebPMuxAnimDispose dispose_method; // dispose method for the frame.
150 | int complete; // true if 'fragment' contains a full frame. partial images
151 | // may still be decoded with the WebP incremental decoder.
152 | WebPData fragment; // The frame given by 'frame_num'. Note for historical
153 | // reasons this is called a fragment.
154 | int has_alpha; // True if the frame contains transparency.
155 | WebPMuxAnimBlend blend_method; // Blend operation for the frame.
156 |
157 | uint32_t pad[2]; // padding for later use.
158 | void* private_; // for internal use only.
159 | };
160 |
161 | // Retrieves frame 'frame_number' from 'dmux'.
162 | // 'iter->fragment' points to the frame on return from this function.
163 | // Setting 'frame_number' equal to 0 will return the last frame of the image.
164 | // Returns false if 'dmux' is NULL or frame 'frame_number' is not present.
165 | // Call WebPDemuxReleaseIterator() when use of the iterator is complete.
166 | // NOTE: 'dmux' must persist for the lifetime of 'iter'.
167 | WEBP_EXTERN int WebPDemuxGetFrame(
168 | const WebPDemuxer* dmux, int frame_number, WebPIterator* iter);
169 |
170 | // Sets 'iter->fragment' to point to the next ('iter->frame_num' + 1) or
171 | // previous ('iter->frame_num' - 1) frame. These functions do not loop.
172 | // Returns true on success, false otherwise.
173 | WEBP_EXTERN int WebPDemuxNextFrame(WebPIterator* iter);
174 | WEBP_EXTERN int WebPDemuxPrevFrame(WebPIterator* iter);
175 |
176 | // Releases any memory associated with 'iter'.
177 | // Must be called before any subsequent calls to WebPDemuxGetChunk() on the same
178 | // iter. Also, must be called before destroying the associated WebPDemuxer with
179 | // WebPDemuxDelete().
180 | WEBP_EXTERN void WebPDemuxReleaseIterator(WebPIterator* iter);
181 |
182 | //------------------------------------------------------------------------------
183 | // Chunk iteration.
184 |
185 | struct WebPChunkIterator {
186 | // The current and total number of chunks with the fourcc given to
187 | // WebPDemuxGetChunk().
188 | int chunk_num;
189 | int num_chunks;
190 | WebPData chunk; // The payload of the chunk.
191 |
192 | uint32_t pad[6]; // padding for later use
193 | void* private_;
194 | };
195 |
196 | // Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from
197 | // 'dmux'.
198 | // 'fourcc' is a character array containing the fourcc of the chunk to return,
199 | // e.g., "ICCP", "XMP ", "EXIF", etc.
200 | // Setting 'chunk_number' equal to 0 will return the last chunk in a set.
201 | // Returns true if the chunk is found, false otherwise. Image related chunk
202 | // payloads are accessed through WebPDemuxGetFrame() and related functions.
203 | // Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete.
204 | // NOTE: 'dmux' must persist for the lifetime of the iterator.
205 | WEBP_EXTERN int WebPDemuxGetChunk(const WebPDemuxer* dmux,
206 | const char fourcc[4], int chunk_number,
207 | WebPChunkIterator* iter);
208 |
209 | // Sets 'iter->chunk' to point to the next ('iter->chunk_num' + 1) or previous
210 | // ('iter->chunk_num' - 1) chunk. These functions do not loop.
211 | // Returns true on success, false otherwise.
212 | WEBP_EXTERN int WebPDemuxNextChunk(WebPChunkIterator* iter);
213 | WEBP_EXTERN int WebPDemuxPrevChunk(WebPChunkIterator* iter);
214 |
215 | // Releases any memory associated with 'iter'.
216 | // Must be called before destroying the associated WebPDemuxer with
217 | // WebPDemuxDelete().
218 | WEBP_EXTERN void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter);
219 |
220 | //------------------------------------------------------------------------------
221 | // WebPAnimDecoder API
222 | //
223 | // This API allows decoding (possibly) animated WebP images.
224 | //
225 | // Code Example:
226 | /*
227 | WebPAnimDecoderOptions dec_options;
228 | WebPAnimDecoderOptionsInit(&dec_options);
229 | // Tune 'dec_options' as needed.
230 | WebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options);
231 | WebPAnimInfo anim_info;
232 | WebPAnimDecoderGetInfo(dec, &anim_info);
233 | for (uint32_t i = 0; i < anim_info.loop_count; ++i) {
234 | while (WebPAnimDecoderHasMoreFrames(dec)) {
235 | uint8_t* buf;
236 | int timestamp;
237 | WebPAnimDecoderGetNext(dec, &buf, ×tamp);
238 | // ... (Render 'buf' based on 'timestamp').
239 | // ... (Do NOT free 'buf', as it is owned by 'dec').
240 | }
241 | WebPAnimDecoderReset(dec);
242 | }
243 | const WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec);
244 | // ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data).
245 | WebPAnimDecoderDelete(dec);
246 | */
247 |
248 | typedef struct WebPAnimDecoder WebPAnimDecoder; // Main opaque object.
249 |
250 | // Global options.
251 | struct WebPAnimDecoderOptions {
252 | // Output colorspace. Only the following modes are supported:
253 | // MODE_RGBA, MODE_BGRA, MODE_rgbA and MODE_bgrA.
254 | WEBP_CSP_MODE color_mode;
255 | int use_threads; // If true, use multi-threaded decoding.
256 | uint32_t padding[7]; // Padding for later use.
257 | };
258 |
259 | // Internal, version-checked, entry point.
260 | WEBP_EXTERN int WebPAnimDecoderOptionsInitInternal(
261 | WebPAnimDecoderOptions*, int);
262 |
263 | // Should always be called, to initialize a fresh WebPAnimDecoderOptions
264 | // structure before modification. Returns false in case of version mismatch.
265 | // WebPAnimDecoderOptionsInit() must have succeeded before using the
266 | // 'dec_options' object.
267 | static WEBP_INLINE int WebPAnimDecoderOptionsInit(
268 | WebPAnimDecoderOptions* dec_options) {
269 | return WebPAnimDecoderOptionsInitInternal(dec_options,
270 | WEBP_DEMUX_ABI_VERSION);
271 | }
272 |
273 | // Internal, version-checked, entry point.
274 | WEBP_EXTERN WebPAnimDecoder* WebPAnimDecoderNewInternal(
275 | const WebPData*, const WebPAnimDecoderOptions*, int);
276 |
277 | // Creates and initializes a WebPAnimDecoder object.
278 | // Parameters:
279 | // webp_data - (in) WebP bitstream. This should remain unchanged during the
280 | // lifetime of the output WebPAnimDecoder object.
281 | // dec_options - (in) decoding options. Can be passed NULL to choose
282 | // reasonable defaults (in particular, color mode MODE_RGBA
283 | // will be picked).
284 | // Returns:
285 | // A pointer to the newly created WebPAnimDecoder object, or NULL in case of
286 | // parsing error, invalid option or memory error.
287 | static WEBP_INLINE WebPAnimDecoder* WebPAnimDecoderNew(
288 | const WebPData* webp_data, const WebPAnimDecoderOptions* dec_options) {
289 | return WebPAnimDecoderNewInternal(webp_data, dec_options,
290 | WEBP_DEMUX_ABI_VERSION);
291 | }
292 |
293 | // Global information about the animation..
294 | struct WebPAnimInfo {
295 | uint32_t canvas_width;
296 | uint32_t canvas_height;
297 | uint32_t loop_count;
298 | uint32_t bgcolor;
299 | uint32_t frame_count;
300 | uint32_t pad[4]; // padding for later use
301 | };
302 |
303 | // Get global information about the animation.
304 | // Parameters:
305 | // dec - (in) decoder instance to get information from.
306 | // info - (out) global information fetched from the animation.
307 | // Returns:
308 | // True on success.
309 | WEBP_EXTERN int WebPAnimDecoderGetInfo(const WebPAnimDecoder* dec,
310 | WebPAnimInfo* info);
311 |
312 | // Fetch the next frame from 'dec' based on options supplied to
313 | // WebPAnimDecoderNew(). This will be a fully reconstructed canvas of size
314 | // 'canvas_width * 4 * canvas_height', and not just the frame sub-rectangle. The
315 | // returned buffer 'buf' is valid only until the next call to
316 | // WebPAnimDecoderGetNext(), WebPAnimDecoderReset() or WebPAnimDecoderDelete().
317 | // Parameters:
318 | // dec - (in/out) decoder instance from which the next frame is to be fetched.
319 | // buf - (out) decoded frame.
320 | // timestamp - (out) timestamp of the frame in milliseconds.
321 | // Returns:
322 | // False if any of the arguments are NULL, or if there is a parsing or
323 | // decoding error, or if there are no more frames. Otherwise, returns true.
324 | WEBP_EXTERN int WebPAnimDecoderGetNext(WebPAnimDecoder* dec,
325 | uint8_t** buf, int* timestamp);
326 |
327 | // Check if there are more frames left to decode.
328 | // Parameters:
329 | // dec - (in) decoder instance to be checked.
330 | // Returns:
331 | // True if 'dec' is not NULL and some frames are yet to be decoded.
332 | // Otherwise, returns false.
333 | WEBP_EXTERN int WebPAnimDecoderHasMoreFrames(const WebPAnimDecoder* dec);
334 |
335 | // Resets the WebPAnimDecoder object, so that next call to
336 | // WebPAnimDecoderGetNext() will restart decoding from 1st frame. This would be
337 | // helpful when all frames need to be decoded multiple times (e.g.
338 | // info.loop_count times) without destroying and recreating the 'dec' object.
339 | // Parameters:
340 | // dec - (in/out) decoder instance to be reset
341 | WEBP_EXTERN void WebPAnimDecoderReset(WebPAnimDecoder* dec);
342 |
343 | // Grab the internal demuxer object.
344 | // Getting the demuxer object can be useful if one wants to use operations only
345 | // available through demuxer; e.g. to get XMP/EXIF/ICC metadata. The returned
346 | // demuxer object is owned by 'dec' and is valid only until the next call to
347 | // WebPAnimDecoderDelete().
348 | //
349 | // Parameters:
350 | // dec - (in) decoder instance from which the demuxer object is to be fetched.
351 | WEBP_EXTERN const WebPDemuxer* WebPAnimDecoderGetDemuxer(
352 | const WebPAnimDecoder* dec);
353 |
354 | // Deletes the WebPAnimDecoder object.
355 | // Parameters:
356 | // dec - (in/out) decoder instance to be deleted
357 | WEBP_EXTERN void WebPAnimDecoderDelete(WebPAnimDecoder* dec);
358 |
359 | #ifdef __cplusplus
360 | } // extern "C"
361 | #endif
362 |
363 | #endif // WEBP_WEBP_DEMUX_H_
364 |
--------------------------------------------------------------------------------
/deps/libwebp/encode.h:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // WebP encoder: main interface
11 | //
12 | // Author: Skal (pascal.massimino@gmail.com)
13 |
14 | #ifndef WEBP_WEBP_ENCODE_H_
15 | #define WEBP_WEBP_ENCODE_H_
16 |
17 | #include "./types.h"
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif
22 |
23 | #define WEBP_ENCODER_ABI_VERSION 0x020e // MAJOR(8b) + MINOR(8b)
24 |
25 | // Note: forward declaring enumerations is not allowed in (strict) C and C++,
26 | // the types are left here for reference.
27 | // typedef enum WebPImageHint WebPImageHint;
28 | // typedef enum WebPEncCSP WebPEncCSP;
29 | // typedef enum WebPPreset WebPPreset;
30 | // typedef enum WebPEncodingError WebPEncodingError;
31 | typedef struct WebPConfig WebPConfig;
32 | typedef struct WebPPicture WebPPicture; // main structure for I/O
33 | typedef struct WebPAuxStats WebPAuxStats;
34 | typedef struct WebPMemoryWriter WebPMemoryWriter;
35 |
36 | // Return the encoder's version number, packed in hexadecimal using 8bits for
37 | // each of major/minor/revision. E.g: v2.5.7 is 0x020507.
38 | WEBP_EXTERN int WebPGetEncoderVersion(void);
39 |
40 | //------------------------------------------------------------------------------
41 | // One-stop-shop call! No questions asked:
42 |
43 | // Returns the size of the compressed data (pointed to by *output), or 0 if
44 | // an error occurred. The compressed data must be released by the caller
45 | // using the call 'WebPFree(*output)'.
46 | // These functions compress using the lossy format, and the quality_factor
47 | // can go from 0 (smaller output, lower quality) to 100 (best quality,
48 | // larger output).
49 | WEBP_EXTERN size_t WebPEncodeRGB(const uint8_t* rgb,
50 | int width, int height, int stride,
51 | float quality_factor, uint8_t** output);
52 | WEBP_EXTERN size_t WebPEncodeBGR(const uint8_t* bgr,
53 | int width, int height, int stride,
54 | float quality_factor, uint8_t** output);
55 | WEBP_EXTERN size_t WebPEncodeRGBA(const uint8_t* rgba,
56 | int width, int height, int stride,
57 | float quality_factor, uint8_t** output);
58 | WEBP_EXTERN size_t WebPEncodeBGRA(const uint8_t* bgra,
59 | int width, int height, int stride,
60 | float quality_factor, uint8_t** output);
61 |
62 | // These functions are the equivalent of the above, but compressing in a
63 | // lossless manner. Files are usually larger than lossy format, but will
64 | // not suffer any compression loss.
65 | WEBP_EXTERN size_t WebPEncodeLosslessRGB(const uint8_t* rgb,
66 | int width, int height, int stride,
67 | uint8_t** output);
68 | WEBP_EXTERN size_t WebPEncodeLosslessBGR(const uint8_t* bgr,
69 | int width, int height, int stride,
70 | uint8_t** output);
71 | WEBP_EXTERN size_t WebPEncodeLosslessRGBA(const uint8_t* rgba,
72 | int width, int height, int stride,
73 | uint8_t** output);
74 | WEBP_EXTERN size_t WebPEncodeLosslessBGRA(const uint8_t* bgra,
75 | int width, int height, int stride,
76 | uint8_t** output);
77 |
78 | // Releases memory returned by the WebPEncode*() functions above.
79 | WEBP_EXTERN void WebPFree(void* ptr);
80 |
81 | //------------------------------------------------------------------------------
82 | // Coding parameters
83 |
84 | // Image characteristics hint for the underlying encoder.
85 | typedef enum WebPImageHint {
86 | WEBP_HINT_DEFAULT = 0, // default preset.
87 | WEBP_HINT_PICTURE, // digital picture, like portrait, inner shot
88 | WEBP_HINT_PHOTO, // outdoor photograph, with natural lighting
89 | WEBP_HINT_GRAPH, // Discrete tone image (graph, map-tile etc).
90 | WEBP_HINT_LAST
91 | } WebPImageHint;
92 |
93 | // Compression parameters.
94 | struct WebPConfig {
95 | int lossless; // Lossless encoding (0=lossy(default), 1=lossless).
96 | float quality; // between 0 and 100. For lossy, 0 gives the smallest
97 | // size and 100 the largest. For lossless, this
98 | // parameter is the amount of effort put into the
99 | // compression: 0 is the fastest but gives larger
100 | // files compared to the slowest, but best, 100.
101 | int method; // quality/speed trade-off (0=fast, 6=slower-better)
102 |
103 | WebPImageHint image_hint; // Hint for image type (lossless only for now).
104 |
105 | int target_size; // if non-zero, set the desired target size in bytes.
106 | // Takes precedence over the 'compression' parameter.
107 | float target_PSNR; // if non-zero, specifies the minimal distortion to
108 | // try to achieve. Takes precedence over target_size.
109 | int segments; // maximum number of segments to use, in [1..4]
110 | int sns_strength; // Spatial Noise Shaping. 0=off, 100=maximum.
111 | int filter_strength; // range: [0 = off .. 100 = strongest]
112 | int filter_sharpness; // range: [0 = off .. 7 = least sharp]
113 | int filter_type; // filtering type: 0 = simple, 1 = strong (only used
114 | // if filter_strength > 0 or autofilter > 0)
115 | int autofilter; // Auto adjust filter's strength [0 = off, 1 = on]
116 | int alpha_compression; // Algorithm for encoding the alpha plane (0 = none,
117 | // 1 = compressed with WebP lossless). Default is 1.
118 | int alpha_filtering; // Predictive filtering method for alpha plane.
119 | // 0: none, 1: fast, 2: best. Default if 1.
120 | int alpha_quality; // Between 0 (smallest size) and 100 (lossless).
121 | // Default is 100.
122 | int pass; // number of entropy-analysis passes (in [1..10]).
123 |
124 | int show_compressed; // if true, export the compressed picture back.
125 | // In-loop filtering is not applied.
126 | int preprocessing; // preprocessing filter:
127 | // 0=none, 1=segment-smooth, 2=pseudo-random dithering
128 | int partitions; // log2(number of token partitions) in [0..3]. Default
129 | // is set to 0 for easier progressive decoding.
130 | int partition_limit; // quality degradation allowed to fit the 512k limit
131 | // on prediction modes coding (0: no degradation,
132 | // 100: maximum possible degradation).
133 | int emulate_jpeg_size; // If true, compression parameters will be remapped
134 | // to better match the expected output size from
135 | // JPEG compression. Generally, the output size will
136 | // be similar but the degradation will be lower.
137 | int thread_level; // If non-zero, try and use multi-threaded encoding.
138 | int low_memory; // If set, reduce memory usage (but increase CPU use).
139 |
140 | int near_lossless; // Near lossless encoding [0 = max loss .. 100 = off
141 | // (default)].
142 | int exact; // if non-zero, preserve the exact RGB values under
143 | // transparent area. Otherwise, discard this invisible
144 | // RGB information for better compression. The default
145 | // value is 0.
146 |
147 | int use_delta_palette; // reserved for future lossless feature
148 | int use_sharp_yuv; // if needed, use sharp (and slow) RGB->YUV conversion
149 |
150 | uint32_t pad[2]; // padding for later use
151 | };
152 |
153 | // Enumerate some predefined settings for WebPConfig, depending on the type
154 | // of source picture. These presets are used when calling WebPConfigPreset().
155 | typedef enum WebPPreset {
156 | WEBP_PRESET_DEFAULT = 0, // default preset.
157 | WEBP_PRESET_PICTURE, // digital picture, like portrait, inner shot
158 | WEBP_PRESET_PHOTO, // outdoor photograph, with natural lighting
159 | WEBP_PRESET_DRAWING, // hand or line drawing, with high-contrast details
160 | WEBP_PRESET_ICON, // small-sized colorful images
161 | WEBP_PRESET_TEXT // text-like
162 | } WebPPreset;
163 |
164 | // Internal, version-checked, entry point
165 | WEBP_EXTERN int WebPConfigInitInternal(WebPConfig*, WebPPreset, float, int);
166 |
167 | // Should always be called, to initialize a fresh WebPConfig structure before
168 | // modification. Returns false in case of version mismatch. WebPConfigInit()
169 | // must have succeeded before using the 'config' object.
170 | // Note that the default values are lossless=0 and quality=75.
171 | static WEBP_INLINE int WebPConfigInit(WebPConfig* config) {
172 | return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f,
173 | WEBP_ENCODER_ABI_VERSION);
174 | }
175 |
176 | // This function will initialize the configuration according to a predefined
177 | // set of parameters (referred to by 'preset') and a given quality factor.
178 | // This function can be called as a replacement to WebPConfigInit(). Will
179 | // return false in case of error.
180 | static WEBP_INLINE int WebPConfigPreset(WebPConfig* config,
181 | WebPPreset preset, float quality) {
182 | return WebPConfigInitInternal(config, preset, quality,
183 | WEBP_ENCODER_ABI_VERSION);
184 | }
185 |
186 | // Activate the lossless compression mode with the desired efficiency level
187 | // between 0 (fastest, lowest compression) and 9 (slower, best compression).
188 | // A good default level is '6', providing a fair tradeoff between compression
189 | // speed and final compressed size.
190 | // This function will overwrite several fields from config: 'method', 'quality'
191 | // and 'lossless'. Returns false in case of parameter error.
192 | WEBP_EXTERN int WebPConfigLosslessPreset(WebPConfig* config, int level);
193 |
194 | // Returns true if 'config' is non-NULL and all configuration parameters are
195 | // within their valid ranges.
196 | WEBP_EXTERN int WebPValidateConfig(const WebPConfig* config);
197 |
198 | //------------------------------------------------------------------------------
199 | // Input / Output
200 | // Structure for storing auxiliary statistics.
201 |
202 | struct WebPAuxStats {
203 | int coded_size; // final size
204 |
205 | float PSNR[5]; // peak-signal-to-noise ratio for Y/U/V/All/Alpha
206 | int block_count[3]; // number of intra4/intra16/skipped macroblocks
207 | int header_bytes[2]; // approximate number of bytes spent for header
208 | // and mode-partition #0
209 | int residual_bytes[3][4]; // approximate number of bytes spent for
210 | // DC/AC/uv coefficients for each (0..3) segments.
211 | int segment_size[4]; // number of macroblocks in each segments
212 | int segment_quant[4]; // quantizer values for each segments
213 | int segment_level[4]; // filtering strength for each segments [0..63]
214 |
215 | int alpha_data_size; // size of the transparency data
216 | int layer_data_size; // size of the enhancement layer data
217 |
218 | // lossless encoder statistics
219 | uint32_t lossless_features; // bit0:predictor bit1:cross-color transform
220 | // bit2:subtract-green bit3:color indexing
221 | int histogram_bits; // number of precision bits of histogram
222 | int transform_bits; // precision bits for transform
223 | int cache_bits; // number of bits for color cache lookup
224 | int palette_size; // number of color in palette, if used
225 | int lossless_size; // final lossless size
226 | int lossless_hdr_size; // lossless header (transform, huffman etc) size
227 | int lossless_data_size; // lossless image data size
228 |
229 | uint32_t pad[2]; // padding for later use
230 | };
231 |
232 | // Signature for output function. Should return true if writing was successful.
233 | // data/data_size is the segment of data to write, and 'picture' is for
234 | // reference (and so one can make use of picture->custom_ptr).
235 | typedef int (*WebPWriterFunction)(const uint8_t* data, size_t data_size,
236 | const WebPPicture* picture);
237 |
238 | // WebPMemoryWrite: a special WebPWriterFunction that writes to memory using
239 | // the following WebPMemoryWriter object (to be set as a custom_ptr).
240 | struct WebPMemoryWriter {
241 | uint8_t* mem; // final buffer (of size 'max_size', larger than 'size').
242 | size_t size; // final size
243 | size_t max_size; // total capacity
244 | uint32_t pad[1]; // padding for later use
245 | };
246 |
247 | // The following must be called first before any use.
248 | WEBP_EXTERN void WebPMemoryWriterInit(WebPMemoryWriter* writer);
249 |
250 | // The following must be called to deallocate writer->mem memory. The 'writer'
251 | // object itself is not deallocated.
252 | WEBP_EXTERN void WebPMemoryWriterClear(WebPMemoryWriter* writer);
253 | // The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon
254 | // completion, writer.mem and writer.size will hold the coded data.
255 | // writer.mem must be freed by calling WebPMemoryWriterClear.
256 | WEBP_EXTERN int WebPMemoryWrite(const uint8_t* data, size_t data_size,
257 | const WebPPicture* picture);
258 |
259 | // Progress hook, called from time to time to report progress. It can return
260 | // false to request an abort of the encoding process, or true otherwise if
261 | // everything is OK.
262 | typedef int (*WebPProgressHook)(int percent, const WebPPicture* picture);
263 |
264 | // Color spaces.
265 | typedef enum WebPEncCSP {
266 | // chroma sampling
267 | WEBP_YUV420 = 0, // 4:2:0
268 | WEBP_YUV420A = 4, // alpha channel variant
269 | WEBP_CSP_UV_MASK = 3, // bit-mask to get the UV sampling factors
270 | WEBP_CSP_ALPHA_BIT = 4 // bit that is set if alpha is present
271 | } WebPEncCSP;
272 |
273 | // Encoding error conditions.
274 | typedef enum WebPEncodingError {
275 | VP8_ENC_OK = 0,
276 | VP8_ENC_ERROR_OUT_OF_MEMORY, // memory error allocating objects
277 | VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY, // memory error while flushing bits
278 | VP8_ENC_ERROR_NULL_PARAMETER, // a pointer parameter is NULL
279 | VP8_ENC_ERROR_INVALID_CONFIGURATION, // configuration is invalid
280 | VP8_ENC_ERROR_BAD_DIMENSION, // picture has invalid width/height
281 | VP8_ENC_ERROR_PARTITION0_OVERFLOW, // partition is bigger than 512k
282 | VP8_ENC_ERROR_PARTITION_OVERFLOW, // partition is bigger than 16M
283 | VP8_ENC_ERROR_BAD_WRITE, // error while flushing bytes
284 | VP8_ENC_ERROR_FILE_TOO_BIG, // file is bigger than 4G
285 | VP8_ENC_ERROR_USER_ABORT, // abort request by user
286 | VP8_ENC_ERROR_LAST // list terminator. always last.
287 | } WebPEncodingError;
288 |
289 | // maximum width/height allowed (inclusive), in pixels
290 | #define WEBP_MAX_DIMENSION 16383
291 |
292 | // Main exchange structure (input samples, output bytes, statistics)
293 | struct WebPPicture {
294 | // INPUT
295 | //////////////
296 | // Main flag for encoder selecting between ARGB or YUV input.
297 | // It is recommended to use ARGB input (*argb, argb_stride) for lossless
298 | // compression, and YUV input (*y, *u, *v, etc.) for lossy compression
299 | // since these are the respective native colorspace for these formats.
300 | int use_argb;
301 |
302 | // YUV input (mostly used for input to lossy compression)
303 | WebPEncCSP colorspace; // colorspace: should be YUV420 for now (=Y'CbCr).
304 | int width, height; // dimensions (less or equal to WEBP_MAX_DIMENSION)
305 | uint8_t *y, *u, *v; // pointers to luma/chroma planes.
306 | int y_stride, uv_stride; // luma/chroma strides.
307 | uint8_t* a; // pointer to the alpha plane
308 | int a_stride; // stride of the alpha plane
309 | uint32_t pad1[2]; // padding for later use
310 |
311 | // ARGB input (mostly used for input to lossless compression)
312 | uint32_t* argb; // Pointer to argb (32 bit) plane.
313 | int argb_stride; // This is stride in pixels units, not bytes.
314 | uint32_t pad2[3]; // padding for later use
315 |
316 | // OUTPUT
317 | ///////////////
318 | // Byte-emission hook, to store compressed bytes as they are ready.
319 | WebPWriterFunction writer; // can be NULL
320 | void* custom_ptr; // can be used by the writer.
321 |
322 | // map for extra information (only for lossy compression mode)
323 | int extra_info_type; // 1: intra type, 2: segment, 3: quant
324 | // 4: intra-16 prediction mode,
325 | // 5: chroma prediction mode,
326 | // 6: bit cost, 7: distortion
327 | uint8_t* extra_info; // if not NULL, points to an array of size
328 | // ((width + 15) / 16) * ((height + 15) / 16) that
329 | // will be filled with a macroblock map, depending
330 | // on extra_info_type.
331 |
332 | // STATS AND REPORTS
333 | ///////////////////////////
334 | // Pointer to side statistics (updated only if not NULL)
335 | WebPAuxStats* stats;
336 |
337 | // Error code for the latest error encountered during encoding
338 | WebPEncodingError error_code;
339 |
340 | // If not NULL, report progress during encoding.
341 | WebPProgressHook progress_hook;
342 |
343 | void* user_data; // this field is free to be set to any value and
344 | // used during callbacks (like progress-report e.g.).
345 |
346 | uint32_t pad3[3]; // padding for later use
347 |
348 | // Unused for now
349 | uint8_t *pad4, *pad5;
350 | uint32_t pad6[8]; // padding for later use
351 |
352 | // PRIVATE FIELDS
353 | ////////////////////
354 | void* memory_; // row chunk of memory for yuva planes
355 | void* memory_argb_; // and for argb too.
356 | void* pad7[2]; // padding for later use
357 | };
358 |
359 | // Internal, version-checked, entry point
360 | WEBP_EXTERN int WebPPictureInitInternal(WebPPicture*, int);
361 |
362 | // Should always be called, to initialize the structure. Returns false in case
363 | // of version mismatch. WebPPictureInit() must have succeeded before using the
364 | // 'picture' object.
365 | // Note that, by default, use_argb is false and colorspace is WEBP_YUV420.
366 | static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) {
367 | return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION);
368 | }
369 |
370 | //------------------------------------------------------------------------------
371 | // WebPPicture utils
372 |
373 | // Convenience allocation / deallocation based on picture->width/height:
374 | // Allocate y/u/v buffers as per colorspace/width/height specification.
375 | // Note! This function will free the previous buffer if needed.
376 | // Returns false in case of memory error.
377 | WEBP_EXTERN int WebPPictureAlloc(WebPPicture* picture);
378 |
379 | // Release the memory allocated by WebPPictureAlloc() or WebPPictureImport*().
380 | // Note that this function does _not_ free the memory used by the 'picture'
381 | // object itself.
382 | // Besides memory (which is reclaimed) all other fields of 'picture' are
383 | // preserved.
384 | WEBP_EXTERN void WebPPictureFree(WebPPicture* picture);
385 |
386 | // Copy the pixels of *src into *dst, using WebPPictureAlloc. Upon return, *dst
387 | // will fully own the copied pixels (this is not a view). The 'dst' picture need
388 | // not be initialized as its content is overwritten.
389 | // Returns false in case of memory allocation error.
390 | WEBP_EXTERN int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst);
391 |
392 | // Compute the single distortion for packed planes of samples.
393 | // 'src' will be compared to 'ref', and the raw distortion stored into
394 | // '*distortion'. The refined metric (log(MSE), log(1 - ssim),...' will be
395 | // stored in '*result'.
396 | // 'x_step' is the horizontal stride (in bytes) between samples.
397 | // 'src/ref_stride' is the byte distance between rows.
398 | // Returns false in case of error (bad parameter, memory allocation error, ...).
399 | WEBP_EXTERN int WebPPlaneDistortion(const uint8_t* src, size_t src_stride,
400 | const uint8_t* ref, size_t ref_stride,
401 | int width, int height,
402 | size_t x_step,
403 | int type, // 0 = PSNR, 1 = SSIM, 2 = LSIM
404 | float* distortion, float* result);
405 |
406 | // Compute PSNR, SSIM or LSIM distortion metric between two pictures. Results
407 | // are in dB, stored in result[] in the B/G/R/A/All order. The distortion is
408 | // always performed using ARGB samples. Hence if the input is YUV(A), the
409 | // picture will be internally converted to ARGB (just for the measurement).
410 | // Warning: this function is rather CPU-intensive.
411 | WEBP_EXTERN int WebPPictureDistortion(
412 | const WebPPicture* src, const WebPPicture* ref,
413 | int metric_type, // 0 = PSNR, 1 = SSIM, 2 = LSIM
414 | float result[5]);
415 |
416 | // self-crops a picture to the rectangle defined by top/left/width/height.
417 | // Returns false in case of memory allocation error, or if the rectangle is
418 | // outside of the source picture.
419 | // The rectangle for the view is defined by the top-left corner pixel
420 | // coordinates (left, top) as well as its width and height. This rectangle
421 | // must be fully be comprised inside the 'src' source picture. If the source
422 | // picture uses the YUV420 colorspace, the top and left coordinates will be
423 | // snapped to even values.
424 | WEBP_EXTERN int WebPPictureCrop(WebPPicture* picture,
425 | int left, int top, int width, int height);
426 |
427 | // Extracts a view from 'src' picture into 'dst'. The rectangle for the view
428 | // is defined by the top-left corner pixel coordinates (left, top) as well
429 | // as its width and height. This rectangle must be fully be comprised inside
430 | // the 'src' source picture. If the source picture uses the YUV420 colorspace,
431 | // the top and left coordinates will be snapped to even values.
432 | // Picture 'src' must out-live 'dst' picture. Self-extraction of view is allowed
433 | // ('src' equal to 'dst') as a mean of fast-cropping (but note that doing so,
434 | // the original dimension will be lost). Picture 'dst' need not be initialized
435 | // with WebPPictureInit() if it is different from 'src', since its content will
436 | // be overwritten.
437 | // Returns false in case of memory allocation error or invalid parameters.
438 | WEBP_EXTERN int WebPPictureView(const WebPPicture* src,
439 | int left, int top, int width, int height,
440 | WebPPicture* dst);
441 |
442 | // Returns true if the 'picture' is actually a view and therefore does
443 | // not own the memory for pixels.
444 | WEBP_EXTERN int WebPPictureIsView(const WebPPicture* picture);
445 |
446 | // Rescale a picture to new dimension width x height.
447 | // If either 'width' or 'height' (but not both) is 0 the corresponding
448 | // dimension will be calculated preserving the aspect ratio.
449 | // No gamma correction is applied.
450 | // Returns false in case of error (invalid parameter or insufficient memory).
451 | WEBP_EXTERN int WebPPictureRescale(WebPPicture* pic, int width, int height);
452 |
453 | // Colorspace conversion function to import RGB samples.
454 | // Previous buffer will be free'd, if any.
455 | // *rgb buffer should have a size of at least height * rgb_stride.
456 | // Returns false in case of memory error.
457 | WEBP_EXTERN int WebPPictureImportRGB(
458 | WebPPicture* picture, const uint8_t* rgb, int rgb_stride);
459 | // Same, but for RGBA buffer.
460 | WEBP_EXTERN int WebPPictureImportRGBA(
461 | WebPPicture* picture, const uint8_t* rgba, int rgba_stride);
462 | // Same, but for RGBA buffer. Imports the RGB direct from the 32-bit format
463 | // input buffer ignoring the alpha channel. Avoids needing to copy the data
464 | // to a temporary 24-bit RGB buffer to import the RGB only.
465 | WEBP_EXTERN int WebPPictureImportRGBX(
466 | WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride);
467 |
468 | // Variants of the above, but taking BGR(A|X) input.
469 | WEBP_EXTERN int WebPPictureImportBGR(
470 | WebPPicture* picture, const uint8_t* bgr, int bgr_stride);
471 | WEBP_EXTERN int WebPPictureImportBGRA(
472 | WebPPicture* picture, const uint8_t* bgra, int bgra_stride);
473 | WEBP_EXTERN int WebPPictureImportBGRX(
474 | WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride);
475 |
476 | // Converts picture->argb data to the YUV420A format. The 'colorspace'
477 | // parameter is deprecated and should be equal to WEBP_YUV420.
478 | // Upon return, picture->use_argb is set to false. The presence of real
479 | // non-opaque transparent values is detected, and 'colorspace' will be
480 | // adjusted accordingly. Note that this method is lossy.
481 | // Returns false in case of error.
482 | WEBP_EXTERN int WebPPictureARGBToYUVA(WebPPicture* picture,
483 | WebPEncCSP /*colorspace = WEBP_YUV420*/);
484 |
485 | // Same as WebPPictureARGBToYUVA(), but the conversion is done using
486 | // pseudo-random dithering with a strength 'dithering' between
487 | // 0.0 (no dithering) and 1.0 (maximum dithering). This is useful
488 | // for photographic picture.
489 | WEBP_EXTERN int WebPPictureARGBToYUVADithered(
490 | WebPPicture* picture, WebPEncCSP colorspace, float dithering);
491 |
492 | // Performs 'sharp' RGBA->YUVA420 downsampling and colorspace conversion.
493 | // Downsampling is handled with extra care in case of color clipping. This
494 | // method is roughly 2x slower than WebPPictureARGBToYUVA() but produces better
495 | // and sharper YUV representation.
496 | // Returns false in case of error.
497 | WEBP_EXTERN int WebPPictureSharpARGBToYUVA(WebPPicture* picture);
498 | // kept for backward compatibility:
499 | WEBP_EXTERN int WebPPictureSmartARGBToYUVA(WebPPicture* picture);
500 |
501 | // Converts picture->yuv to picture->argb and sets picture->use_argb to true.
502 | // The input format must be YUV_420 or YUV_420A. The conversion from YUV420 to
503 | // ARGB incurs a small loss too.
504 | // Note that the use of this colorspace is discouraged if one has access to the
505 | // raw ARGB samples, since using YUV420 is comparatively lossy.
506 | // Returns false in case of error.
507 | WEBP_EXTERN int WebPPictureYUVAToARGB(WebPPicture* picture);
508 |
509 | // Helper function: given a width x height plane of RGBA or YUV(A) samples
510 | // clean-up or smoothen the YUV or RGB samples under fully transparent area,
511 | // to help compressibility (no guarantee, though).
512 | WEBP_EXTERN void WebPCleanupTransparentArea(WebPPicture* picture);
513 |
514 | // Scan the picture 'picture' for the presence of non fully opaque alpha values.
515 | // Returns true in such case. Otherwise returns false (indicating that the
516 | // alpha plane can be ignored altogether e.g.).
517 | WEBP_EXTERN int WebPPictureHasTransparency(const WebPPicture* picture);
518 |
519 | // Remove the transparency information (if present) by blending the color with
520 | // the background color 'background_rgb' (specified as 24bit RGB triplet).
521 | // After this call, all alpha values are reset to 0xff.
522 | WEBP_EXTERN void WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb);
523 |
524 | //------------------------------------------------------------------------------
525 | // Main call
526 |
527 | // Main encoding call, after config and picture have been initialized.
528 | // 'picture' must be less than 16384x16384 in dimension (cf WEBP_MAX_DIMENSION),
529 | // and the 'config' object must be a valid one.
530 | // Returns false in case of error, true otherwise.
531 | // In case of error, picture->error_code is updated accordingly.
532 | // 'picture' can hold the source samples in both YUV(A) or ARGB input, depending
533 | // on the value of 'picture->use_argb'. It is highly recommended to use
534 | // the former for lossy encoding, and the latter for lossless encoding
535 | // (when config.lossless is true). Automatic conversion from one format to
536 | // another is provided but they both incur some loss.
537 | WEBP_EXTERN int WebPEncode(const WebPConfig* config, WebPPicture* picture);
538 |
539 | //------------------------------------------------------------------------------
540 |
541 | #ifdef __cplusplus
542 | } // extern "C"
543 | #endif
544 |
545 | #endif // WEBP_WEBP_ENCODE_H_
546 |
--------------------------------------------------------------------------------
/deps/libwebp/format_constants.h:
--------------------------------------------------------------------------------
1 | // Copyright 2012 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // Internal header for constants related to WebP file format.
11 | //
12 | // Author: Urvang (urvang@google.com)
13 |
14 | #ifndef WEBP_WEBP_FORMAT_CONSTANTS_H_
15 | #define WEBP_WEBP_FORMAT_CONSTANTS_H_
16 |
17 | // Create fourcc of the chunk from the chunk tag characters.
18 | #define MKFOURCC(a, b, c, d) ((a) | (b) << 8 | (c) << 16 | (uint32_t)(d) << 24)
19 |
20 | // VP8 related constants.
21 | #define VP8_SIGNATURE 0x9d012a // Signature in VP8 data.
22 | #define VP8_MAX_PARTITION0_SIZE (1 << 19) // max size of mode partition
23 | #define VP8_MAX_PARTITION_SIZE (1 << 24) // max size for token partition
24 | #define VP8_FRAME_HEADER_SIZE 10 // Size of the frame header within VP8 data.
25 |
26 | // VP8L related constants.
27 | #define VP8L_SIGNATURE_SIZE 1 // VP8L signature size.
28 | #define VP8L_MAGIC_BYTE 0x2f // VP8L signature byte.
29 | #define VP8L_IMAGE_SIZE_BITS 14 // Number of bits used to store
30 | // width and height.
31 | #define VP8L_VERSION_BITS 3 // 3 bits reserved for version.
32 | #define VP8L_VERSION 0 // version 0
33 | #define VP8L_FRAME_HEADER_SIZE 5 // Size of the VP8L frame header.
34 |
35 | #define MAX_PALETTE_SIZE 256
36 | #define MAX_CACHE_BITS 11
37 | #define HUFFMAN_CODES_PER_META_CODE 5
38 | #define ARGB_BLACK 0xff000000
39 |
40 | #define DEFAULT_CODE_LENGTH 8
41 | #define MAX_ALLOWED_CODE_LENGTH 15
42 |
43 | #define NUM_LITERAL_CODES 256
44 | #define NUM_LENGTH_CODES 24
45 | #define NUM_DISTANCE_CODES 40
46 | #define CODE_LENGTH_CODES 19
47 |
48 | #define MIN_HUFFMAN_BITS 2 // min number of Huffman bits
49 | #define MAX_HUFFMAN_BITS 9 // max number of Huffman bits
50 |
51 | #define TRANSFORM_PRESENT 1 // The bit to be written when next data
52 | // to be read is a transform.
53 | #define NUM_TRANSFORMS 4 // Maximum number of allowed transform
54 | // in a bitstream.
55 | typedef enum {
56 | PREDICTOR_TRANSFORM = 0,
57 | CROSS_COLOR_TRANSFORM = 1,
58 | SUBTRACT_GREEN = 2,
59 | COLOR_INDEXING_TRANSFORM = 3
60 | } VP8LImageTransformType;
61 |
62 | // Alpha related constants.
63 | #define ALPHA_HEADER_LEN 1
64 | #define ALPHA_NO_COMPRESSION 0
65 | #define ALPHA_LOSSLESS_COMPRESSION 1
66 | #define ALPHA_PREPROCESSED_LEVELS 1
67 |
68 | // Mux related constants.
69 | #define TAG_SIZE 4 // Size of a chunk tag (e.g. "VP8L").
70 | #define CHUNK_SIZE_BYTES 4 // Size needed to store chunk's size.
71 | #define CHUNK_HEADER_SIZE 8 // Size of a chunk header.
72 | #define RIFF_HEADER_SIZE 12 // Size of the RIFF header ("RIFFnnnnWEBP").
73 | #define ANMF_CHUNK_SIZE 16 // Size of an ANMF chunk.
74 | #define ANIM_CHUNK_SIZE 6 // Size of an ANIM chunk.
75 | #define VP8X_CHUNK_SIZE 10 // Size of a VP8X chunk.
76 |
77 | #define MAX_CANVAS_SIZE (1 << 24) // 24-bit max for VP8X width/height.
78 | #define MAX_IMAGE_AREA (1ULL << 32) // 32-bit max for width x height.
79 | #define MAX_LOOP_COUNT (1 << 16) // maximum value for loop-count
80 | #define MAX_DURATION (1 << 24) // maximum duration
81 | #define MAX_POSITION_OFFSET (1 << 24) // maximum frame x/y offset
82 |
83 | // Maximum chunk payload is such that adding the header and padding won't
84 | // overflow a uint32_t.
85 | #define MAX_CHUNK_PAYLOAD (~0U - CHUNK_HEADER_SIZE - 1)
86 |
87 | #endif // WEBP_WEBP_FORMAT_CONSTANTS_H_
88 |
--------------------------------------------------------------------------------
/deps/libwebp/libwebp.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nyx0uf/qlImageSize/41082059f6b0d57609a60aa27b7127552e17708f/deps/libwebp/libwebp.a
--------------------------------------------------------------------------------
/deps/libwebp/mux.h:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // RIFF container manipulation and encoding for WebP images.
11 | //
12 | // Authors: Urvang (urvang@google.com)
13 | // Vikas (vikasa@google.com)
14 |
15 | #ifndef WEBP_WEBP_MUX_H_
16 | #define WEBP_WEBP_MUX_H_
17 |
18 | #include "./mux_types.h"
19 |
20 | #ifdef __cplusplus
21 | extern "C" {
22 | #endif
23 |
24 | #define WEBP_MUX_ABI_VERSION 0x0108 // MAJOR(8b) + MINOR(8b)
25 |
26 | //------------------------------------------------------------------------------
27 | // Mux API
28 | //
29 | // This API allows manipulation of WebP container images containing features
30 | // like color profile, metadata, animation.
31 | //
32 | // Code Example#1: Create a WebPMux object with image data, color profile and
33 | // XMP metadata.
34 | /*
35 | int copy_data = 0;
36 | WebPMux* mux = WebPMuxNew();
37 | // ... (Prepare image data).
38 | WebPMuxSetImage(mux, &image, copy_data);
39 | // ... (Prepare ICCP color profile data).
40 | WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
41 | // ... (Prepare XMP metadata).
42 | WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
43 | // Get data from mux in WebP RIFF format.
44 | WebPMuxAssemble(mux, &output_data);
45 | WebPMuxDelete(mux);
46 | // ... (Consume output_data; e.g. write output_data.bytes to file).
47 | WebPDataClear(&output_data);
48 | */
49 |
50 | // Code Example#2: Get image and color profile data from a WebP file.
51 | /*
52 | int copy_data = 0;
53 | // ... (Read data from file).
54 | WebPMux* mux = WebPMuxCreate(&data, copy_data);
55 | WebPMuxGetFrame(mux, 1, &image);
56 | // ... (Consume image; e.g. call WebPDecode() to decode the data).
57 | WebPMuxGetChunk(mux, "ICCP", &icc_profile);
58 | // ... (Consume icc_data).
59 | WebPMuxDelete(mux);
60 | free(data);
61 | */
62 |
63 | // Note: forward declaring enumerations is not allowed in (strict) C and C++,
64 | // the types are left here for reference.
65 | // typedef enum WebPMuxError WebPMuxError;
66 | // typedef enum WebPChunkId WebPChunkId;
67 | typedef struct WebPMux WebPMux; // main opaque object.
68 | typedef struct WebPMuxFrameInfo WebPMuxFrameInfo;
69 | typedef struct WebPMuxAnimParams WebPMuxAnimParams;
70 | typedef struct WebPAnimEncoderOptions WebPAnimEncoderOptions;
71 |
72 | // Error codes
73 | typedef enum WebPMuxError {
74 | WEBP_MUX_OK = 1,
75 | WEBP_MUX_NOT_FOUND = 0,
76 | WEBP_MUX_INVALID_ARGUMENT = -1,
77 | WEBP_MUX_BAD_DATA = -2,
78 | WEBP_MUX_MEMORY_ERROR = -3,
79 | WEBP_MUX_NOT_ENOUGH_DATA = -4
80 | } WebPMuxError;
81 |
82 | // IDs for different types of chunks.
83 | typedef enum WebPChunkId {
84 | WEBP_CHUNK_VP8X, // VP8X
85 | WEBP_CHUNK_ICCP, // ICCP
86 | WEBP_CHUNK_ANIM, // ANIM
87 | WEBP_CHUNK_ANMF, // ANMF
88 | WEBP_CHUNK_DEPRECATED, // (deprecated from FRGM)
89 | WEBP_CHUNK_ALPHA, // ALPH
90 | WEBP_CHUNK_IMAGE, // VP8/VP8L
91 | WEBP_CHUNK_EXIF, // EXIF
92 | WEBP_CHUNK_XMP, // XMP
93 | WEBP_CHUNK_UNKNOWN, // Other chunks.
94 | WEBP_CHUNK_NIL
95 | } WebPChunkId;
96 |
97 | //------------------------------------------------------------------------------
98 |
99 | // Returns the version number of the mux library, packed in hexadecimal using
100 | // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.
101 | WEBP_EXTERN int WebPGetMuxVersion(void);
102 |
103 | //------------------------------------------------------------------------------
104 | // Life of a Mux object
105 |
106 | // Internal, version-checked, entry point
107 | WEBP_EXTERN WebPMux* WebPNewInternal(int);
108 |
109 | // Creates an empty mux object.
110 | // Returns:
111 | // A pointer to the newly created empty mux object.
112 | // Or NULL in case of memory error.
113 | static WEBP_INLINE WebPMux* WebPMuxNew(void) {
114 | return WebPNewInternal(WEBP_MUX_ABI_VERSION);
115 | }
116 |
117 | // Deletes the mux object.
118 | // Parameters:
119 | // mux - (in/out) object to be deleted
120 | WEBP_EXTERN void WebPMuxDelete(WebPMux* mux);
121 |
122 | //------------------------------------------------------------------------------
123 | // Mux creation.
124 |
125 | // Internal, version-checked, entry point
126 | WEBP_EXTERN WebPMux* WebPMuxCreateInternal(const WebPData*, int, int);
127 |
128 | // Creates a mux object from raw data given in WebP RIFF format.
129 | // Parameters:
130 | // bitstream - (in) the bitstream data in WebP RIFF format
131 | // copy_data - (in) value 1 indicates given data WILL be copied to the mux
132 | // object and value 0 indicates data will NOT be copied.
133 | // Returns:
134 | // A pointer to the mux object created from given data - on success.
135 | // NULL - In case of invalid data or memory error.
136 | static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* bitstream,
137 | int copy_data) {
138 | return WebPMuxCreateInternal(bitstream, copy_data, WEBP_MUX_ABI_VERSION);
139 | }
140 |
141 | //------------------------------------------------------------------------------
142 | // Non-image chunks.
143 |
144 | // Note: Only non-image related chunks should be managed through chunk APIs.
145 | // (Image related chunks are: "ANMF", "VP8 ", "VP8L" and "ALPH").
146 | // To add, get and delete images, use WebPMuxSetImage(), WebPMuxPushFrame(),
147 | // WebPMuxGetFrame() and WebPMuxDeleteFrame().
148 |
149 | // Adds a chunk with id 'fourcc' and data 'chunk_data' in the mux object.
150 | // Any existing chunk(s) with the same id will be removed.
151 | // Parameters:
152 | // mux - (in/out) object to which the chunk is to be added
153 | // fourcc - (in) a character array containing the fourcc of the given chunk;
154 | // e.g., "ICCP", "XMP ", "EXIF" etc.
155 | // chunk_data - (in) the chunk data to be added
156 | // copy_data - (in) value 1 indicates given data WILL be copied to the mux
157 | // object and value 0 indicates data will NOT be copied.
158 | // Returns:
159 | // WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL
160 | // or if fourcc corresponds to an image chunk.
161 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error.
162 | // WEBP_MUX_OK - on success.
163 | WEBP_EXTERN WebPMuxError WebPMuxSetChunk(
164 | WebPMux* mux, const char fourcc[4], const WebPData* chunk_data,
165 | int copy_data);
166 |
167 | // Gets a reference to the data of the chunk with id 'fourcc' in the mux object.
168 | // The caller should NOT free the returned data.
169 | // Parameters:
170 | // mux - (in) object from which the chunk data is to be fetched
171 | // fourcc - (in) a character array containing the fourcc of the chunk;
172 | // e.g., "ICCP", "XMP ", "EXIF" etc.
173 | // chunk_data - (out) returned chunk data
174 | // Returns:
175 | // WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL
176 | // or if fourcc corresponds to an image chunk.
177 | // WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given id.
178 | // WEBP_MUX_OK - on success.
179 | WEBP_EXTERN WebPMuxError WebPMuxGetChunk(
180 | const WebPMux* mux, const char fourcc[4], WebPData* chunk_data);
181 |
182 | // Deletes the chunk with the given 'fourcc' from the mux object.
183 | // Parameters:
184 | // mux - (in/out) object from which the chunk is to be deleted
185 | // fourcc - (in) a character array containing the fourcc of the chunk;
186 | // e.g., "ICCP", "XMP ", "EXIF" etc.
187 | // Returns:
188 | // WEBP_MUX_INVALID_ARGUMENT - if mux or fourcc is NULL
189 | // or if fourcc corresponds to an image chunk.
190 | // WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given fourcc.
191 | // WEBP_MUX_OK - on success.
192 | WEBP_EXTERN WebPMuxError WebPMuxDeleteChunk(
193 | WebPMux* mux, const char fourcc[4]);
194 |
195 | //------------------------------------------------------------------------------
196 | // Images.
197 |
198 | // Encapsulates data about a single frame.
199 | struct WebPMuxFrameInfo {
200 | WebPData bitstream; // image data: can be a raw VP8/VP8L bitstream
201 | // or a single-image WebP file.
202 | int x_offset; // x-offset of the frame.
203 | int y_offset; // y-offset of the frame.
204 | int duration; // duration of the frame (in milliseconds).
205 |
206 | WebPChunkId id; // frame type: should be one of WEBP_CHUNK_ANMF
207 | // or WEBP_CHUNK_IMAGE
208 | WebPMuxAnimDispose dispose_method; // Disposal method for the frame.
209 | WebPMuxAnimBlend blend_method; // Blend operation for the frame.
210 | uint32_t pad[1]; // padding for later use
211 | };
212 |
213 | // Sets the (non-animated) image in the mux object.
214 | // Note: Any existing images (including frames) will be removed.
215 | // Parameters:
216 | // mux - (in/out) object in which the image is to be set
217 | // bitstream - (in) can be a raw VP8/VP8L bitstream or a single-image
218 | // WebP file (non-animated)
219 | // copy_data - (in) value 1 indicates given data WILL be copied to the mux
220 | // object and value 0 indicates data will NOT be copied.
221 | // Returns:
222 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or bitstream is NULL.
223 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error.
224 | // WEBP_MUX_OK - on success.
225 | WEBP_EXTERN WebPMuxError WebPMuxSetImage(
226 | WebPMux* mux, const WebPData* bitstream, int copy_data);
227 |
228 | // Adds a frame at the end of the mux object.
229 | // Notes: (1) frame.id should be WEBP_CHUNK_ANMF
230 | // (2) For setting a non-animated image, use WebPMuxSetImage() instead.
231 | // (3) Type of frame being pushed must be same as the frames in mux.
232 | // (4) As WebP only supports even offsets, any odd offset will be snapped
233 | // to an even location using: offset &= ~1
234 | // Parameters:
235 | // mux - (in/out) object to which the frame is to be added
236 | // frame - (in) frame data.
237 | // copy_data - (in) value 1 indicates given data WILL be copied to the mux
238 | // object and value 0 indicates data will NOT be copied.
239 | // Returns:
240 | // WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL
241 | // or if content of 'frame' is invalid.
242 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error.
243 | // WEBP_MUX_OK - on success.
244 | WEBP_EXTERN WebPMuxError WebPMuxPushFrame(
245 | WebPMux* mux, const WebPMuxFrameInfo* frame, int copy_data);
246 |
247 | // Gets the nth frame from the mux object.
248 | // The content of 'frame->bitstream' is allocated using malloc(), and NOT
249 | // owned by the 'mux' object. It MUST be deallocated by the caller by calling
250 | // WebPDataClear().
251 | // nth=0 has a special meaning - last position.
252 | // Parameters:
253 | // mux - (in) object from which the info is to be fetched
254 | // nth - (in) index of the frame in the mux object
255 | // frame - (out) data of the returned frame
256 | // Returns:
257 | // WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL.
258 | // WEBP_MUX_NOT_FOUND - if there are less than nth frames in the mux object.
259 | // WEBP_MUX_BAD_DATA - if nth frame chunk in mux is invalid.
260 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error.
261 | // WEBP_MUX_OK - on success.
262 | WEBP_EXTERN WebPMuxError WebPMuxGetFrame(
263 | const WebPMux* mux, uint32_t nth, WebPMuxFrameInfo* frame);
264 |
265 | // Deletes a frame from the mux object.
266 | // nth=0 has a special meaning - last position.
267 | // Parameters:
268 | // mux - (in/out) object from which a frame is to be deleted
269 | // nth - (in) The position from which the frame is to be deleted
270 | // Returns:
271 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL.
272 | // WEBP_MUX_NOT_FOUND - If there are less than nth frames in the mux object
273 | // before deletion.
274 | // WEBP_MUX_OK - on success.
275 | WEBP_EXTERN WebPMuxError WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth);
276 |
277 | //------------------------------------------------------------------------------
278 | // Animation.
279 |
280 | // Animation parameters.
281 | struct WebPMuxAnimParams {
282 | uint32_t bgcolor; // Background color of the canvas stored (in MSB order) as:
283 | // Bits 00 to 07: Alpha.
284 | // Bits 08 to 15: Red.
285 | // Bits 16 to 23: Green.
286 | // Bits 24 to 31: Blue.
287 | int loop_count; // Number of times to repeat the animation [0 = infinite].
288 | };
289 |
290 | // Sets the animation parameters in the mux object. Any existing ANIM chunks
291 | // will be removed.
292 | // Parameters:
293 | // mux - (in/out) object in which ANIM chunk is to be set/added
294 | // params - (in) animation parameters.
295 | // Returns:
296 | // WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL.
297 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error.
298 | // WEBP_MUX_OK - on success.
299 | WEBP_EXTERN WebPMuxError WebPMuxSetAnimationParams(
300 | WebPMux* mux, const WebPMuxAnimParams* params);
301 |
302 | // Gets the animation parameters from the mux object.
303 | // Parameters:
304 | // mux - (in) object from which the animation parameters to be fetched
305 | // params - (out) animation parameters extracted from the ANIM chunk
306 | // Returns:
307 | // WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL.
308 | // WEBP_MUX_NOT_FOUND - if ANIM chunk is not present in mux object.
309 | // WEBP_MUX_OK - on success.
310 | WEBP_EXTERN WebPMuxError WebPMuxGetAnimationParams(
311 | const WebPMux* mux, WebPMuxAnimParams* params);
312 |
313 | //------------------------------------------------------------------------------
314 | // Misc Utilities.
315 |
316 | // Sets the canvas size for the mux object. The width and height can be
317 | // specified explicitly or left as zero (0, 0).
318 | // * When width and height are specified explicitly, then this frame bound is
319 | // enforced during subsequent calls to WebPMuxAssemble() and an error is
320 | // reported if any animated frame does not completely fit within the canvas.
321 | // * When unspecified (0, 0), the constructed canvas will get the frame bounds
322 | // from the bounding-box over all frames after calling WebPMuxAssemble().
323 | // Parameters:
324 | // mux - (in) object to which the canvas size is to be set
325 | // width - (in) canvas width
326 | // height - (in) canvas height
327 | // Returns:
328 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL; or
329 | // width or height are invalid or out of bounds
330 | // WEBP_MUX_OK - on success.
331 | WEBP_EXTERN WebPMuxError WebPMuxSetCanvasSize(WebPMux* mux,
332 | int width, int height);
333 |
334 | // Gets the canvas size from the mux object.
335 | // Note: This method assumes that the VP8X chunk, if present, is up-to-date.
336 | // That is, the mux object hasn't been modified since the last call to
337 | // WebPMuxAssemble() or WebPMuxCreate().
338 | // Parameters:
339 | // mux - (in) object from which the canvas size is to be fetched
340 | // width - (out) canvas width
341 | // height - (out) canvas height
342 | // Returns:
343 | // WEBP_MUX_INVALID_ARGUMENT - if mux, width or height is NULL.
344 | // WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid.
345 | // WEBP_MUX_OK - on success.
346 | WEBP_EXTERN WebPMuxError WebPMuxGetCanvasSize(const WebPMux* mux,
347 | int* width, int* height);
348 |
349 | // Gets the feature flags from the mux object.
350 | // Note: This method assumes that the VP8X chunk, if present, is up-to-date.
351 | // That is, the mux object hasn't been modified since the last call to
352 | // WebPMuxAssemble() or WebPMuxCreate().
353 | // Parameters:
354 | // mux - (in) object from which the features are to be fetched
355 | // flags - (out) the flags specifying which features are present in the
356 | // mux object. This will be an OR of various flag values.
357 | // Enum 'WebPFeatureFlags' can be used to test individual flag values.
358 | // Returns:
359 | // WEBP_MUX_INVALID_ARGUMENT - if mux or flags is NULL.
360 | // WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid.
361 | // WEBP_MUX_OK - on success.
362 | WEBP_EXTERN WebPMuxError WebPMuxGetFeatures(const WebPMux* mux,
363 | uint32_t* flags);
364 |
365 | // Gets number of chunks with the given 'id' in the mux object.
366 | // Parameters:
367 | // mux - (in) object from which the info is to be fetched
368 | // id - (in) chunk id specifying the type of chunk
369 | // num_elements - (out) number of chunks with the given chunk id
370 | // Returns:
371 | // WEBP_MUX_INVALID_ARGUMENT - if mux, or num_elements is NULL.
372 | // WEBP_MUX_OK - on success.
373 | WEBP_EXTERN WebPMuxError WebPMuxNumChunks(const WebPMux* mux,
374 | WebPChunkId id, int* num_elements);
375 |
376 | // Assembles all chunks in WebP RIFF format and returns in 'assembled_data'.
377 | // This function also validates the mux object.
378 | // Note: The content of 'assembled_data' will be ignored and overwritten.
379 | // Also, the content of 'assembled_data' is allocated using malloc(), and NOT
380 | // owned by the 'mux' object. It MUST be deallocated by the caller by calling
381 | // WebPDataClear(). It's always safe to call WebPDataClear() upon return,
382 | // even in case of error.
383 | // Parameters:
384 | // mux - (in/out) object whose chunks are to be assembled
385 | // assembled_data - (out) assembled WebP data
386 | // Returns:
387 | // WEBP_MUX_BAD_DATA - if mux object is invalid.
388 | // WEBP_MUX_INVALID_ARGUMENT - if mux or assembled_data is NULL.
389 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error.
390 | // WEBP_MUX_OK - on success.
391 | WEBP_EXTERN WebPMuxError WebPMuxAssemble(WebPMux* mux,
392 | WebPData* assembled_data);
393 |
394 | //------------------------------------------------------------------------------
395 | // WebPAnimEncoder API
396 | //
397 | // This API allows encoding (possibly) animated WebP images.
398 | //
399 | // Code Example:
400 | /*
401 | WebPAnimEncoderOptions enc_options;
402 | WebPAnimEncoderOptionsInit(&enc_options);
403 | // Tune 'enc_options' as needed.
404 | WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
405 | while() {
406 | WebPConfig config;
407 | WebPConfigInit(&config);
408 | // Tune 'config' as needed.
409 | WebPAnimEncoderAdd(enc, frame, timestamp_ms, &config);
410 | }
411 | WebPAnimEncoderAdd(enc, NULL, timestamp_ms, NULL);
412 | WebPAnimEncoderAssemble(enc, webp_data);
413 | WebPAnimEncoderDelete(enc);
414 | // Write the 'webp_data' to a file, or re-mux it further.
415 | */
416 |
417 | typedef struct WebPAnimEncoder WebPAnimEncoder; // Main opaque object.
418 |
419 | // Forward declarations. Defined in encode.h.
420 | struct WebPPicture;
421 | struct WebPConfig;
422 |
423 | // Global options.
424 | struct WebPAnimEncoderOptions {
425 | WebPMuxAnimParams anim_params; // Animation parameters.
426 | int minimize_size; // If true, minimize the output size (slow). Implicitly
427 | // disables key-frame insertion.
428 | int kmin;
429 | int kmax; // Minimum and maximum distance between consecutive key
430 | // frames in the output. The library may insert some key
431 | // frames as needed to satisfy this criteria.
432 | // Note that these conditions should hold: kmax > kmin
433 | // and kmin >= kmax / 2 + 1. Also, if kmax <= 0, then
434 | // key-frame insertion is disabled; and if kmax == 1,
435 | // then all frames will be key-frames (kmin value does
436 | // not matter for these special cases).
437 | int allow_mixed; // If true, use mixed compression mode; may choose
438 | // either lossy and lossless for each frame.
439 | int verbose; // If true, print info and warning messages to stderr.
440 |
441 | uint32_t padding[4]; // Padding for later use.
442 | };
443 |
444 | // Internal, version-checked, entry point.
445 | WEBP_EXTERN int WebPAnimEncoderOptionsInitInternal(
446 | WebPAnimEncoderOptions*, int);
447 |
448 | // Should always be called, to initialize a fresh WebPAnimEncoderOptions
449 | // structure before modification. Returns false in case of version mismatch.
450 | // WebPAnimEncoderOptionsInit() must have succeeded before using the
451 | // 'enc_options' object.
452 | static WEBP_INLINE int WebPAnimEncoderOptionsInit(
453 | WebPAnimEncoderOptions* enc_options) {
454 | return WebPAnimEncoderOptionsInitInternal(enc_options, WEBP_MUX_ABI_VERSION);
455 | }
456 |
457 | // Internal, version-checked, entry point.
458 | WEBP_EXTERN WebPAnimEncoder* WebPAnimEncoderNewInternal(
459 | int, int, const WebPAnimEncoderOptions*, int);
460 |
461 | // Creates and initializes a WebPAnimEncoder object.
462 | // Parameters:
463 | // width/height - (in) canvas width and height of the animation.
464 | // enc_options - (in) encoding options; can be passed NULL to pick
465 | // reasonable defaults.
466 | // Returns:
467 | // A pointer to the newly created WebPAnimEncoder object.
468 | // Or NULL in case of memory error.
469 | static WEBP_INLINE WebPAnimEncoder* WebPAnimEncoderNew(
470 | int width, int height, const WebPAnimEncoderOptions* enc_options) {
471 | return WebPAnimEncoderNewInternal(width, height, enc_options,
472 | WEBP_MUX_ABI_VERSION);
473 | }
474 |
475 | // Optimize the given frame for WebP, encode it and add it to the
476 | // WebPAnimEncoder object.
477 | // The last call to 'WebPAnimEncoderAdd' should be with frame = NULL, which
478 | // indicates that no more frames are to be added. This call is also used to
479 | // determine the duration of the last frame.
480 | // Parameters:
481 | // enc - (in/out) object to which the frame is to be added.
482 | // frame - (in/out) frame data in ARGB or YUV(A) format. If it is in YUV(A)
483 | // format, it will be converted to ARGB, which incurs a small loss.
484 | // timestamp_ms - (in) timestamp of this frame in milliseconds.
485 | // Duration of a frame would be calculated as
486 | // "timestamp of next frame - timestamp of this frame".
487 | // Hence, timestamps should be in non-decreasing order.
488 | // config - (in) encoding options; can be passed NULL to pick
489 | // reasonable defaults.
490 | // Returns:
491 | // On error, returns false and frame->error_code is set appropriately.
492 | // Otherwise, returns true.
493 | WEBP_EXTERN int WebPAnimEncoderAdd(
494 | WebPAnimEncoder* enc, struct WebPPicture* frame, int timestamp_ms,
495 | const struct WebPConfig* config);
496 |
497 | // Assemble all frames added so far into a WebP bitstream.
498 | // This call should be preceded by a call to 'WebPAnimEncoderAdd' with
499 | // frame = NULL; if not, the duration of the last frame will be internally
500 | // estimated.
501 | // Parameters:
502 | // enc - (in/out) object from which the frames are to be assembled.
503 | // webp_data - (out) generated WebP bitstream.
504 | // Returns:
505 | // True on success.
506 | WEBP_EXTERN int WebPAnimEncoderAssemble(WebPAnimEncoder* enc,
507 | WebPData* webp_data);
508 |
509 | // Get error string corresponding to the most recent call using 'enc'. The
510 | // returned string is owned by 'enc' and is valid only until the next call to
511 | // WebPAnimEncoderAdd() or WebPAnimEncoderAssemble() or WebPAnimEncoderDelete().
512 | // Parameters:
513 | // enc - (in/out) object from which the error string is to be fetched.
514 | // Returns:
515 | // NULL if 'enc' is NULL. Otherwise, returns the error string if the last call
516 | // to 'enc' had an error, or an empty string if the last call was a success.
517 | WEBP_EXTERN const char* WebPAnimEncoderGetError(WebPAnimEncoder* enc);
518 |
519 | // Deletes the WebPAnimEncoder object.
520 | // Parameters:
521 | // enc - (in/out) object to be deleted
522 | WEBP_EXTERN void WebPAnimEncoderDelete(WebPAnimEncoder* enc);
523 |
524 | //------------------------------------------------------------------------------
525 |
526 | #ifdef __cplusplus
527 | } // extern "C"
528 | #endif
529 |
530 | #endif // WEBP_WEBP_MUX_H_
531 |
--------------------------------------------------------------------------------
/deps/libwebp/mux_types.h:
--------------------------------------------------------------------------------
1 | // Copyright 2012 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // Data-types common to the mux and demux libraries.
11 | //
12 | // Author: Urvang (urvang@google.com)
13 |
14 | #ifndef WEBP_WEBP_MUX_TYPES_H_
15 | #define WEBP_WEBP_MUX_TYPES_H_
16 |
17 | #include // free()
18 | #include // memset()
19 | #include "./types.h"
20 |
21 | #ifdef __cplusplus
22 | extern "C" {
23 | #endif
24 |
25 | // Note: forward declaring enumerations is not allowed in (strict) C and C++,
26 | // the types are left here for reference.
27 | // typedef enum WebPFeatureFlags WebPFeatureFlags;
28 | // typedef enum WebPMuxAnimDispose WebPMuxAnimDispose;
29 | // typedef enum WebPMuxAnimBlend WebPMuxAnimBlend;
30 | typedef struct WebPData WebPData;
31 |
32 | // VP8X Feature Flags.
33 | typedef enum WebPFeatureFlags {
34 | ANIMATION_FLAG = 0x00000002,
35 | XMP_FLAG = 0x00000004,
36 | EXIF_FLAG = 0x00000008,
37 | ALPHA_FLAG = 0x00000010,
38 | ICCP_FLAG = 0x00000020,
39 |
40 | ALL_VALID_FLAGS = 0x0000003e
41 | } WebPFeatureFlags;
42 |
43 | // Dispose method (animation only). Indicates how the area used by the current
44 | // frame is to be treated before rendering the next frame on the canvas.
45 | typedef enum WebPMuxAnimDispose {
46 | WEBP_MUX_DISPOSE_NONE, // Do not dispose.
47 | WEBP_MUX_DISPOSE_BACKGROUND // Dispose to background color.
48 | } WebPMuxAnimDispose;
49 |
50 | // Blend operation (animation only). Indicates how transparent pixels of the
51 | // current frame are blended with those of the previous canvas.
52 | typedef enum WebPMuxAnimBlend {
53 | WEBP_MUX_BLEND, // Blend.
54 | WEBP_MUX_NO_BLEND // Do not blend.
55 | } WebPMuxAnimBlend;
56 |
57 | // Data type used to describe 'raw' data, e.g., chunk data
58 | // (ICC profile, metadata) and WebP compressed image data.
59 | struct WebPData {
60 | const uint8_t* bytes;
61 | size_t size;
62 | };
63 |
64 | // Initializes the contents of the 'webp_data' object with default values.
65 | static WEBP_INLINE void WebPDataInit(WebPData* webp_data) {
66 | if (webp_data != NULL) {
67 | memset(webp_data, 0, sizeof(*webp_data));
68 | }
69 | }
70 |
71 | // Clears the contents of the 'webp_data' object by calling free(). Does not
72 | // deallocate the object itself.
73 | static WEBP_INLINE void WebPDataClear(WebPData* webp_data) {
74 | if (webp_data != NULL) {
75 | free((void*)webp_data->bytes);
76 | WebPDataInit(webp_data);
77 | }
78 | }
79 |
80 | // Allocates necessary storage for 'dst' and copies the contents of 'src'.
81 | // Returns true on success.
82 | static WEBP_INLINE int WebPDataCopy(const WebPData* src, WebPData* dst) {
83 | if (src == NULL || dst == NULL) return 0;
84 | WebPDataInit(dst);
85 | if (src->bytes != NULL && src->size != 0) {
86 | dst->bytes = (uint8_t*)malloc(src->size);
87 | if (dst->bytes == NULL) return 0;
88 | memcpy((void*)dst->bytes, src->bytes, src->size);
89 | dst->size = src->size;
90 | }
91 | return 1;
92 | }
93 |
94 | #ifdef __cplusplus
95 | } // extern "C"
96 | #endif
97 |
98 | #endif // WEBP_WEBP_MUX_TYPES_H_
99 |
--------------------------------------------------------------------------------
/deps/libwebp/types.h:
--------------------------------------------------------------------------------
1 | // Copyright 2010 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // Common types
11 | //
12 | // Author: Skal (pascal.massimino@gmail.com)
13 |
14 | #ifndef WEBP_WEBP_TYPES_H_
15 | #define WEBP_WEBP_TYPES_H_
16 |
17 | #include // for size_t
18 |
19 | #ifndef _MSC_VER
20 | #include
21 | #if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \
22 | (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
23 | #define WEBP_INLINE inline
24 | #else
25 | #define WEBP_INLINE
26 | #endif
27 | #else
28 | typedef signed char int8_t;
29 | typedef unsigned char uint8_t;
30 | typedef signed short int16_t;
31 | typedef unsigned short uint16_t;
32 | typedef signed int int32_t;
33 | typedef unsigned int uint32_t;
34 | typedef unsigned long long int uint64_t;
35 | typedef long long int int64_t;
36 | #define WEBP_INLINE __forceinline
37 | #endif /* _MSC_VER */
38 |
39 | #ifndef WEBP_EXTERN
40 | // This explicitly marks library functions and allows for changing the
41 | // signature for e.g., Windows DLL builds.
42 | # if defined(__GNUC__) && __GNUC__ >= 4
43 | # define WEBP_EXTERN extern __attribute__ ((visibility ("default")))
44 | # else
45 | # define WEBP_EXTERN extern
46 | # endif /* __GNUC__ >= 4 */
47 | #endif /* WEBP_EXTERN */
48 |
49 | // Macro to check ABI compatibility (same major revision number)
50 | #define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8))
51 |
52 | #endif // WEBP_WEBP_TYPES_H_
53 |
--------------------------------------------------------------------------------
/images-samples.txz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nyx0uf/qlImageSize/41082059f6b0d57609a60aa27b7127552e17708f/images-samples.txz
--------------------------------------------------------------------------------
/mdimporter/rsrc/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDocumentTypes
8 |
9 |
10 | CFBundleTypeRole
11 | MDImporter
12 | LSItemContentTypes
13 |
14 | public.image
15 | public.webp
16 | com.google.webp
17 | fr.whine.bpg
18 | fr.whine.ppm
19 | fr.whine.pbm
20 | fr.whine.pgm
21 |
22 |
23 |
24 | CFBundleExecutable
25 | $(EXECUTABLE_NAME)
26 | CFBundleIdentifier
27 | $(PRODUCT_BUNDLE_IDENTIFIER)
28 | CFBundleInfoDictionaryVersion
29 | 6.0
30 | CFBundleName
31 | $(PRODUCT_NAME)
32 | CFBundleShortVersionString
33 | 1
34 | CFBundleSignature
35 | NYXM
36 | CFBundleVersion
37 | 2.6
38 | CFPlugInDynamicRegisterFunction
39 |
40 | CFPlugInDynamicRegistration
41 | NO
42 | CFPlugInFactories
43 |
44 | F0D38E63-504A-49AF-936B-2468C8D82C96
45 | MetadataImporterPluginFactory
46 |
47 | CFPlugInTypes
48 |
49 | 8B08C4BF-415B-11D8-B3F9-0003936726FC
50 |
51 | F0D38E63-504A-49AF-936B-2468C8D82C96
52 |
53 |
54 | CFPlugInUnloadFunction
55 |
56 | LSMinimumSystemVersion
57 | $(MACOSX_DEPLOYMENT_TARGET)
58 | NSHumanReadableCopyright
59 | Copyright © 2019 Nyx0uf. All rights reserved.
60 |
61 |
62 |
--------------------------------------------------------------------------------
/mdimporter/src/GetMetadataForFile.m:
--------------------------------------------------------------------------------
1 | //
2 | // GetMetadataForFile.m
3 | // qlImageSize
4 | //
5 | // Created by @Nyx0uf on 20/12/14.
6 | // Copyright (c) 2014 Nyx0uf. All rights reserved.
7 | //
8 |
9 |
10 | #import "tools.h"
11 |
12 | #ifdef NYX_MD_SUPPORT_BPG_DECODE
13 | #import "bpg_decode.h"
14 | #endif
15 |
16 | #ifdef NYX_MD_SUPPORT_WEBP_DECODE
17 | #import "webp_decode.h"
18 | #endif
19 |
20 | #ifdef NYX_MD_SUPPORT_NETPBM_DECODE
21 | #import "netpbm_decode.h"
22 | #endif
23 |
24 |
25 | Boolean GetMetadataForFile(void* thisInterface, CFMutableDictionaryRef attributes, CFStringRef contentTypeUTI, CFStringRef pathToFile);
26 | bool GetImageInfos(CFStringRef pathToFile, NSMutableDictionary* attrs, bool (*infos_fn_ptr)(CFStringRef, image_infos*));
27 |
28 |
29 | Boolean GetMetadataForFile(__unused void* thisInterface, CFMutableDictionaryRef attributes, __unused CFStringRef contentTypeUTI, CFStringRef pathToFile)
30 | {
31 | @autoreleasepool
32 | {
33 | NSString* extension = [[(__bridge NSString*)pathToFile pathExtension] lowercaseString];
34 |
35 | #ifdef NYX_MD_SUPPORT_BPG_DECODE
36 | if ([extension isEqualToString:@"bpg"])
37 | {
38 | return GetImageInfos(pathToFile, (__bridge NSMutableDictionary*)attributes, &get_bpg_informations_for_filepath);
39 | }
40 | #endif
41 | #ifdef NYX_MD_SUPPORT_WEBP_DECODE
42 | if ([extension isEqualToString:@"webp"])
43 | {
44 | return GetImageInfos(pathToFile, (__bridge NSMutableDictionary*)attributes, &get_webp_informations_for_filepath);
45 | }
46 | #endif
47 | #ifdef NYX_MD_SUPPORT_NETPBM_DECODE
48 | if ([extension isEqualToString:@"ppm"] || [extension isEqualToString:@"pgm"] || [extension isEqualToString:@"pbm"])
49 | {
50 | return GetImageInfos(pathToFile, (__bridge NSMutableDictionary*)attributes, &get_netpbm_informations_for_filepath);
51 | }
52 | #endif
53 | }
54 |
55 | return TRUE;
56 | }
57 |
58 | bool GetImageInfos(CFStringRef pathToFile, NSMutableDictionary* attrs, bool (*infos_fn_ptr)(CFStringRef, image_infos*))
59 | {
60 | image_infos infos;
61 | memset(&infos, 0, sizeof(image_infos));
62 | bool ret = infos_fn_ptr(pathToFile, &infos);
63 |
64 | if (!ret)
65 | return FALSE;
66 |
67 | attrs[(NSString*)kMDItemPixelWidth] = @(infos.width);
68 | attrs[(NSString*)kMDItemPixelHeight] = @(infos.height);
69 | attrs[(NSString*)kMDItemPixelCount] = @(infos.height * infos.width);
70 | attrs[(NSString*)kMDItemHasAlphaChannel] = (!infos.has_alpha) ? @NO : @YES;
71 | attrs[(NSString*)kMDItemBitsPerSample] = @(infos.bit_depth);
72 | attrs[(NSString*)kMDItemColorSpace] = @(colorspace_string(infos.colorspace));
73 |
74 | return TRUE;
75 | }
76 |
--------------------------------------------------------------------------------
/mdimporter/src/main.c:
--------------------------------------------------------------------------------
1 | //
2 | // main.c
3 | // qlImageSize
4 | //
5 | // Created by @Nyx0uf on 20/12/14.
6 | // Copyright (c) 2014 Nyx0uf. All rights reserved.
7 | //
8 |
9 |
10 | //==============================================================================
11 | //
12 | // DO NO MODIFY THE CONTENT OF THIS FILE
13 | //
14 | // This file contains the generic CFPlug-in code necessary for your importer
15 | // To complete your importer implement the function in GetMetadataForFile.c
16 | //
17 | //==============================================================================
18 |
19 |
20 | #import
21 | #import
22 | #import
23 |
24 | // -----------------------------------------------------------------------------
25 | // constants
26 | // -----------------------------------------------------------------------------
27 |
28 |
29 | #define PLUGIN_ID "F0D38E63-504A-49AF-936B-2468C8D82C96"
30 |
31 | //
32 | // Below is the generic glue code for all plug-ins.
33 | //
34 | // You should not have to modify this code aside from changing
35 | // names if you decide to change the names defined in the Info.plist
36 | //
37 |
38 |
39 | // -----------------------------------------------------------------------------
40 | // typedefs
41 | // -----------------------------------------------------------------------------
42 |
43 | // The import function to be implemented in GetMetadataForFile.c
44 | Boolean GetMetadataForFile(void* thisInterface, CFMutableDictionaryRef attributes, CFStringRef contentTypeUTI, CFStringRef pathToFile);
45 |
46 | // The layout for an instance of MetaDataImporterPlugIn
47 | typedef struct __MetadataImporterPluginType
48 | {
49 | MDImporterInterfaceStruct* conduitInterface;
50 | CFUUIDRef factoryID;
51 | UInt32 refCount;
52 | } MetadataImporterPluginType;
53 |
54 | // -----------------------------------------------------------------------------
55 | // prototypes
56 | // -----------------------------------------------------------------------------
57 | // Forward declaration for the IUnknown implementation.
58 | //
59 |
60 | MetadataImporterPluginType* AllocMetadataImporterPluginType(CFUUIDRef inFactoryID);
61 | void DeallocMetadataImporterPluginType(MetadataImporterPluginType* thisInstance);
62 | HRESULT MetadataImporterQueryInterface(void* thisInstance, REFIID iid, LPVOID* ppv);
63 | void* MetadataImporterPluginFactory(CFAllocatorRef allocator, CFUUIDRef typeID);
64 | ULONG MetadataImporterPluginAddRef(void* thisInstance);
65 | ULONG MetadataImporterPluginRelease(void* thisInstance);
66 | // -----------------------------------------------------------------------------
67 | // testInterfaceFtbl definition
68 | // -----------------------------------------------------------------------------
69 | // The TestInterface function table.
70 | //
71 |
72 | static MDImporterInterfaceStruct testInterfaceFtbl = {
73 | NULL,
74 | MetadataImporterQueryInterface,
75 | MetadataImporterPluginAddRef,
76 | MetadataImporterPluginRelease,
77 | GetMetadataForFile
78 | };
79 |
80 |
81 | // -----------------------------------------------------------------------------
82 | // AllocMetadataImporterPluginType
83 | // -----------------------------------------------------------------------------
84 | // Utility function that allocates a new instance.
85 | // You can do some initial setup for the importer here if you wish
86 | // like allocating globals etc...
87 | //
88 | MetadataImporterPluginType* AllocMetadataImporterPluginType(CFUUIDRef inFactoryID)
89 | {
90 | MetadataImporterPluginType* theNewInstance;
91 |
92 | theNewInstance = (MetadataImporterPluginType*)malloc(sizeof(MetadataImporterPluginType));
93 | memset(theNewInstance, 0, sizeof(MetadataImporterPluginType));
94 |
95 | /* Point to the function table */
96 | theNewInstance->conduitInterface = &testInterfaceFtbl;
97 |
98 | /* Retain and keep an open instance refcount for each factory. */
99 | theNewInstance->factoryID = CFRetain(inFactoryID);
100 | CFPlugInAddInstanceForFactory(inFactoryID);
101 |
102 | /* This function returns the IUnknown interface so set the refCount to one. */
103 | theNewInstance->refCount = 1;
104 | return theNewInstance;
105 | }
106 |
107 | // -----------------------------------------------------------------------------
108 | // DeallocmdImageSizeMDImporterPluginType
109 | // -----------------------------------------------------------------------------
110 | // Utility function that deallocates the instance when
111 | // the refCount goes to zero.
112 | // In the current implementation importer interfaces are never deallocated
113 | // but implement this as this might change in the future
114 | //
115 | void DeallocMetadataImporterPluginType(MetadataImporterPluginType* thisInstance)
116 | {
117 | CFUUIDRef theFactoryID;
118 |
119 | theFactoryID = thisInstance->factoryID;
120 | free(thisInstance);
121 | if (theFactoryID)
122 | {
123 | CFPlugInRemoveInstanceForFactory(theFactoryID);
124 | CFRelease(theFactoryID);
125 | }
126 | }
127 |
128 | // -----------------------------------------------------------------------------
129 | // MetadataImporterQueryInterface
130 | // -----------------------------------------------------------------------------
131 | // Implementation of the IUnknown QueryInterface function.
132 | //
133 | HRESULT MetadataImporterQueryInterface(void* thisInstance, REFIID iid, LPVOID* ppv)
134 | {
135 | CFUUIDRef interfaceID;
136 |
137 | interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, iid);
138 |
139 | if (CFEqual(interfaceID, kMDImporterInterfaceID))
140 | {
141 | /* If the Right interface was requested, bump the ref count,
142 | * set the ppv parameter equal to the instance, and
143 | * return good status.
144 | */
145 | ((MetadataImporterPluginType*)thisInstance)->conduitInterface->AddRef(thisInstance);
146 | *ppv = thisInstance;
147 | CFRelease(interfaceID);
148 | return S_OK;
149 | }
150 | else
151 | {
152 | if (CFEqual(interfaceID,IUnknownUUID))
153 | {
154 | /* If the IUnknown interface was requested, same as above. */
155 | ((MetadataImporterPluginType*)thisInstance)->conduitInterface->AddRef(thisInstance);
156 | *ppv = thisInstance;
157 | CFRelease(interfaceID);
158 | return S_OK;
159 | }
160 | else
161 | {
162 | /* Requested interface unknown, bail with error. */
163 | *ppv = NULL;
164 | CFRelease(interfaceID);
165 | return E_NOINTERFACE;
166 | }
167 | }
168 | }
169 |
170 | // -----------------------------------------------------------------------------
171 | // MetadataImporterPluginAddRef
172 | // -----------------------------------------------------------------------------
173 | // Implementation of reference counting for this type. Whenever an interface
174 | // is requested, bump the refCount for the instance. NOTE: returning the
175 | // refcount is a convention but is not required so don't rely on it.
176 | //
177 | ULONG MetadataImporterPluginAddRef(void* thisInstance)
178 | {
179 | ((MetadataImporterPluginType*)thisInstance)->refCount += 1;
180 | return ((MetadataImporterPluginType*)thisInstance)->refCount;
181 | }
182 |
183 | // -----------------------------------------------------------------------------
184 | // SampleCMPluginRelease
185 | // -----------------------------------------------------------------------------
186 | // When an interface is released, decrement the refCount.
187 | // If the refCount goes to zero, deallocate the instance.
188 | //
189 | ULONG MetadataImporterPluginRelease(void* thisInstance)
190 | {
191 | ((MetadataImporterPluginType*)thisInstance)->refCount -= 1;
192 | if (((MetadataImporterPluginType*)thisInstance)->refCount == 0)
193 | {
194 | DeallocMetadataImporterPluginType((MetadataImporterPluginType*)thisInstance);
195 | return 0;
196 | }
197 | else
198 | return ((MetadataImporterPluginType*)thisInstance)->refCount;
199 | }
200 |
201 | // -----------------------------------------------------------------------------
202 | // mdImageSizeMDImporterPluginFactory
203 | // -----------------------------------------------------------------------------
204 | // Implementation of the factory function for this type.
205 | //
206 | void* MetadataImporterPluginFactory(__unused CFAllocatorRef allocator, CFUUIDRef typeID)
207 | {
208 | MetadataImporterPluginType* result;
209 | CFUUIDRef uuid;
210 |
211 | /* If correct type is being requested, allocate an
212 | * instance of TestType and return the IUnknown interface.
213 | */
214 | if (CFEqual(typeID, kMDImporterTypeID))
215 | {
216 | uuid = CFUUIDCreateFromString(kCFAllocatorDefault, CFSTR(PLUGIN_ID));
217 | result = AllocMetadataImporterPluginType(uuid);
218 | CFRelease(uuid);
219 | return result;
220 | }
221 | /* If the requested type is incorrect, return NULL. */
222 | return NULL;
223 | }
224 |
--------------------------------------------------------------------------------
/qlImageSize.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/qlImageSize.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/qlImageSize.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/qlImageSize.xcodeproj/project.xcworkspace/xcuserdata/nyxouf.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges
6 |
7 | SnapshotAutomaticallyBeforeSignificantChanges
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/qlImageSize.xcodeproj/xcuserdata/benjamin.xcuserdatad/xcschemes/mdImageSize.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/qlImageSize.xcodeproj/xcuserdata/benjamin.xcuserdatad/xcschemes/qlImageSize.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/qlImageSize.xcodeproj/xcuserdata/benjamin.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | mdImageSize.xcscheme
8 |
9 | orderHint
10 | 1
11 |
12 | qlImageSize.xcscheme
13 |
14 | orderHint
15 | 0
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | 1E7F115A1A459FE800EA2767
21 |
22 | primary
23 |
24 |
25 | 1EFA993D14D9288600A09F03
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/qlImageSize.xcodeproj/xcuserdata/nyxouf.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/qlImageSize.xcodeproj/xcuserdata/nyxouf.xcuserdatad/xcschemes/mdImageSize.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
60 |
61 |
67 |
68 |
69 |
70 |
72 |
73 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/qlImageSize.xcodeproj/xcuserdata/nyxouf.xcuserdatad/xcschemes/qlImageSize.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
60 |
61 |
63 |
64 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/qlImageSize.xcodeproj/xcuserdata/nyxouf.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | mdImageSize.xcscheme
8 |
9 | orderHint
10 | 2
11 |
12 | qlImageSize.xcscheme
13 |
14 | orderHint
15 | 1
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | 1E7F115A1A459FE800EA2767
21 |
22 | primary
23 |
24 |
25 | 1EFA993D14D9288600A09F03
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/qlgenerator/rsrc/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleDocumentTypes
8 |
9 |
10 | CFBundleTypeRole
11 | QLGenerator
12 | LSItemContentTypes
13 |
14 | public.image
15 | public.webp
16 | com.google.webp
17 | fr.whine.bpg
18 | fr.whine.ppm
19 | fr.whine.pbm
20 | fr.whine.pgm
21 |
22 |
23 |
24 | CFBundleExecutable
25 | ${EXECUTABLE_NAME}
26 | CFBundleIconFile
27 |
28 | CFBundleIdentifier
29 | $(PRODUCT_BUNDLE_IDENTIFIER)
30 | CFBundleInfoDictionaryVersion
31 | 6.0
32 | CFBundleName
33 | ${PRODUCT_NAME}
34 | CFBundleShortVersionString
35 | 1
36 | CFBundleVersion
37 | 2.6
38 | CFPlugInDynamicRegisterFunction
39 |
40 | CFPlugInDynamicRegistration
41 | NO
42 | CFPlugInFactories
43 |
44 | B39D1988-F7D1-4420-B89F-4627490F6326
45 | QuickLookGeneratorPluginFactory
46 |
47 | CFPlugInTypes
48 |
49 | 5E2D9680-5022-40FA-B806-43349622E5B9
50 |
51 | B39D1988-F7D1-4420-B89F-4627490F6326
52 |
53 |
54 | CFPlugInUnloadFunction
55 |
56 | NSHumanReadableCopyright
57 | Copyright © 2019 Nyx0uf. All rights reserved.
58 | QLNeedsToBeRunInMainThread
59 |
60 | QLPreviewHeight
61 | 600
62 | QLPreviewWidth
63 | 800
64 | QLSupportsConcurrentRequests
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/qlgenerator/src/GeneratePreviewForURL.m:
--------------------------------------------------------------------------------
1 | //
2 | // GeneratePreviewForURL.c
3 | // qlImageSize
4 | //
5 | // Created by @Nyx0uf on 31/01/12.
6 | // Copyright (c) 2012 Nyx0uf. All rights reserved.
7 | //
8 |
9 |
10 | #import
11 | #import "tools.h"
12 |
13 | #ifdef NYX_QL_SUPPORT_BPG_DECODE
14 | #import "bpg_decode.h"
15 | #endif
16 |
17 | #ifdef NYX_QL_SUPPORT_WEBP_DECODE
18 | #import "webp_decode.h"
19 | #endif
20 |
21 | #ifdef NYX_QL_SUPPORT_NETPBM_DECODE
22 | #import "netpbm_decode.h"
23 | #endif
24 |
25 | // To enable logging --> defaults write -g QLEnableLogging NO
26 | OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options);
27 | void CancelPreviewGeneration(void* thisInterface, QLPreviewRequestRef preview);
28 | void HandleFileForPreview(CFURLRef url, CGImageRef (*decode_fn_ptr)(CFStringRef, image_infos*), QLPreviewRequestRef preview, CFStringRef contentTypeUTI);
29 | CF_RETURNS_RETAINED static CFDictionaryRef _create_properties(CFURLRef url, const size_t size, const size_t width, const size_t height, const size_t dpi, const bool b);
30 |
31 |
32 | OSStatus GeneratePreviewForURL(__unused void* thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, __unused CFDictionaryRef options)
33 | {
34 | @autoreleasepool
35 | {
36 | // Non-standard images (not supported by the OS by default)
37 | // Check by extension because it's highly unprobable that an UTI for these formats is declared
38 | NSString* extension = [[(__bridge NSURL*)url pathExtension] lowercaseString];
39 |
40 | #ifdef NYX_QL_SUPPORT_BPG_DECODE
41 | if ([extension isEqualToString:@"bpg"])
42 | {
43 | HandleFileForPreview(url, &decode_bpg_at_path, preview, contentTypeUTI);
44 | return kQLReturnNoError;
45 | }
46 | #endif
47 | #ifdef NYX_QL_SUPPORT_WEBP_DECODE
48 | if ([extension isEqualToString:@"webp"])
49 | {
50 | HandleFileForPreview(url, &decode_webp_at_path, preview, contentTypeUTI);
51 | return kQLReturnNoError;
52 | }
53 | #endif
54 | #ifdef NYX_QL_SUPPORT_NETPBM_DECODE
55 | if ([extension isEqualToString:@"ppm"] || [extension isEqualToString:@"pgm"] || [extension isEqualToString:@"pbm"])
56 | {
57 | HandleFileForPreview(url, &decode_netpbm_at_path, preview, contentTypeUTI);
58 | return kQLReturnNoError;
59 | }
60 | #endif
61 | // Standard images (supported by the OS by default)
62 | size_t width = 0, height = 0, dpi = 0, file_size = 0;
63 | properties_for_file(url, &width, &height, &dpi, &file_size);
64 |
65 | // Request preview with updated titlebar
66 | CFDictionaryRef properties = _create_properties(url, file_size, width, height, dpi, false);
67 | QLPreviewRequestSetURLRepresentation(preview, url, contentTypeUTI, properties);
68 |
69 | SAFE_CFRelease(properties);
70 | }
71 | return kQLReturnNoError;
72 | }
73 |
74 | void HandleFileForPreview(CFURLRef url, CGImageRef (*decode_fn_ptr)(CFStringRef, image_infos*), QLPreviewRequestRef preview, CFStringRef contentTypeUTI)
75 | {
76 | // 1. decode the image
77 | if (!QLPreviewRequestIsCancelled(preview))
78 | {
79 | image_infos infos;
80 | memset(&infos, 0, sizeof(image_infos));
81 | CFStringRef filepath = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
82 | CGImageRef img_ref = decode_fn_ptr(filepath, &infos);
83 | SAFE_CFRelease(filepath);
84 |
85 | // 2. render it
86 | CFDictionaryRef properties = _create_properties(url, infos.filesize, infos.width, infos.height, infos.dpi, true);
87 | if (img_ref != NULL)
88 | {
89 | // Have to draw the image ourselves
90 | CGContextRef ctx = QLPreviewRequestCreateContext(preview, (CGSize){.width = infos.width, .height = infos.height}, YES, properties);
91 | CGContextDrawImage(ctx, (CGRect){.origin = CGPointZero, .size.width = infos.width, .size.height = infos.height}, img_ref);
92 | QLPreviewRequestFlushContext(preview, ctx);
93 | CGContextRelease(ctx);
94 | CGImageRelease(img_ref);
95 | }
96 | else
97 | QLPreviewRequestSetURLRepresentation(preview, url, contentTypeUTI, properties);
98 | SAFE_CFRelease(properties);
99 | }
100 | }
101 |
102 | void CancelPreviewGeneration(__unused void* thisInterface, __unused QLPreviewRequestRef preview)
103 | {
104 | }
105 |
106 | CF_RETURNS_RETAINED static CFDictionaryRef _create_properties(CFURLRef url, const size_t size, const size_t width, const size_t height, const size_t dpi, const bool b)
107 | {
108 | // Format file size
109 | NSString* fmt = nil;
110 | if (size > 1048576) // More than 1Mb
111 | fmt = [[NSString alloc] initWithFormat:@"%.1fMb", (float)((float)size / 1048576.0f)];
112 | else if ((size < 1048576) && (size > 1024)) // 1Kb - 1Mb
113 | fmt = [[NSString alloc] initWithFormat:@"%.2fKb", (float)((float)size / 1024.0f)];
114 | else // Less than 1Kb
115 | fmt = [[NSString alloc] initWithFormat:@"%zub", size];
116 |
117 | // Get filename
118 | CFStringRef filename = CFURLCopyLastPathComponent(url);
119 |
120 | // Create props
121 | CFDictionaryRef properties = NULL;
122 | if (b)
123 | {
124 | CFTypeRef keys[3] = {kQLPreviewPropertyDisplayNameKey, kQLPreviewPropertyWidthKey, kQLPreviewPropertyHeightKey};
125 | // WIDTH×HEIGHTpx • 25.01Kb • filename
126 | CFStringRef title = dpi > 0 ? CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d×%dpx (%ddpi) • %@ • %@"), (int)width, (int)height, (int)dpi, fmt, filename) : CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d×%dpx • %@ • %@"), (int)width, (int)height, fmt, filename);
127 | CFTypeRef values[3] = {title, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &width), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &height)};
128 | properties = CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, (const void**)values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
129 | SAFE_CFRelease(values[0]);
130 | SAFE_CFRelease(values[1]);
131 | SAFE_CFRelease(values[2]);
132 | }
133 | else
134 | {
135 | CFTypeRef keys[1] = {kQLPreviewPropertyDisplayNameKey};
136 | // WIDTH×HEIGHTpx • 25.01Kb • filename
137 | CFStringRef title = dpi > 0 ? CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d×%dpx (%ddpi) • %@ • %@"), (int)width, (int)height, (int)dpi, fmt, filename) : CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d×%dpx • %@ • %@"), (int)width, (int)height, fmt, filename);
138 | CFTypeRef values[1] = {title};
139 | properties = CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, (const void**)values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
140 | SAFE_CFRelease(values[0]);
141 | }
142 |
143 | SAFE_CFRelease(filename);
144 |
145 | return properties;
146 | }
147 |
--------------------------------------------------------------------------------
/qlgenerator/src/GenerateThumbnailForURL.m:
--------------------------------------------------------------------------------
1 | //
2 | // GenerateThumbnailForURL.c
3 | // qlImageSize
4 | //
5 | // Created by @Nyx0uf on 31/01/12.
6 | // Copyright (c) 2012 Nyx0uf. All rights reserved.
7 | //
8 |
9 |
10 | #import
11 | #import "tools.h"
12 |
13 | #ifdef NYX_QL_SUPPORT_BPG_DECODE
14 | #import "bpg_decode.h"
15 | #endif
16 |
17 | #ifdef NYX_QL_SUPPORT_WEBP_DECODE
18 | #import "webp_decode.h"
19 | #endif
20 |
21 | #ifdef NYX_QL_SUPPORT_NETPBM_DECODE
22 | #import "netpbm_decode.h"
23 | #endif
24 |
25 |
26 | OSStatus GenerateThumbnailForURL(void* thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize);
27 | void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail);
28 | void HandleFileForThumbnail(CFURLRef url, CGImageRef (*decode_fn_ptr)(CFStringRef, image_infos*), QLThumbnailRequestRef thumbnail);
29 |
30 |
31 | OSStatus GenerateThumbnailForURL(__unused void* thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, __unused CFStringRef contentTypeUTI, __unused CFDictionaryRef options, __unused CGSize maxSize)
32 | {
33 | @autoreleasepool
34 | {
35 | // Check by extension because it's highly unprobable that an UTI for these formats is declared
36 | // the simplest way to declare one is creating a dummy automator app and adding imported/exported UTI conforming to public.image
37 | NSString* extension = [[(__bridge NSURL*)url pathExtension] lowercaseString];
38 | CFDictionaryRef properties = NULL;
39 |
40 | #ifdef NYX_QL_SUPPORT_BPG_DECODE
41 | if ([extension isEqualToString:@"bpg"])
42 | {
43 | HandleFileForThumbnail(url, &decode_bpg_at_path, thumbnail);
44 | return kQLReturnNoError;
45 | }
46 | #endif
47 | #ifdef NYX_QL_SUPPORT_WEBP_DECODE
48 | if ([extension isEqualToString:@"webp"])
49 | {
50 | HandleFileForThumbnail(url, &decode_webp_at_path, thumbnail);
51 | return kQLReturnNoError;
52 | }
53 | #endif
54 | #ifdef NYX_QL_SUPPORT_NETPBM_DECODE
55 | if ([extension isEqualToString:@"ppm"] || [extension isEqualToString:@"pgm"] || [extension isEqualToString:@"pbm"])
56 | {
57 | HandleFileForThumbnail(url, &decode_netpbm_at_path, thumbnail);
58 | return kQLReturnNoError;
59 | }
60 | #endif
61 | QLThumbnailRequestSetImageAtURL(thumbnail, url, properties);
62 | }
63 | return kQLReturnNoError;
64 | }
65 |
66 | void HandleFileForThumbnail(CFURLRef url, CGImageRef (*decode_fn_ptr)(CFStringRef, image_infos*), QLThumbnailRequestRef thumbnail)
67 | {
68 | CFDictionaryRef properties = NULL;
69 | if (!QLThumbnailRequestIsCancelled(thumbnail))
70 | {
71 | // 1. decode the image
72 | CFStringRef filepath = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
73 | CGImageRef img_ref = decode_fn_ptr(filepath, NULL);
74 | SAFE_CFRelease(filepath);
75 |
76 | // 2. render it
77 | if (img_ref != NULL)
78 | {
79 | QLThumbnailRequestSetImage(thumbnail, img_ref, properties);
80 | CGImageRelease(img_ref);
81 | }
82 | else
83 | QLThumbnailRequestSetImageAtURL(thumbnail, url, properties);
84 | }
85 | else
86 | QLThumbnailRequestSetImageAtURL(thumbnail, url, properties);
87 | }
88 |
89 | void CancelThumbnailGeneration(__unused void* thisInterface, __unused QLThumbnailRequestRef thumbnail)
90 | {
91 | }
92 |
--------------------------------------------------------------------------------
/qlgenerator/src/main.m:
--------------------------------------------------------------------------------
1 | //==============================================================================
2 | //
3 | // DO NO MODIFY THE CONTENT OF THIS FILE
4 | //
5 | // This file contains the generic CFPlug-in code necessary for your generator
6 | // To complete your generator implement the function in GenerateThumbnailForURL/GeneratePreviewForURL.c
7 | //
8 | //==============================================================================
9 |
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | // -----------------------------------------------------------------------------
16 | // constants
17 | // -----------------------------------------------------------------------------
18 |
19 | // Don't modify this line
20 | #define PLUGIN_ID "B39D1988-F7D1-4420-B89F-4627490F6326"
21 |
22 | //
23 | // Below is the generic glue code for all plug-ins.
24 | //
25 | // You should not have to modify this code aside from changing
26 | // names if you decide to change the names defined in the Info.plist
27 | //
28 |
29 |
30 | // -----------------------------------------------------------------------------
31 | // typedefs
32 | // -----------------------------------------------------------------------------
33 |
34 | // The thumbnail generation function to be implemented in GenerateThumbnailForURL.c
35 | OSStatus GenerateThumbnailForURL(void* thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize);
36 | void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail);
37 |
38 | // The preview generation function to be implemented in GeneratePreviewForURL.c
39 | OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options);
40 | void CancelPreviewGeneration(void* thisInterface, QLPreviewRequestRef preview);
41 |
42 | // The layout for an instance of QuickLookGeneratorPlugIn
43 | typedef struct __QuickLookGeneratorPluginType
44 | {
45 | void* conduitInterface;
46 | CFUUIDRef factoryID;
47 | UInt32 refCount;
48 | } QuickLookGeneratorPluginType;
49 |
50 | // -----------------------------------------------------------------------------
51 | // prototypes
52 | // -----------------------------------------------------------------------------
53 | // Forward declaration for the IUnknown implementation.
54 | //
55 |
56 | QuickLookGeneratorPluginType* AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID);
57 | void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType* thisInstance);
58 | HRESULT QuickLookGeneratorQueryInterface(void* thisInstance, REFIID iid, LPVOID* ppv);
59 | void* QuickLookGeneratorPluginFactory(CFAllocatorRef allocator, CFUUIDRef typeID);
60 | ULONG QuickLookGeneratorPluginAddRef(void* thisInstance);
61 | ULONG QuickLookGeneratorPluginRelease(void* thisInstance);
62 |
63 | // -----------------------------------------------------------------------------
64 | // myInterfaceFtbl definition
65 | // -----------------------------------------------------------------------------
66 | // The QLGeneratorInterfaceStruct function table.
67 | //
68 | static QLGeneratorInterfaceStruct myInterfaceFtbl = {
69 | NULL,
70 | QuickLookGeneratorQueryInterface,
71 | QuickLookGeneratorPluginAddRef,
72 | QuickLookGeneratorPluginRelease,
73 | NULL,
74 | NULL,
75 | NULL,
76 | NULL
77 | };
78 |
79 |
80 | // -----------------------------------------------------------------------------
81 | // AllocQuickLookGeneratorPluginType
82 | // -----------------------------------------------------------------------------
83 | // Utility function that allocates a new instance.
84 | // You can do some initial setup for the generator here if you wish
85 | // like allocating globals etc...
86 | //
87 | QuickLookGeneratorPluginType* AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID)
88 | {
89 | QuickLookGeneratorPluginType* theNewInstance;
90 |
91 | theNewInstance = (QuickLookGeneratorPluginType*)malloc(sizeof(QuickLookGeneratorPluginType));
92 | memset(theNewInstance, 0, sizeof(QuickLookGeneratorPluginType));
93 |
94 | /* Point to the function table Malloc enough to store the stuff and copy the filler from myInterfaceFtbl over */
95 | theNewInstance->conduitInterface = malloc(sizeof(QLGeneratorInterfaceStruct));
96 | memcpy(theNewInstance->conduitInterface, &myInterfaceFtbl, sizeof(QLGeneratorInterfaceStruct));
97 |
98 | /* Retain and keep an open instance refcount for each factory. */
99 | theNewInstance->factoryID = CFRetain(inFactoryID);
100 | CFPlugInAddInstanceForFactory(inFactoryID);
101 |
102 | /* This function returns the IUnknown interface so set the refCount to one. */
103 | theNewInstance->refCount = 1;
104 | return theNewInstance;
105 | }
106 |
107 | // -----------------------------------------------------------------------------
108 | // DeallocQuickLookGeneratorPluginType
109 | // -----------------------------------------------------------------------------
110 | // Utility function that deallocates the instance when
111 | // the refCount goes to zero.
112 | // In the current implementation generator interfaces are never deallocated
113 | // but implement this as this might change in the future
114 | //
115 | void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType* thisInstance)
116 | {
117 | CFUUIDRef theFactoryID;
118 |
119 | theFactoryID = thisInstance->factoryID;
120 | /* Free the conduitInterface table up */
121 | free(thisInstance->conduitInterface);
122 |
123 | /* Free the instance structure */
124 | free(thisInstance);
125 | if (theFactoryID)
126 | {
127 | CFPlugInRemoveInstanceForFactory(theFactoryID);
128 | CFRelease(theFactoryID);
129 | }
130 | }
131 |
132 | // -----------------------------------------------------------------------------
133 | // QuickLookGeneratorQueryInterface
134 | // -----------------------------------------------------------------------------
135 | // Implementation of the IUnknown QueryInterface function.
136 | //
137 | HRESULT QuickLookGeneratorQueryInterface(void* thisInstance, REFIID iid, LPVOID* ppv)
138 | {
139 | CFUUIDRef interfaceID;
140 |
141 | interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid);
142 |
143 | if (CFEqual(interfaceID, kQLGeneratorCallbacksInterfaceID))
144 | {
145 | /* If the Right interface was requested, bump the ref count,
146 | * set the ppv parameter equal to the instance, and
147 | * return good status.
148 | */
149 | ((QLGeneratorInterfaceStruct*)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->GenerateThumbnailForURL = GenerateThumbnailForURL;
150 | ((QLGeneratorInterfaceStruct*)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->CancelThumbnailGeneration = CancelThumbnailGeneration;
151 | ((QLGeneratorInterfaceStruct*)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->GeneratePreviewForURL = GeneratePreviewForURL;
152 | ((QLGeneratorInterfaceStruct*)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->CancelPreviewGeneration = CancelPreviewGeneration;
153 | ((QLGeneratorInterfaceStruct*)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->AddRef(thisInstance);
154 | *ppv = thisInstance;
155 | CFRelease(interfaceID);
156 | return S_OK;
157 | }
158 | else
159 | {
160 | /* Requested interface unknown, bail with error. */
161 | *ppv = NULL;
162 | CFRelease(interfaceID);
163 | return E_NOINTERFACE;
164 | }
165 | }
166 |
167 | // -----------------------------------------------------------------------------
168 | // QuickLookGeneratorPluginAddRef
169 | // -----------------------------------------------------------------------------
170 | // Implementation of reference counting for this type. Whenever an interface
171 | // is requested, bump the refCount for the instance. NOTE: returning the
172 | // refcount is a convention but is not required so don't rely on it.
173 | //
174 | ULONG QuickLookGeneratorPluginAddRef(void* thisInstance)
175 | {
176 | ((QuickLookGeneratorPluginType*)thisInstance)->refCount += 1;
177 | return ((QuickLookGeneratorPluginType*)thisInstance)->refCount;
178 | }
179 |
180 | // -----------------------------------------------------------------------------
181 | // QuickLookGeneratorPluginRelease
182 | // -----------------------------------------------------------------------------
183 | // When an interface is released, decrement the refCount.
184 | // If the refCount goes to zero, deallocate the instance.
185 | //
186 | ULONG QuickLookGeneratorPluginRelease(void* thisInstance)
187 | {
188 | ((QuickLookGeneratorPluginType*)thisInstance)->refCount -= 1;
189 | if (((QuickLookGeneratorPluginType*)thisInstance)->refCount == 0)
190 | {
191 | DeallocQuickLookGeneratorPluginType((QuickLookGeneratorPluginType*)thisInstance);
192 | return 0;
193 | }
194 | else
195 | {
196 | return ((QuickLookGeneratorPluginType*)thisInstance)->refCount;
197 | }
198 | }
199 |
200 | // -----------------------------------------------------------------------------
201 | // QuickLookGeneratorPluginFactory
202 | // -----------------------------------------------------------------------------
203 | void* QuickLookGeneratorPluginFactory(CFAllocatorRef __unused allocator, CFUUIDRef typeID)
204 | {
205 | QuickLookGeneratorPluginType* result;
206 | CFUUIDRef uuid;
207 |
208 | /* If correct type is being requested, allocate an
209 | * instance of kQLGeneratorTypeID and return the IUnknown interface.
210 | */
211 | if (CFEqual(typeID, kQLGeneratorTypeID))
212 | {
213 | uuid = CFUUIDCreateFromString(kCFAllocatorDefault, CFSTR(PLUGIN_ID));
214 | result = AllocQuickLookGeneratorPluginType(uuid);
215 | CFRelease(uuid);
216 | return result;
217 | }
218 | /* If the requested type is incorrect, return NULL. */
219 | return NULL;
220 | }
221 |
--------------------------------------------------------------------------------