-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpnm_header.ixx
110 lines (85 loc) · 2.43 KB
/
pnm_header.ixx
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
// Copyright (c) Victor Derks.
// SPDX-License-Identifier: MIT
module;
#include "intellisense.hpp"
export module pnm_header;
import std;
import <win.h>;
import winrt;
import buffered_stream_reader;
import errors;
import util;
using winrt::throw_hresult;
using std::uint32_t;
export enum class PnmType
{
Bitmap,
Graymap,
Pixmap
};
export bool is_pnm_file(_In_ IStream* stream)
{
char magic[2];
unsigned long read;
check_hresult(stream->Read(magic, sizeof magic, &read), wincodec::error_stream_read);
return read == sizeof magic && magic[0] == 'P' && (magic[1] == '5' || magic[1] == '6');
}
export struct pnm_header
{
PnmType PnmType;
bool AsciiFormat;
uint32_t width;
uint32_t height;
USHORT MaxColorValue;
pnm_header() = default;
explicit pnm_header(buffered_stream_reader& streamReader)
{
winrt::check_hresult(Parse(streamReader));
}
HRESULT Parse(buffered_stream_reader& streamReader)
{
char magic[2];
ULONG bytesRead;
streamReader.read_bytes((BYTE*)&magic, sizeof(magic), &bytesRead);
if (bytesRead != sizeof(magic))
throw_hresult(wincodec::error_bad_header);
if (magic[0] != 'P')
throw_hresult(wincodec::error_bad_header);
AsciiFormat = false;
switch (magic[1])
{
case '1': // P1: bitmap, ASCII
AsciiFormat = true;
case '4': // P4: bitmap, binary
PnmType = PnmType::Bitmap;
break;
case '2': // P2: graymap, ASCII
AsciiFormat = true;
case '5': // P5: graymap, binary
PnmType = PnmType::Graymap;
break;
case '3': // P3: pixmap, ASCII
AsciiFormat = true;
case '6': // P6: pixmap, binary
PnmType = PnmType::Pixmap;
break;
default:
throw_hresult(wincodec::error_bad_header);
}
width = streamReader.read_int();
height = streamReader.read_int();
if (width < 1 || height < 1)
return WINCODEC_ERR_BADHEADER;
int maxColorValue;
if (PnmType != PnmType::Bitmap)
{
maxColorValue = streamReader.read_int();
}
else
maxColorValue = 1;
if (maxColorValue < 1 || maxColorValue > 65535)
return WINCODEC_ERR_BADHEADER;
MaxColorValue = static_cast<USHORT>(maxColorValue);
return error_ok;
}
};