summaryrefslogtreecommitdiff
path: root/src/lib/PictHeader.cpp
blob: f9af1cfdc4fd467d2680f54b839e8b9b65cbbaa6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libpict project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "PictHeader.h"
#include "libpict_utils.h"

namespace
{
unsigned char readU8(librevenge::RVNGInputStream *input)
{
  unsigned long numBytesRead;
  unsigned char const *p = input->read(sizeof(unsigned char), numBytesRead);

  if (numBytesRead !=  sizeof(unsigned char))
    throw libpict::EndOfStreamException();
  return *(unsigned char const *)(p);
}

unsigned short readU16(librevenge::RVNGInputStream *input)
{
  unsigned long numBytesRead;
  unsigned short const *p = (unsigned short const *)input->read(sizeof(unsigned short), numBytesRead);

  if (numBytesRead != sizeof(unsigned short))
    throw libpict::EndOfStreamException();
  return (unsigned short)((((unsigned char const *)(p))[1] << 0) | (((unsigned char const *)(p))[0] << 8));
}

unsigned readU32(librevenge::RVNGInputStream *input)
{
  unsigned long numBytesRead;
  unsigned const *p = (unsigned const *)input->read(sizeof(unsigned), numBytesRead);
  if (numBytesRead !=  sizeof(unsigned))
    throw libpict::EndOfStreamException();
  return (unsigned)((((unsigned char const *)(p))[3] << 0) | (((unsigned char const *)(p))[2] << 8) |
                    (((unsigned char const *)(p))[1] << 16) | (((unsigned char const *)(p))[0] << 24));
}
}

PictHeader::PictHeader() :
  m_fileSize(0),
  m_top(0),
  m_left(0),
  m_bottom(0),
  m_right(0),
  m_pictVersion(0),
  m_horizontalResolution(72),
  m_verticalResolution(72),
  m_pictureSize(0),
  m_dataStart(0)
{
}

bool PictHeader::load(librevenge::RVNGInputStream *input)
{
  if (loadPict1Header(input))
    return true;
  if (loadPict2Header(input))
    return true;
  return false;
}

bool PictHeader::loadPict1Header(librevenge::RVNGInputStream *input)
{
  input->seek(0, librevenge::RVNG_SEEK_SET);
  /* Try first to see whether the 512 bytes header is missing */
  input->seek(10, librevenge::RVNG_SEEK_CUR);
  if ((0x11 == readU8(input)) && (0x01 == readU8(input)))
    input->seek(0, librevenge::RVNG_SEEK_CUR);
  /* Ok, let us now skip the first 512 bytes and restart */
  else
  {
    input->seek(512 + 10, librevenge::RVNG_SEEK_SET);
    if ((0x11 == readU8(input)) && (0x01 == readU8(input)))
      input->seek(512, librevenge::RVNG_SEEK_SET);
    else
    {
      input->seek(0, librevenge::RVNG_SEEK_SET);
      PICT_DEBUG_MSG(("No Pict1 header present\n"));
      return false;
    }
  }
  /* Now, we should be out or at the beginning of the Pict1 file */
  PICT_DEBUG_MSG(("Reading Pict1 header\n"));
  m_fileSize = readU16(input);
  m_top = readU16(input);
  m_left = readU16(input);
  m_bottom = readU16(input);
  m_right = readU16(input);
  if (0x11 != readU8(input))
  {
    input->seek(0, librevenge::RVNG_SEEK_SET);
    return false;
  }
  if (0x01 != readU8(input))
  {
    input->seek(0, librevenge::RVNG_SEEK_SET);
    return false;
  }
  PICT_DEBUG_MSG(("Pict1Header: fileSize = 0x%.4x, top = 0x%.4x, left = 0x%.4x, bottom = 0x%.4x, right = 0x%.4x\n", m_fileSize,  m_top, m_left, m_bottom, m_right));
  m_dataStart = input->tell();
  input->seek(0, librevenge::RVNG_SEEK_SET);
  m_pictVersion = 1;
  return true;
}

bool PictHeader::loadPict2Header(librevenge::RVNGInputStream *input)
{
  input->seek(0, librevenge::RVNG_SEEK_SET);
  /* Try first to see whether the 512 bytes header is missing */
  input->seek(10, librevenge::RVNG_SEEK_CUR);
  if ((0x0011 == readU16(input)) && (0x02FF == readU16(input)))
    input->seek(0, librevenge::RVNG_SEEK_CUR);
  /* Ok, let us now skip the first 512 bytes and restart */
  else
  {
    input->seek(512 + 10, librevenge::RVNG_SEEK_SET);
    if ((0x0011 == readU16(input)) && (0x02FF == readU16(input)))
      input->seek(512, librevenge::RVNG_SEEK_SET);
    else
    {
      input->seek(0, librevenge::RVNG_SEEK_SET);
      PICT_DEBUG_MSG(("No Pict2 header present\n"));
      return false;
    }
  }
  /* Now, we should be out or at the beginning of the Pict1 file */
  PICT_DEBUG_MSG(("Reading Pict2 header\n"));
  m_fileSize = readU16(input);
  m_top = readU16(input);
  m_left = readU16(input);
  m_bottom = readU16(input);
  m_right = readU16(input);
  if (0x0011 != readU16(input))
  {
    input->seek(0, librevenge::RVNG_SEEK_SET);
    return false;
  }
  if (0x02FF != readU16(input))
  {
    input->seek(0, librevenge::RVNG_SEEK_SET);
    return false;
  }
  if (0x0C00 != readU16(input))
  {
    input->seek(0, librevenge::RVNG_SEEK_SET);
    return false;
  }
  else
    input->seek(24, librevenge::RVNG_SEEK_CUR);
  PICT_DEBUG_MSG(("Pict2Header: fileSize = 0x%.4x, top = 0x%.4x, left = 0x%.4x, bottom = 0x%.4x, right = 0x%.4x\n", m_fileSize,  m_top, m_left, m_bottom, m_right));
  m_dataStart = input->tell();
  input->seek(0, librevenge::RVNG_SEEK_SET);
  m_pictVersion = 2;
  return true;
}
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */