/* -*- C++ -*-
 * Copyright 2019-2025 LibRaw LLC (info@libraw.org)
 *

 LibRaw is free software; you can redistribute it and/or modify
 it under the terms of the one of two licenses as you choose:

1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).

2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).

 */

#include "third_party/libraw/internal/dcraw_defs.h"

void LibRaw::parseAdobePanoMakernote()
{
  uchar *PrivateMknBuf;
  unsigned posPrivateMknBuf;
  unsigned PrivateMknLength;
  unsigned PrivateOrder;
  unsigned PrivateEntries, PrivateTagID, PrivateTagType, PrivateTagCount;
  unsigned PrivateTagBytes;
  int truncated;

#define CHECKSPACE(s)                                                          \
  if (posPrivateMknBuf + (s) > PrivateMknLength)                               \
  {                                                                            \
    free(PrivateMknBuf);                                                       \
    return;                                                                    \
  }

  order = 0x4d4d;
  truncated = 0;
  PrivateMknLength = get4();

  if ((PrivateMknLength > 4) && (PrivateMknLength < 10240000) &&
      (PrivateMknBuf = (uchar *)calloc(PrivateMknLength + 1024,1)))
  { // 1024b for safety
    fread(PrivateMknBuf, PrivateMknLength, 1, ifp);
    PrivateOrder = sget2(PrivateMknBuf);
    PrivateEntries = sget2(PrivateMknBuf + 2);
    if ((PrivateEntries > 1000) ||
        ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949)))
    {
      free(PrivateMknBuf);
      return;
    }
    posPrivateMknBuf = 4;
    while (PrivateEntries--)
    {
      order = 0x4d4d;
      CHECKSPACE(8);
      PrivateTagID = sget2(PrivateMknBuf + posPrivateMknBuf);
      PrivateTagType = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
      PrivateTagCount = sget4(PrivateMknBuf + posPrivateMknBuf + 4);
      posPrivateMknBuf += 8;
      order = PrivateOrder;

      if (truncated && !PrivateTagCount)
        continue;

      PrivateTagBytes = PrivateTagCount *
          tagtype_dataunit_bytes[(PrivateTagType <= LIBRAW_EXIFTAG_TYPE_IFD8) ? PrivateTagType : 0];
      if(PrivateTagBytes > 10240000u)
      {
         free(PrivateMknBuf);
         return;
      }
      if (PrivateTagID == 0x0002)
      {
        posPrivateMknBuf += 2;
        CHECKSPACE(2);
        if (sget2(PrivateMknBuf + posPrivateMknBuf))
        {
          truncated = 1;
        }
        else
        {
          posPrivateMknBuf += 2;
        }
      }
      else if (PrivateTagID == 0x0013)
      {
        ushort nWB, cnt, tWB;
        CHECKSPACE(2);
        nWB = sget2(PrivateMknBuf + posPrivateMknBuf);
        posPrivateMknBuf += 2;
        if (nWB > 0x100)
          break;
        for (cnt = 0; cnt < nWB; cnt++)
        {
          CHECKSPACE(2);
          tWB = sget2(PrivateMknBuf + posPrivateMknBuf);
          if (tWB < 0x100)
          {
            CHECKSPACE(4);
            icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
            icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 4);
            icWBC[tWB][1] = icWBC[tWB][3] = 0x100;
          }
          posPrivateMknBuf += 6;
        }
      }
      else if (PrivateTagID == 0x0027)
      {
        ushort nWB, cnt, tWB;
        CHECKSPACE(2);
        nWB = sget2(PrivateMknBuf + posPrivateMknBuf);
        posPrivateMknBuf += 2;
        if (nWB > 0x100)
          break;
        for (cnt = 0; cnt < nWB; cnt++)
        {
          CHECKSPACE(2);
          tWB = sget2(PrivateMknBuf + posPrivateMknBuf);
          if (tWB < 0x100)
          {
            CHECKSPACE(6);
            icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
            icWBC[tWB][1] = icWBC[tWB][3] =
                sget2(PrivateMknBuf + posPrivateMknBuf + 4);
            icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 6);
          }
          posPrivateMknBuf += 8;
        }
      }
      else if (PrivateTagID == 0x0121)
      {
        CHECKSPACE(4);
        imPana.Multishot = sget4(PrivateMknBuf + posPrivateMknBuf);
        posPrivateMknBuf += 4;
      }
      else
      {
        if (PrivateTagBytes > 4)
          posPrivateMknBuf += PrivateTagBytes;
        else if (!truncated)
          posPrivateMknBuf += 4;
        else
        {
          if (PrivateTagBytes <= 2)
            posPrivateMknBuf += 2;
          else
            posPrivateMknBuf += 4;
        }
      }
    }
    free(PrivateMknBuf);
  }
#undef CHECKSPACE
}
