File indexing completed on 2025-01-05 03:56:57
0001 /* -*- C++ -*- 0002 * Copyright 2019-2021 LibRaw LLC (info@libraw.org) 0003 * 0004 0005 LibRaw is free software; you can redistribute it and/or modify 0006 it under the terms of the one of two licenses as you choose: 0007 0008 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 0009 (See file LICENSE.LGPL provided in LibRaw distribution archive for details). 0010 0011 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 0012 (See file LICENSE.CDDL provided in LibRaw distribution archive for details). 0013 0014 */ 0015 0016 #include "../../internal/dcraw_defs.h" 0017 0018 void LibRaw::parseAdobePanoMakernote() 0019 { 0020 uchar *PrivateMknBuf; 0021 unsigned posPrivateMknBuf; 0022 unsigned PrivateMknLength; 0023 unsigned PrivateOrder; 0024 unsigned PrivateEntries, PrivateTagID, PrivateTagType, PrivateTagCount; 0025 unsigned PrivateTagBytes; 0026 int truncated; 0027 0028 #define CHECKSPACE(s) \ 0029 if (posPrivateMknBuf + (s) > PrivateMknLength) \ 0030 { \ 0031 free(PrivateMknBuf); \ 0032 return; \ 0033 } 0034 0035 order = 0x4d4d; 0036 truncated = 0; 0037 PrivateMknLength = get4(); 0038 0039 if ((PrivateMknLength > 4) && (PrivateMknLength < 10240000) && 0040 (PrivateMknBuf = (uchar *)malloc(PrivateMknLength + 1024))) 0041 { // 1024b for safety 0042 fread(PrivateMknBuf, PrivateMknLength, 1, ifp); 0043 PrivateOrder = sget2(PrivateMknBuf); 0044 PrivateEntries = sget2(PrivateMknBuf + 2); 0045 if ((PrivateEntries > 1000) || 0046 ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949))) 0047 { 0048 free(PrivateMknBuf); 0049 return; 0050 } 0051 posPrivateMknBuf = 4; 0052 while (PrivateEntries--) 0053 { 0054 order = 0x4d4d; 0055 CHECKSPACE(8); 0056 PrivateTagID = sget2(PrivateMknBuf + posPrivateMknBuf); 0057 PrivateTagType = sget2(PrivateMknBuf + posPrivateMknBuf + 2); 0058 PrivateTagCount = sget4(PrivateMknBuf + posPrivateMknBuf + 4); 0059 posPrivateMknBuf += 8; 0060 order = PrivateOrder; 0061 0062 if (truncated && !PrivateTagCount) 0063 continue; 0064 0065 PrivateTagBytes = PrivateTagCount * 0066 tagtype_dataunit_bytes[(PrivateTagType <= LIBRAW_EXIFTAG_TYPE_IFD8) ? PrivateTagType : 0]; 0067 if(PrivateTagBytes > 10240000u) 0068 { 0069 free(PrivateMknBuf); 0070 return; 0071 } 0072 if (PrivateTagID == 0x0002) 0073 { 0074 posPrivateMknBuf += 2; 0075 CHECKSPACE(2); 0076 if (sget2(PrivateMknBuf + posPrivateMknBuf)) 0077 { 0078 truncated = 1; 0079 } 0080 else 0081 { 0082 posPrivateMknBuf += 2; 0083 } 0084 } 0085 else if (PrivateTagID == 0x0013) 0086 { 0087 ushort nWB, cnt, tWB; 0088 CHECKSPACE(2); 0089 nWB = sget2(PrivateMknBuf + posPrivateMknBuf); 0090 posPrivateMknBuf += 2; 0091 if (nWB > 0x100) 0092 break; 0093 for (cnt = 0; cnt < nWB; cnt++) 0094 { 0095 CHECKSPACE(2); 0096 tWB = sget2(PrivateMknBuf + posPrivateMknBuf); 0097 if (tWB < 0x100) 0098 { 0099 CHECKSPACE(4); 0100 icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2); 0101 icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 4); 0102 icWBC[tWB][1] = icWBC[tWB][3] = 0x100; 0103 } 0104 posPrivateMknBuf += 6; 0105 } 0106 } 0107 else if (PrivateTagID == 0x0027) 0108 { 0109 ushort nWB, cnt, tWB; 0110 CHECKSPACE(2); 0111 nWB = sget2(PrivateMknBuf + posPrivateMknBuf); 0112 posPrivateMknBuf += 2; 0113 if (nWB > 0x100) 0114 break; 0115 for (cnt = 0; cnt < nWB; cnt++) 0116 { 0117 CHECKSPACE(2); 0118 tWB = sget2(PrivateMknBuf + posPrivateMknBuf); 0119 if (tWB < 0x100) 0120 { 0121 CHECKSPACE(6); 0122 icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2); 0123 icWBC[tWB][1] = icWBC[tWB][3] = 0124 sget2(PrivateMknBuf + posPrivateMknBuf + 4); 0125 icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 6); 0126 } 0127 posPrivateMknBuf += 8; 0128 } 0129 } 0130 else if (PrivateTagID == 0x0121) 0131 { 0132 CHECKSPACE(4); 0133 imPana.Multishot = sget4(PrivateMknBuf + posPrivateMknBuf); 0134 posPrivateMknBuf += 4; 0135 } 0136 else 0137 { 0138 if (PrivateTagBytes > 4) 0139 posPrivateMknBuf += PrivateTagBytes; 0140 else if (!truncated) 0141 posPrivateMknBuf += 4; 0142 else 0143 { 0144 if (PrivateTagBytes <= 2) 0145 posPrivateMknBuf += 2; 0146 else 0147 posPrivateMknBuf += 4; 0148 } 0149 } 0150 } 0151 free(PrivateMknBuf); 0152 } 0153 #undef CHECKSPACE 0154 }