// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include <windows.h>

#include "core/fxcrt/fx_system.h"
#include "core/fxge/cfx_gemodule.h"
#include "core/fxge/win32/cfx_windowsdib.h"
#include "core/fxge/win32/win32_int.h"

CFX_ByteString CFX_WindowsDIB::GetBitmapInfo(
    const CFX_RetainPtr<CFX_DIBitmap>& pBitmap) {
  CFX_ByteString result;
  int len = sizeof(BITMAPINFOHEADER);
  if (pBitmap->GetBPP() == 1 || pBitmap->GetBPP() == 8) {
    len += sizeof(DWORD) * (int)(1 << pBitmap->GetBPP());
  }
  BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)result.GetBuffer(len);
  memset(pbmih, 0, sizeof(BITMAPINFOHEADER));
  pbmih->biSize = sizeof(BITMAPINFOHEADER);
  pbmih->biBitCount = pBitmap->GetBPP();
  pbmih->biCompression = BI_RGB;
  pbmih->biHeight = -(int)pBitmap->GetHeight();
  pbmih->biPlanes = 1;
  pbmih->biWidth = pBitmap->GetWidth();
  if (pBitmap->GetBPP() == 8) {
    uint32_t* pPalette = (uint32_t*)(pbmih + 1);
    if (pBitmap->GetPalette()) {
      for (int i = 0; i < 256; i++) {
        pPalette[i] = pBitmap->GetPalette()[i];
      }
    } else {
      for (int i = 0; i < 256; i++) {
        pPalette[i] = i * 0x010101;
      }
    }
  }
  if (pBitmap->GetBPP() == 1) {
    uint32_t* pPalette = (uint32_t*)(pbmih + 1);
    if (pBitmap->GetPalette()) {
      pPalette[0] = pBitmap->GetPalette()[0];
      pPalette[1] = pBitmap->GetPalette()[1];
    } else {
      pPalette[0] = 0;
      pPalette[1] = 0xffffff;
    }
  }
  result.ReleaseBuffer(len);
  return result;
}

CFX_RetainPtr<CFX_DIBitmap> _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi,
                                                       LPVOID pData,
                                                       bool bAlpha) {
  int width = pbmi->bmiHeader.biWidth;
  int height = pbmi->bmiHeader.biHeight;
  BOOL bBottomUp = true;
  if (height < 0) {
    height = -height;
    bBottomUp = false;
  }
  int pitch = (width * pbmi->bmiHeader.biBitCount + 31) / 32 * 4;
  auto pBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
  FXDIB_Format format = bAlpha
                            ? (FXDIB_Format)(pbmi->bmiHeader.biBitCount + 0x200)
                            : (FXDIB_Format)pbmi->bmiHeader.biBitCount;
  if (!pBitmap->Create(width, height, format))
    return nullptr;

  memcpy(pBitmap->GetBuffer(), pData, pitch * height);
  if (bBottomUp) {
    uint8_t* temp_buf = FX_Alloc(uint8_t, pitch);
    int top = 0, bottom = height - 1;
    while (top < bottom) {
      memcpy(temp_buf, pBitmap->GetBuffer() + top * pitch, pitch);
      memcpy(pBitmap->GetBuffer() + top * pitch,
             pBitmap->GetBuffer() + bottom * pitch, pitch);
      memcpy(pBitmap->GetBuffer() + bottom * pitch, temp_buf, pitch);
      top++;
      bottom--;
    }
    FX_Free(temp_buf);
    temp_buf = nullptr;
  }
  if (pbmi->bmiHeader.biBitCount == 1) {
    for (int i = 0; i < 2; i++)
      pBitmap->SetPaletteArgb(i, ((uint32_t*)pbmi->bmiColors)[i] | 0xff000000);
  } else if (pbmi->bmiHeader.biBitCount == 8) {
    for (int i = 0; i < 256; i++)
      pBitmap->SetPaletteArgb(i, ((uint32_t*)pbmi->bmiColors)[i] | 0xff000000);
  }
  return pBitmap;
}

CFX_RetainPtr<CFX_DIBitmap> CFX_WindowsDIB::LoadFromBuf(BITMAPINFO* pbmi,
                                                        LPVOID pData) {
  return _FX_WindowsDIB_LoadFromBuf(pbmi, pData, false);
}

