1 /*
2  * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
3  * License: https://github.com/bkaradzic/bimg#license-bsd-2-clause
4  */
5 
6 #ifndef BIMG_IMAGE_H_HEADER_GUARD
7 #define BIMG_IMAGE_H_HEADER_GUARD
8 
9 #include <stdint.h> // uint32_t
10 #include <stdlib.h> // NULL
11 
12 #define BIMG_API_VERSION UINT32_C(7)
13 
14 namespace bx
15 {
16 	struct AllocatorI;
17 	class  Error;
18 	struct ReaderSeekerI;
19 	struct WriterI;
20 
21 } // namespace bx
22 
23 namespace bimg
24 {
25 	typedef void (*PackFn)(void*, const float*);
26 	typedef void (*UnpackFn)(float*, const void*);
27 
28 	/// Texture format enum.
29 	///
30 	/// Notation:
31 	///
32 	///       RGBA16S
33 	///       ^   ^ ^
34 	///       |   | +-- [ ]Unorm
35 	///       |   |     [F]loat
36 	///       |   |     [S]norm
37 	///       |   |     [I]nt
38 	///       |   |     [U]int
39 	///       |   +---- Number of bits per component
40 	///       +-------- Components
41 	///
42 	/// @attention Availability depends on Caps (see: formats).
43 	///
44 	/// @attention C99 equivalent is `bgfx_texture_format_t`.
45 	///
46 	struct TextureFormat
47 	{
48 		/// Texture formats:
49 		enum Enum
50 		{
51 			BC1,          //!< DXT1
52 			BC2,          //!< DXT3
53 			BC3,          //!< DXT5
54 			BC4,          //!< LATC1/ATI1
55 			BC5,          //!< LATC2/ATI2
56 			BC6H,         //!< BC6H
57 			BC7,          //!< BC7
58 			ETC1,         //!< ETC1 RGB8
59 			ETC2,         //!< ETC2 RGB8
60 			ETC2A,        //!< ETC2 RGBA8
61 			ETC2A1,       //!< ETC2 RGB8A1
62 			PTC12,        //!< PVRTC1 RGB 2BPP
63 			PTC14,        //!< PVRTC1 RGB 4BPP
64 			PTC12A,       //!< PVRTC1 RGBA 2BPP
65 			PTC14A,       //!< PVRTC1 RGBA 4BPP
66 			PTC22,        //!< PVRTC2 RGBA 2BPP
67 			PTC24,        //!< PVRTC2 RGBA 4BPP
68 			ATC,          //!< ATC RGB 4BPP
69 			ATCE,         //!< ATCE RGBA 8 BPP explicit alpha
70 			ATCI,         //!< ATCI RGBA 8 BPP interpolated alpha
71 			ASTC4x4,      //!< ASTC 4x4 8.0 BPP
72 			ASTC5x5,      //!< ASTC 5x5 5.12 BPP
73 			ASTC6x6,      //!< ASTC 6x6 3.56 BPP
74 			ASTC8x5,      //!< ASTC 8x5 3.20 BPP
75 			ASTC8x6,      //!< ASTC 8x6 2.67 BPP
76 			ASTC10x5,     //!< ASTC 10x5 2.56 BPP
77 
78 			Unknown,      // Compressed formats above.
79 
80 			R1,
81 			A8,
82 			R8,
83 			R8I,
84 			R8U,
85 			R8S,
86 			R16,
87 			R16I,
88 			R16U,
89 			R16F,
90 			R16S,
91 			R32I,
92 			R32U,
93 			R32F,
94 			RG8,
95 			RG8I,
96 			RG8U,
97 			RG8S,
98 			RG16,
99 			RG16I,
100 			RG16U,
101 			RG16F,
102 			RG16S,
103 			RG32I,
104 			RG32U,
105 			RG32F,
106 			RGB8,
107 			RGB8I,
108 			RGB8U,
109 			RGB8S,
110 			RGB9E5F,
111 			BGRA8,
112 			RGBA8,
113 			RGBA8I,
114 			RGBA8U,
115 			RGBA8S,
116 			RGBA16,
117 			RGBA16I,
118 			RGBA16U,
119 			RGBA16F,
120 			RGBA16S,
121 			RGBA32I,
122 			RGBA32U,
123 			RGBA32F,
124 			R5G6B5,
125 			RGBA4,
126 			RGB5A1,
127 			RGB10A2,
128 			RG11B10F,
129 
130 			UnknownDepth, // Depth formats below.
131 
132 			D16,
133 			D24,
134 			D24S8,
135 			D32,
136 			D16F,
137 			D24F,
138 			D32F,
139 			D0S8,
140 
141 			Count
142 		};
143 	};
144 
145 	///
146 	struct Orientation
147 	{
148 		///
149 		enum Enum
150 		{
151 			R0,
152 			R90,
153 			R180,
154 			R270,
155 			HFlip,
156 			HFlipR90,
157 			HFlipR270,
158 			VFlip,
159 		};
160 	};
161 
162 	/// Texture info.
163 	///
164 	/// @attention C99 equivalent is `bgfx_texture_info_t`.
165 	///
166 	struct TextureInfo
167 	{
168 		TextureFormat::Enum format; //!< Texture format.
169 		uint32_t storageSize;       //!< Total amount of bytes required to store texture.
170 		uint16_t width;             //!< Texture width.
171 		uint16_t height;            //!< Texture height.
172 		uint16_t depth;             //!< Texture depth.
173 		uint16_t numLayers;         //!< Number of layers in texture array.
174 		uint8_t numMips;            //!< Number of MIP maps.
175 		uint8_t bitsPerPixel;       //!< Format bits per pixel.
176 		bool    cubeMap;            //!< Texture is cubemap.
177 	};
178 
179 	struct ImageContainer
180 	{
181 		bx::AllocatorI* m_allocator;
182 		void*           m_data;
183 
184 		TextureFormat::Enum m_format;
185 		Orientation::Enum m_orientation;
186 
187 		uint32_t m_size;
188 		uint32_t m_offset;
189 		uint32_t m_width;
190 		uint32_t m_height;
191 		uint32_t m_depth;
192 		uint16_t m_numLayers;
193 		uint8_t  m_numMips;
194 		bool     m_hasAlpha;
195 		bool     m_cubeMap;
196 		bool     m_ktx;
197 		bool     m_ktxLE;
198 		bool     m_srgb;
199 	};
200 
201 	struct ImageMip
202 	{
203 		TextureFormat::Enum m_format;
204 		uint32_t m_width;
205 		uint32_t m_height;
206 		uint32_t m_depth;
207 		uint32_t m_blockSize;
208 		uint32_t m_size;
209 		uint8_t  m_bpp;
210 		bool     m_hasAlpha;
211 		const uint8_t* m_data;
212 	};
213 
214 	struct ImageBlockInfo
215 	{
216 		uint8_t bitsPerPixel;
217 		uint8_t blockWidth;
218 		uint8_t blockHeight;
219 		uint8_t blockSize;
220 		uint8_t minBlockX;
221 		uint8_t minBlockY;
222 		uint8_t depthBits;
223 		uint8_t stencilBits;
224 		uint8_t rBits;
225 		uint8_t gBits;
226 		uint8_t bBits;
227 		uint8_t aBits;
228 		uint8_t encoding;
229 	};
230 
231 	/// Returns true if texture format is compressed.
232 	bool isCompressed(TextureFormat::Enum _format);
233 
234 	/// Returns true if texture format is uncompressed.
235 	bool isColor(TextureFormat::Enum _format);
236 
237 	/// Returns true if texture format is depth.
238 	bool isDepth(TextureFormat::Enum _format);
239 
240 	/// Returns true if texture format is valid.
241 	bool isValid(TextureFormat::Enum _format);
242 
243 	/// returns true if texture format encoding is float.
244 	bool isFloat(TextureFormat::Enum _format);
245 
246 	/// Returns bits per pixel.
247 	uint8_t getBitsPerPixel(TextureFormat::Enum _format);
248 
249 	/// Returns texture block info.
250 	const ImageBlockInfo& getBlockInfo(TextureFormat::Enum _format);
251 
252 	/// Converts format to string.
253 	const char* getName(TextureFormat::Enum _format);
254 
255 	/// Converts string to format.
256 	TextureFormat::Enum getFormat(const char* _name);
257 
258 	/// Returns number of mip-maps required for complete mip-map chain.
259 	uint8_t imageGetNumMips(
260 		  TextureFormat::Enum _format
261 		, uint16_t _width
262 		, uint16_t _height
263 		, uint16_t _depth = 0
264 		);
265 
266 	/// Returns image size.
267 	uint32_t imageGetSize(
268 		  TextureInfo* _info
269 		, uint16_t _width
270 		, uint16_t _height
271 		, uint16_t _depth
272 		, bool _cubeMap
273 		, bool _hasMips
274 		, uint16_t _numLayers
275 		, TextureFormat::Enum _format
276 		);
277 
278 	///
279 	void imageSolid(
280 		  void* _dst
281 		, uint32_t _width
282 		, uint32_t _height
283 		, uint32_t _solid
284 		);
285 
286 	///
287 	void imageCheckerboard(
288 		  void* _dst
289 		, uint32_t _width
290 		, uint32_t _height
291 		, uint32_t _step
292 		, uint32_t _0
293 		, uint32_t _1
294 		);
295 
296 	///
297 	void imageRgba8Downsample2x2(
298 		  void* _dst
299 		, uint32_t _width
300 		, uint32_t _height
301 		, uint32_t _depth
302 		, uint32_t _srcPitch
303 		, uint32_t _dstPitch
304 		, const void* _src
305 		);
306 
307 	///
308 	void imageRgba32fToLinear(
309 		  void* _dst
310 		, uint32_t _width
311 		, uint32_t _height
312 		, uint32_t _depth
313 		, uint32_t _srcPitch
314 		, const void* _src
315 		);
316 
317 	///
318 	void imageRgba32fToLinear(ImageContainer* _imageContainer);
319 
320 	///
321 	void imageRgba32fToGamma(
322 		  void* _dst
323 		, uint32_t _width
324 		, uint32_t _height
325 		, uint32_t _depth
326 		, uint32_t _srcPitch
327 		, const void* _src
328 		);
329 
330 	///
331 	void imageRgba32fToGamma(ImageContainer* _imageContainer);
332 
333 	///
334 	void imageRgba32fLinearDownsample2x2(
335 		  void* _dst
336 		, uint32_t _width
337 		, uint32_t _height
338 		, uint32_t _depth
339 		, uint32_t _srcPitch
340 		, const void* _src
341 		);
342 
343 	///
344 	void imageRgba32fDownsample2x2(
345 		  void* _dst
346 		, uint32_t _width
347 		, uint32_t _height
348 		, uint32_t _depth
349 		, uint32_t _srcPitch
350 		, const void* _src
351 		);
352 
353 	///
354 	void imageRgba32fDownsample2x2NormalMap(
355 		  void* _dst
356 		, uint32_t _width
357 		, uint32_t _height
358 		, uint32_t _srcPitch
359 		, uint32_t _dstPitch
360 		, const void* _src
361 		);
362 
363 	///
364 	void imageSwizzleBgra8(
365 		  void* _dst
366 		, uint32_t _dstPitch
367 		, uint32_t _width
368 		, uint32_t _height
369 		, const void* _src
370 		, uint32_t _srcPitch
371 		);
372 
373 	///
374 	void imageCopy(
375 		  void* _dst
376 		, uint32_t _height
377 		, uint32_t _srcPitch
378 		, uint32_t _depth
379 		, const void* _src
380 		, uint32_t _dstPitch
381 		);
382 
383 	///
384 	void imageCopy(
385 		  void* _dst
386 		, uint32_t _width
387 		, uint32_t _height
388 		, uint32_t _depth
389 		, uint32_t _bpp
390 		, uint32_t _srcPitch
391 		, const void* _src
392 		);
393 
394 	///
395 	PackFn getPack(TextureFormat::Enum _format);
396 
397 	///
398 	UnpackFn getUnpack(TextureFormat::Enum _format);
399 
400 	///
401 	bool imageConvert(
402 		  TextureFormat::Enum _dstFormat
403 		, TextureFormat::Enum _srcFormat
404 		);
405 
406 	///
407 	void imageConvert(
408 		  void* _dst
409 		, uint32_t _bpp
410 		, PackFn _pack
411 		, const void* _src
412 		, UnpackFn _unpack
413 		, uint32_t _size
414 		);
415 
416 	///
417 	void imageConvert(
418 		  void* _dst
419 		, uint32_t _dstBpp
420 		, PackFn _pack
421 		, const void* _src
422 		, uint32_t _srcBpp
423 		, UnpackFn _unpack
424 		, uint32_t _width
425 		, uint32_t _height
426 		, uint32_t _depth
427 		, uint32_t _srcPitch
428 		, uint32_t _dstPitch
429 		);
430 
431 	///
432 	bool imageConvert(
433 		  bx::AllocatorI* _allocator
434 		, void* _dst
435 		, TextureFormat::Enum _dstFormat
436 		, const void* _src
437 		, TextureFormat::Enum _srcFormat
438 		, uint32_t _width
439 		, uint32_t _height
440 		, uint32_t _depth
441 		);
442 
443 	///
444 	ImageContainer* imageConvert(
445 		  bx::AllocatorI* _allocator
446 		, TextureFormat::Enum _dstFormat
447 		, const void* _src
448 		, uint32_t _size
449 		);
450 
451 	///
452 	ImageContainer* imageConvert(
453 		  bx::AllocatorI* _allocator
454 		, TextureFormat::Enum _dstFormat
455 		, const ImageContainer& _input
456 		, bool _convertMips = true
457 		);
458 
459 	///
460 	ImageContainer* imageAlloc(
461 		  bx::AllocatorI* _allocator
462 		, TextureFormat::Enum _format
463 		, uint16_t _width
464 		, uint16_t _height
465 		, uint16_t _depth
466 		, uint16_t _numLayers
467 		, bool _cubeMap
468 		, bool _hasMips
469 		, const void* _data = NULL
470 		);
471 
472 	///
473 	void imageFree(
474 		  ImageContainer* _imageContainer
475 		);
476 
477 	///
478 	int32_t imageWriteTga(
479 		  bx::WriterI* _writer
480 		, uint32_t _width
481 		, uint32_t _height
482 		, uint32_t _srcPitch
483 		, const void* _src
484 		, bool _grayscale
485 		, bool _yflip
486 		, bx::Error* _err = NULL
487 		);
488 
489 	///
490 	int32_t imageWritePng(
491 		  bx::WriterI* _writer
492 		, uint32_t _width
493 		, uint32_t _height
494 		, uint32_t _srcPitch
495 		, const void* _src
496 		, TextureFormat::Enum _format
497 		, bool _yflip
498 		, bx::Error* _err = NULL
499 		);
500 
501 	///
502 	int32_t imageWriteExr(
503 		  bx::WriterI* _writer
504 		, uint32_t _width
505 		, uint32_t _height
506 		, uint32_t _srcPitch
507 		, const void* _src
508 		, TextureFormat::Enum _format
509 		, bool _yflip
510 		, bx::Error* _err
511 		);
512 
513 	///
514 	int32_t imageWriteHdr(
515 		  bx::WriterI* _writer
516 		, uint32_t _width
517 		, uint32_t _height
518 		, uint32_t _srcPitch
519 		, const void* _src
520 		, TextureFormat::Enum _format
521 		, bool _yflip
522 		, bx::Error* _err
523 		);
524 
525 	///
526 	int32_t imageWriteDds(
527 		  bx::WriterI* _writer
528 		, ImageContainer& _imageContainer
529 		, const void* _data
530 		, uint32_t _size
531 		, bx::Error* _err
532 		);
533 
534 	///
535 	int32_t imageWriteKtx(
536 		  bx::WriterI* _writer
537 		, TextureFormat::Enum _format
538 		, bool _cubeMap
539 		, uint32_t _width
540 		, uint32_t _height
541 		, uint32_t _depth
542 		, uint8_t _numMips
543 		, uint32_t _numLayers
544 		, const void* _src
545 		, bx::Error* _err = NULL
546 		);
547 
548 	///
549 	int32_t imageWriteKtx(
550 		  bx::WriterI* _writer
551 		, ImageContainer& _imageContainer
552 		, const void* _data
553 		, uint32_t _size
554 		, bx::Error* _err = NULL
555 		);
556 
557 	///
558 	bool imageParse(
559 		  ImageContainer& _imageContainer
560 		, bx::ReaderSeekerI* _reader
561 		, bx::Error* _err
562 		);
563 
564 	///
565 	bool imageParse(
566 		  ImageContainer& _imageContainer
567 		, const void* _data
568 		, uint32_t _size
569 		, bx::Error* _err = NULL
570 		);
571 
572 	///
573 	ImageContainer* imageParseDds(
574 		  bx::AllocatorI* _allocator
575 		, const void* _src
576 		, uint32_t _size
577 		, bx::Error* _err
578 		);
579 
580 	///
581 	ImageContainer* imageParseKtx(
582 		  bx::AllocatorI* _allocator
583 		, const void* _src
584 		, uint32_t _size
585 		, bx::Error* _err
586 		);
587 
588 	///
589 	ImageContainer* imageParsePvr3(
590 		  bx::AllocatorI* _allocator
591 		, const void* _src
592 		, uint32_t _size
593 		, bx::Error* _err
594 		);
595 
596 	///
597 	ImageContainer* imageParseGnf(
598 		  bx::AllocatorI* _allocator
599 		, const void* _src
600 		, uint32_t _size
601 		, bx::Error* _err
602 		);
603 
604 	///
605 	void imageDecodeToR8(
606 		  bx::AllocatorI* _allocator
607 		, void* _dst
608 		, const void* _src
609 		, uint32_t _width
610 		, uint32_t _height
611 		, uint32_t _depth
612 		, uint32_t _dstPitch
613 		, TextureFormat::Enum _srcFormat
614 	);
615 
616 	///
617 	void imageDecodeToBgra8(
618 		  bx::AllocatorI* _allocator
619 		, void* _dst
620 		, const void* _src
621 		, uint32_t _width
622 		, uint32_t _height
623 		, uint32_t _dstPitch
624 		, TextureFormat::Enum _format
625 		);
626 
627 	///
628 	void imageDecodeToRgba8(
629 		  bx::AllocatorI* _allocator
630 		, void* _dst
631 		, const void* _src
632 		, uint32_t _width
633 		, uint32_t _height
634 		, uint32_t _dstPitch
635 		, TextureFormat::Enum _format
636 		);
637 
638 	///
639 	void imageDecodeToRgba32f(
640 		  bx::AllocatorI* _allocator
641 		, void* _dst
642 		, const void* _src
643 		, uint32_t _width
644 		, uint32_t _height
645 		, uint32_t _depth
646 		, uint32_t _dstPitch
647 		, TextureFormat::Enum _format
648 		);
649 
650 	///
651 	bool imageGetRawData(
652 		  const ImageContainer& _imageContainer
653 		, uint16_t _side
654 		, uint8_t _lod
655 		, const void* _data
656 		, uint32_t _size
657 		, ImageMip& _mip
658 		);
659 
660 } // namespace bimg
661 
662 #endif // BIMG_IMAGE_H_HEADER_GUARD
663