SourcePP
Several modern C++20 libraries for sanely parsing Valve's formats.
Loading...
Searching...
No Matches
ImageFormats.h
Go to the documentation of this file.
1// ReSharper disable CppDFAUnreachableFunctionCall
2// ReSharper disable CppRedundantParentheses
3// ReSharper disable CppRedundantQualifier
4
5#pragma once
6
7#include <tuple>
8
9#include <sourcepp/Math.h>
10
11namespace vtfpp {
12
94
96
103[[nodiscard]] constexpr int8_t red(ImageFormat format) {
104 switch (format) {
105 using enum ImageFormat;
106 case R32F:
107 case RG3232F:
108 case RGB323232F:
109 case RGBA32323232F:
110 return 32;
111 case R16F:
112 case RG1616F:
113 case RGBA16161616F:
114 case RGBA16161616:
116 return 16;
117 case RGBA1010102:
118 case BGRA1010102:
119 return 10;
120 case RGBA8888:
122 case ABGR8888:
124 case RGB888:
126 case BGR888:
128 case I8:
130 case IA88:
131 case P8:
134 case ARGB8888:
136 case BGRA8888:
139 case BGRX8888:
142 case UV88:
143 case UVWQ8888:
144 case UVLX8888:
145 case RGBX8888:
146 case STRATA_R8:
147 return 8;
148 case RGB565:
149 case BGR565:
150 case BGRX5551:
152 case BGRA5551:
153 return 5;
154 case BGRA4444:
155 return 4;
156 case A8:
157 case EMPTY:
158 return 0;
159 case DXT1:
160 case DXT3:
161 case DXT5:
163 case ATI2N:
164 case ATI1N:
165 case TITANFALL_BC6H:
166 case TITANFALL_BC7:
167 case STRATA_BC7:
168 case STRATA_BC6H_SF:
169 case STRATA_BC6H_UF:
170 case STRATA_BC5:
171 case STRATA_BC4:
175 return -1;
176 }
177 return 0;
178}
179
185[[nodiscard]] constexpr int8_t decompressedRed(ImageFormat format) {
186 // This is merely for convenience, the true size may be different depending on the data
187 switch (format) {
188 using enum ImageFormat;
189 case DXT1:
191 case DXT3:
192 case DXT5:
193 case ATI2N:
194 case ATI1N:
195 case TITANFALL_BC7:
196 case STRATA_BC7:
197 case STRATA_BC5:
198 case STRATA_BC4:
199 return 8;
200 case TITANFALL_BC6H:
201 case STRATA_BC6H_SF:
202 case STRATA_BC6H_UF:
206 return 16;
207 default:
208 break;
209 }
210 return red(format);
211}
212
219[[nodiscard]] constexpr int8_t green(ImageFormat format) {
220 switch (format) {
221 using enum ImageFormat;
222 case RG3232F:
223 case RGB323232F:
224 case RGBA32323232F:
225 return 32;
226 case RG1616F:
227 case RGBA16161616F:
228 case RGBA16161616:
230 return 16;
231 case RGBA1010102:
232 case BGRA1010102:
233 return 10;
234 case RGBA8888:
236 case ABGR8888:
238 case RGB888:
240 case BGR888:
244 case ARGB8888:
246 case BGRA8888:
249 case BGRX8888:
252 case UV88:
253 case UVWQ8888:
254 case UVLX8888:
255 case RGBX8888:
256 return 8;
257 case RGB565:
258 case BGR565:
259 return 6;
260 case BGRX5551:
262 case BGRA5551:
263 return 5;
264 case BGRA4444:
265 return 4;
266 case I8:
268 case IA88:
269 case P8:
270 case R32F:
271 case A8:
272 case EMPTY:
273 case R16F:
274 case STRATA_R8:
275 return 0;
276 case DXT1:
277 case DXT3:
278 case DXT5:
280 case ATI2N:
281 case ATI1N:
282 case TITANFALL_BC6H:
283 case TITANFALL_BC7:
284 case STRATA_BC7:
285 case STRATA_BC6H_SF:
286 case STRATA_BC6H_UF:
287 case STRATA_BC5:
288 case STRATA_BC4:
292 return -1;
293 }
294 return 0;
295}
296
302[[nodiscard]] constexpr int8_t decompressedGreen(ImageFormat format) {
303 // This is merely for convenience, the true size may be different depending on the data
304 switch (format) {
305 using enum ImageFormat;
306 case DXT1:
308 case DXT3:
309 case DXT5:
310 case ATI2N:
311 case ATI1N:
312 case TITANFALL_BC7:
313 case STRATA_BC7:
314 case STRATA_BC5:
315 case STRATA_BC4:
316 return 8;
317 case TITANFALL_BC6H:
318 case STRATA_BC6H_SF:
319 case STRATA_BC6H_UF:
323 return 16;
324 default:
325 break;
326 }
327 return green(format);
328}
329
336[[nodiscard]] constexpr int8_t blue(ImageFormat format) {
337 switch (format) {
338 using enum ImageFormat;
339 case RGB323232F:
340 case RGBA32323232F:
341 return 32;
342 case RGBA16161616F:
343 case RGBA16161616:
345 return 16;
346 case RGBA1010102:
347 case BGRA1010102:
348 return 10;
349 case RGBA8888:
351 case ABGR8888:
353 case RGB888:
355 case BGR888:
359 case ARGB8888:
361 case BGRA8888:
364 case BGRX8888:
367 case UVWQ8888:
368 case UVLX8888:
369 case RGBX8888:
370 return 8;
371 case RGB565:
372 case BGR565:
373 case BGRX5551:
375 case BGRA5551:
376 return 5;
377 case BGRA4444:
378 return 4;
379 case I8:
381 case IA88:
382 case P8:
383 case UV88:
384 case R32F:
385 case A8:
386 case EMPTY:
387 case RG3232F:
388 case RG1616F:
389 case R16F:
390 case STRATA_R8:
391 return 0;
392 case DXT1:
393 case DXT3:
394 case DXT5:
396 case ATI2N:
397 case ATI1N:
398 case TITANFALL_BC6H:
399 case TITANFALL_BC7:
400 case STRATA_BC7:
401 case STRATA_BC6H_SF:
402 case STRATA_BC6H_UF:
403 case STRATA_BC5:
404 case STRATA_BC4:
408 return -1;
409 }
410 return 0;
411}
412
418[[nodiscard]] constexpr int8_t decompressedBlue(ImageFormat format) {
419 // This is merely for convenience, the true size may be different depending on the data
420 switch (format) {
421 using enum ImageFormat;
422 case DXT1:
424 case DXT3:
425 case DXT5:
426 case ATI2N:
427 case ATI1N:
428 case TITANFALL_BC7:
429 case STRATA_BC7:
430 case STRATA_BC5:
431 case STRATA_BC4:
432 return 8;
433 case TITANFALL_BC6H:
434 case STRATA_BC6H_SF:
435 case STRATA_BC6H_UF:
439 return 16;
440 default:
441 break;
442 }
443 return blue(format);
444}
445
452[[nodiscard]] constexpr int8_t alpha(ImageFormat format) {
453 switch (format) {
454 using enum ImageFormat;
455 case RGBA32323232F:
456 return 32;
457 case RGBA16161616F:
458 case RGBA16161616:
460 return 16;
461 case RGBA8888:
463 case ABGR8888:
465 case IA88:
466 case A8:
467 case ARGB8888:
469 case BGRA8888:
472 case BGRX8888:
475 case UVWQ8888:
476 case UVLX8888:
477 case RGBX8888:
478 return 8;
479 case BGRA4444:
480 return 4;
481 case RGBA1010102:
482 case BGRA1010102:
483 return 2;
484 case BGRX5551:
486 case BGRA5551:
487 return 1;
488 case RGB888:
490 case BGR888:
492 case P8:
493 case I8:
497 case UV88:
498 case RGB565:
499 case BGR565:
500 case R32F:
501 case RGB323232F:
502 case EMPTY:
503 case RG3232F:
504 case RG1616F:
505 case R16F:
506 case STRATA_R8:
507 return 0;
508 case DXT1:
509 case DXT3:
510 case DXT5:
512 case ATI2N:
513 case ATI1N:
514 case TITANFALL_BC6H:
515 case TITANFALL_BC7:
516 case STRATA_BC7:
517 case STRATA_BC6H_SF:
518 case STRATA_BC6H_UF:
519 case STRATA_BC5:
520 case STRATA_BC4:
524 return -1;
525 }
526 return 0;
527}
528
534[[nodiscard]] constexpr int8_t decompressedAlpha(ImageFormat format) {
535 // This is merely for convenience, the true size may be different depending on the data
536 switch (format) {
537 using enum ImageFormat;
538 case DXT5:
539 case TITANFALL_BC7:
540 case STRATA_BC7:
541 return 8;
542 case DXT3:
543 return 4;
545 return 1;
546 case DXT1:
547 case ATI2N:
548 case ATI1N:
549 case TITANFALL_BC6H:
550 case STRATA_BC6H_SF:
551 case STRATA_BC6H_UF:
552 case STRATA_BC5:
553 case STRATA_BC4:
557 return 0;
558 default:
559 break;
560 }
561 return alpha(format);
562}
563
570[[nodiscard]] constexpr uint8_t bpp(ImageFormat format) {
571 switch (format) {
572 using enum ImageFormat;
573 case RGBA32323232F:
574 return 128;
575 case RGB323232F:
576 return 96;
577 case RGBA16161616F:
578 case RGBA16161616:
582 case RG3232F:
583 return 64;
584 case RGBA8888:
586 case ABGR8888:
588 case ARGB8888:
590 case BGRA8888:
594 case BGRX8888:
597 case UVLX8888:
598 case R32F:
599 case UVWQ8888:
600 case RGBX8888:
601 case RGBA1010102:
602 case BGRA1010102:
603 case RG1616F:
604 return 32;
605 case RGB888:
607 case BGR888:
611 return 24;
612 case RGB565:
613 case BGR565:
614 case IA88:
615 case BGRX5551:
617 case BGRA4444:
618 case BGRA5551:
619 case UV88:
620 case R16F:
621 return 16;
622 case I8:
624 case P8:
625 case A8:
626 case DXT3:
627 case DXT5:
628 case ATI2N:
629 case TITANFALL_BC6H:
630 case TITANFALL_BC7:
631 case STRATA_R8:
632 case STRATA_BC7:
633 case STRATA_BC6H_SF:
634 case STRATA_BC6H_UF:
635 case STRATA_BC5:
636 return 8;
637 case ATI1N:
638 case DXT1:
640 case STRATA_BC4:
641 return 4;
642 case EMPTY:
643 return 0;
644 }
645 return 0;
646}
647
656[[nodiscard]] constexpr ImageFormat containerFormat(ImageFormat format) {
657 switch (format) {
658 using enum ImageFormat;
659 case R32F:
660 case RG3232F:
661 case RGB323232F:
662 case R16F:
663 case RG1616F:
664 case RGBA16161616F:
665 case RGBA32323232F:
666 case TITANFALL_BC6H:
667 case STRATA_BC6H_SF:
668 case STRATA_BC6H_UF:
672 return RGBA32323232F;
673 case RGBA16161616:
675 case RGBA1010102:
676 case BGRA1010102:
677 return RGBA16161616;
678 case RGBA8888:
680 case ABGR8888:
682 case RGB888:
684 case BGR888:
688 case ARGB8888:
690 case BGRA8888:
693 case BGRX8888:
696 case UVWQ8888:
697 case UVLX8888:
698 case RGB565:
699 case BGR565:
700 case BGRX5551:
702 case BGRA5551:
703 case BGRA4444:
704 case I8:
706 case IA88:
707 case P8:
708 case UV88:
709 case A8:
710 case DXT1:
711 case DXT3:
712 case DXT5:
714 case ATI2N:
715 case ATI1N:
716 case RGBX8888:
717 case TITANFALL_BC7:
718 case STRATA_R8:
719 case STRATA_BC7:
720 case STRATA_BC5:
721 case STRATA_BC4:
722 return RGBA8888;
723 case EMPTY:
724 break;
725 }
726 return ImageFormat::EMPTY;
727}
728
734[[nodiscard]] constexpr bool large(ImageFormat format) {
736}
737
743[[nodiscard]] constexpr bool decimal(ImageFormat format) {
745}
746
752[[nodiscard]] constexpr bool compressed(ImageFormat format) {
753 return red(format) == -1;
754}
755
761[[nodiscard]] constexpr bool compressedHDR(ImageFormat format) {
762 switch (format) {
763 using enum ImageFormat;
767 return true;
768 default:
769 break;
770 }
771 return false;
772}
773
779[[nodiscard]] constexpr bool transparent(ImageFormat format) {
780 const auto a = alpha(format);
781 if (a < 0) {
782 switch (format) {
783 using enum ImageFormat;
784 case DXT3:
785 case DXT5:
787 case TITANFALL_BC6H:
788 case TITANFALL_BC7:
789 case STRATA_BC7:
790 case STRATA_BC6H_SF:
791 case STRATA_BC6H_UF:
792 return true;
793 default:
794 break;
795 }
796 return false;
797 }
798 switch (format) {
799 using enum ImageFormat;
802 return true;
803 case BGRX8888:
806 case BGRX5551:
808 case UVLX8888:
809 case RGBX8888:
810 return false;
811 default:
812 break;
813 }
814 return a != 0;
815}
816
822[[nodiscard]] constexpr bool opaque(ImageFormat format) {
823 return !transparent(format);
824}
825
831[[nodiscard]] constexpr bool console(ImageFormat format) {
832 switch (format) {
833 using enum ImageFormat;
847 return true;
848 default:
849 break;
850 }
851 return false;
852}
853
859[[nodiscard]] constexpr bool titanfall(ImageFormat format) {
860 switch (format) {
861 using enum ImageFormat;
862 case TITANFALL_BC6H:
863 case TITANFALL_BC7:
864 return true;
865 default:
866 break;
867 }
868 return false;
869}
870
876[[nodiscard]] constexpr bool strata(ImageFormat format) {
877 switch (format) {
878 using enum ImageFormat;
879 case STRATA_R8:
880 case STRATA_BC7:
881 case STRATA_BC6H_SF:
882 case STRATA_BC6H_UF:
883 case STRATA_BC5:
884 case STRATA_BC4:
885 return true;
886 default:
887 break;
888 }
889 return false;
890}
891
892} // namespace ImageFormatDetails
893
895
905[[nodiscard]] constexpr uint16_t getMipDim(uint8_t mip, uint16_t dim, bool addCompressedFormatPadding = false) {
906 if (!dim) {
907 return 0;
908 }
909 for (int i = 0; i < mip && dim > 1; i++) {
910 dim >>= 1;
911 }
912 if (addCompressedFormatPadding) {
914 }
915 return dim;
916}
917
926[[nodiscard]] constexpr std::pair<uint16_t, uint16_t> getMipDims(uint8_t mip, uint16_t width, uint16_t height, bool addCompressedFormatPadding = false) {
927 const auto originalWidth = width, originalHeight = height;
928 for (int i = 0; i < mip && (width > 1 || height > 1); i++) {
929 if ((width >>= 1) < 1) width = 1;
930 if ((height >>= 1) < 1) height = 1;
931 }
932 if (addCompressedFormatPadding) {
933 width += sourcepp::math::paddingForAlignment(4, width);
934 height += sourcepp::math::paddingForAlignment(4, height);
935 }
936 return {!originalWidth ? 0 : width, !originalHeight ? 0 : height};
937}
938
948[[nodiscard]] constexpr std::tuple<uint16_t, uint16_t, uint16_t> getMipDims(uint8_t mip, uint16_t width, uint16_t height, uint16_t depth, bool addCompressedFormatPadding = false) {
949 const auto originalWidth = width, originalHeight = height, originalDepth = depth;
950 for (int i = 0; i < mip && (width > 1 || height > 1 || depth > 1); i++) {
951 if ((width >>= 1) < 1) width = 1;
952 if ((height >>= 1) < 1) height = 1;
953 if ((depth >>= 1) < 1) depth = 1;
954 }
955 if (addCompressedFormatPadding) {
956 width += sourcepp::math::paddingForAlignment(4, width);
957 height += sourcepp::math::paddingForAlignment(4, height);
958 }
959 return {!originalWidth ? 0 : width, !originalHeight ? 0 : height, !originalDepth ? 0 : depth};
960}
961
971[[nodiscard]] constexpr uint8_t getMaximumMipCount(uint16_t width, uint16_t height, uint16_t depth = 1) {
972 uint8_t numMipLevels = 1;
973 if (width && height && depth) {
974 while (width > 1 || height > 1 || depth > 1) {
975 if ((width >>= 1) < 1) width = 1;
976 if ((height >>= 1) < 1) height = 1;
977 if ((depth >>= 1) < 1) depth = 1;
978 numMipLevels++;
979 }
980 }
981 return numMipLevels;
982}
983
984} // namespace ImageDimensions
985
986namespace ImageFormatDetails {
987
996[[nodiscard]] constexpr uint32_t getDataLength(ImageFormat format, uint16_t width, uint16_t height, uint16_t depth = 1) {
998 return ((width + 3) / 4) * ((height + 3) / 4) * depth * bpp(format) * 2;
999 }
1000 return width * height * depth * (bpp(format) / 8);
1001}
1002
1015[[nodiscard]] constexpr uint32_t getDataLength(ImageFormat format, uint8_t mipCount, uint16_t frameCount, uint8_t faceCount, uint16_t width, uint16_t height, uint16_t depth = 1) {
1016 uint32_t length = 0;
1017 for (int i = mipCount - 1; i >= 0; i--) {
1018 const auto [mipWidth, mipHeight, mipDepth] = ImageDimensions::getMipDims(i, width, height, depth);
1019 length += ImageFormatDetails::getDataLength(format, mipWidth, mipHeight, mipDepth) * frameCount * faceCount;
1020 }
1021 return length;
1022}
1023
1040[[nodiscard]] constexpr uint32_t getDataLengthXBOX(bool padded, ImageFormat format, uint8_t mipCount, uint16_t frameCount, uint8_t faceCount, uint16_t width, uint16_t height, uint16_t depth = 1) {
1041 uint32_t length = 0;
1042 for (int j = 0; j < frameCount; j++) {
1043 for (int i = 0; i < mipCount; i++) {
1044 const auto [mipWidth, mipHeight, mipDepth] = ImageDimensions::getMipDims(i, width, height, depth);
1045 length += ImageFormatDetails::getDataLength(format, mipWidth, mipHeight, mipDepth) * faceCount;
1046 }
1047 if (padded && j + 1 != frameCount && length > 512) {
1048 length += sourcepp::math::paddingForAlignment(512, length);
1049 }
1050 }
1051 return length;
1052}
1053
1071[[nodiscard]] constexpr bool getDataPosition(uint32_t& offset, uint32_t& length, ImageFormat format, uint8_t mip, uint8_t mipCount, uint16_t frame, uint16_t frameCount, uint8_t face, uint8_t faceCount, uint16_t width, uint16_t height, uint16_t slice = 0, uint16_t depth = 1) {
1072 offset = 0;
1073 length = 0;
1074 for (int i = mipCount - 1; i >= 0; i--) {
1075 const auto [mipWidth, mipHeight, mipDepth] = ImageDimensions::getMipDims(i, width, height, depth);
1076 for (int j = 0; j < frameCount; j++) {
1077 for (int k = 0; k < faceCount; k++) {
1078 for (int l = 0; l < mipDepth; l++) {
1079 const auto imageSize = ImageFormatDetails::getDataLength(format, mipWidth, mipHeight);
1080 if (i == mip && j == frame && k == face && l == slice) {
1081 length = imageSize;
1082 return true;
1083 }
1084 offset += imageSize;
1085 }
1086 }
1087 }
1088 }
1089 return false;
1090}
1091
1113[[nodiscard]] constexpr bool getDataPositionXBOX(uint32_t& offset, uint32_t& length, bool padded, ImageFormat format, uint8_t mip, uint8_t mipCount, uint16_t frame, uint16_t frameCount, uint8_t face, uint8_t faceCount, uint16_t width, uint16_t height, uint16_t slice = 0, uint16_t depth = 1) {
1114 offset = 0;
1115 length = 0;
1116 for (int j = 0; j < frameCount; j++) {
1117 for (int k = 0; k < faceCount; k++) {
1118 for (int i = 0; i < mipCount; i++) {
1119 const auto [mipWidth, mipHeight, mipDepth] = ImageDimensions::getMipDims(i, width, height, depth);
1120 for (int l = 0; l < mipDepth; l++) {
1121 const auto imageSize = ImageFormatDetails::getDataLength(format, mipWidth, mipHeight);
1122 if (i == mip && j == frame && k == face && l == slice) {
1123 length = imageSize;
1124 return true;
1125 }
1126 offset += imageSize;
1127 }
1128 }
1129 }
1130 if (padded && j + 1 != frameCount && offset > 512) {
1131 offset += sourcepp::math::paddingForAlignment(512, offset);
1132 }
1133 }
1134 return false;
1135}
1136
1137} // namespace ImageFormatDetails
1138
1139} // namespace vtfpp
constexpr uint16_t paddingForAlignment(uint16_t alignment, uint64_t n)
Definition Math.h:64
constexpr uint8_t getMaximumMipCount(uint16_t width, uint16_t height, uint16_t depth=1)
Calculate the largest mip count a texture with the given width, height, and depth can contain.
constexpr std::pair< uint16_t, uint16_t > getMipDims(uint8_t mip, uint16_t width, uint16_t height, bool addCompressedFormatPadding=false)
Get the width and height at a given mip level.
constexpr uint16_t getMipDim(uint8_t mip, uint16_t dim, bool addCompressedFormatPadding=false)
Get the dimension at a given mip level.
constexpr uint32_t getDataLength(ImageFormat format, uint16_t width, uint16_t height, uint16_t depth=1)
Calculate the amount of data required to store a texture with the given format and dimensions.
constexpr bool getDataPosition(uint32_t &offset, uint32_t &length, ImageFormat format, uint8_t mip, uint8_t mipCount, uint16_t frame, uint16_t frameCount, uint8_t face, uint8_t faceCount, uint16_t width, uint16_t height, uint16_t slice=0, uint16_t depth=1)
Find the position of a specific mip, frame, face, and slice within a texture.
constexpr int8_t decompressedGreen(ImageFormat format)
Get the number of bits of precision of the green channel in the given format regardless of compressio...
constexpr int8_t alpha(ImageFormat format)
Get the number of bits of precision of the alpha channel in the given format.
constexpr bool large(ImageFormat format)
Check if the given format is representable by RGBA8888 without losing data.
constexpr int8_t green(ImageFormat format)
Get the number of bits of precision of the green channel in the given format.
constexpr int8_t decompressedBlue(ImageFormat format)
Get the number of bits of precision of the blue channel in the given format regardless of compression...
constexpr ImageFormat containerFormat(ImageFormat format)
Find a container format for the given format, a format that is more commonly understood within this l...
constexpr bool transparent(ImageFormat format)
Check if the given format can store transparency.
constexpr uint32_t getDataLengthXBOX(bool padded, ImageFormat format, uint8_t mipCount, uint16_t frameCount, uint8_t faceCount, uint16_t width, uint16_t height, uint16_t depth=1)
Calculate the amount of data required to store an XBOX platform texture with the given format,...
constexpr int8_t decompressedRed(ImageFormat format)
Get the number of bits of precision of the red channel in the given format regardless of compression.
constexpr bool titanfall(ImageFormat format)
Check if the given format is exclusively used by Titanfall 1/2.
constexpr int8_t decompressedAlpha(ImageFormat format)
Get the number of bits of precision of the alpha channel in the given format regardless of compressio...
constexpr int8_t red(ImageFormat format)
Get the number of bits of precision of the red channel in the given format.
constexpr bool decimal(ImageFormat format)
Checks if the given format stores floating points in its channels.
constexpr uint8_t bpp(ImageFormat format)
Find the bits per pixel of the given format.
constexpr bool getDataPositionXBOX(uint32_t &offset, uint32_t &length, bool padded, ImageFormat format, uint8_t mip, uint8_t mipCount, uint16_t frame, uint16_t frameCount, uint8_t face, uint8_t faceCount, uint16_t width, uint16_t height, uint16_t slice=0, uint16_t depth=1)
Find the position of a specific mip, frame, face, and slice within an XBOX platform texture.
constexpr bool console(ImageFormat format)
Check if the given format is exclusively used on console platforms.
constexpr bool compressedHDR(ImageFormat format)
Check if the given format is a compressed HDR format (not counting BC6H).
constexpr bool opaque(ImageFormat format)
Check if the given format cannot store transparency.
constexpr bool strata(ImageFormat format)
Check if the given format is exclusively used by Strata Source.
constexpr bool compressed(ImageFormat format)
Check if the given format is a compressed format (DXT1, DXT3, DXT5, ATI1N, ATI2N, BC7,...
constexpr int8_t blue(ImageFormat format)
Get the number of bits of precision of the blue channel in the given format.