HBITMAP CFX_WindowsDIB::GetDDBitmap(const CFX_RetainPtr<CFX_DIBitmap>& pBitmap,
                                    HDC hDC) {
  CFX_ByteString info = GetBitmapInfo(pBitmap);
  return CreateDIBitmap(hDC, (BITMAPINFOHEADER*)info.c_str(), CBM_INIT,
                        pBitmap->GetBuffer(), (BITMAPINFO*)info.c_str(),
                        DIB_RGB_COLORS);
}

void GetBitmapSize(HBITMAP hBitmap, int& w, int& h) {
  BITMAP bmp;
  GetObject(hBitmap, sizeof bmp, &bmp);
  w = bmp.bmWidth;
  h = bmp.bmHeight;
}

CFX_RetainPtr<CFX_DIBitmap> CFX_WindowsDIB::LoadFromFile(
    const wchar_t* filename) {
  CWin32Platform* pPlatform =
      (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
  if (pPlatform->m_GdiplusExt.IsAvailable()) {
    WINDIB_Open_Args_ args;
    args.flags = WINDIB_OPEN_PATHNAME;
    args.path_name = filename;
    return pPlatform->m_GdiplusExt.LoadDIBitmap(args);
  }
  HBITMAP hBitmap = (HBITMAP)LoadImageW(nullptr, (wchar_t*)filename,
                                        IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  if (!hBitmap) {
    return nullptr;
  }
  HDC hDC = CreateCompatibleDC(nullptr);
  int width;
  int height;
  GetBitmapSize(hBitmap, width, height);
  auto pDIBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
  if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) {
    DeleteDC(hDC);
    return nullptr;
  }
  CFX_ByteString info = GetBitmapInfo(pDIBitmap);
  int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(),
                      (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS);
  DeleteDC(hDC);
  if (!ret)
    return nullptr;
  return pDIBitmap;
}

CFX_RetainPtr<CFX_DIBitmap> CFX_WindowsDIB::LoadFromFile(const char* filename) {
  return LoadFromFile(CFX_WideString::FromLocal(filename).c_str());
}

CFX_RetainPtr<CFX_DIBitmap> CFX_WindowsDIB::LoadDIBitmap(
    WINDIB_Open_Args_ args) {
  CWin32Platform* pPlatform =
      (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
  if (pPlatform->m_GdiplusExt.IsAvailable()) {
    return pPlatform->m_GdiplusExt.LoadDIBitmap(args);
  }
  if (args.flags == WINDIB_OPEN_MEMORY) {
    return nullptr;
  }
  HBITMAP hBitmap = (HBITMAP)LoadImageW(nullptr, (wchar_t*)args.path_name,
                                        IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  if (!hBitmap) {
    return nullptr;
  }
  HDC hDC = CreateCompatibleDC(nullptr);
  int width, height;
  GetBitmapSize(hBitmap, width, height);
  auto pDIBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
  if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) {
    DeleteDC(hDC);
    return nullptr;
  }
  CFX_ByteString info = GetBitmapInfo(pDIBitmap);
  int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(),
                      (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS);
  DeleteDC(hDC);
  if (!ret)
    return nullptr;
  return pDIBitmap;
}

CFX_WindowsDIB::CFX_WindowsDIB(HDC hDC, int width, int height) {
  Create(width, height, FXDIB_Rgb, (uint8_t*)1);
  BITMAPINFOHEADER bmih;
  memset(&bmih, 0, sizeof bmih);
  bmih.biSize = sizeof bmih;
  bmih.biBitCount = 24;
  bmih.biHeight = -height;
  bmih.biPlanes = 1;
  bmih.biWidth = width;
  LPVOID pData = nullptr;
  m_hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, &pData,
                               nullptr, 0);
  m_pBuffer.Reset(static_cast<uint8_t*>(pData));
  m_hMemDC = CreateCompatibleDC(hDC);
  m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap);
}

CFX_WindowsDIB::~CFX_WindowsDIB() {
  SelectObject(m_hMemDC, m_hOldBitmap);
  DeleteDC(m_hMemDC);
  DeleteObject(m_hBitmap);
}

void CFX_WindowsDIB::LoadFromDevice(HDC hDC, int left, int top) {
  ::BitBlt(m_hMemDC, 0, 0, m_Width, m_Height, hDC, left, top, SRCCOPY);
}

void CFX_WindowsDIB::SetToDevice(HDC hDC, int left, int top) {
  ::BitBlt(hDC, left, top, m_Width, m_Height, m_hMemDC, 0, 0, SRCCOPY);
}
