Visual Studio の設定箇所
・C++で空のプロジェクトを作る
・一点だけ注意があります。
デフォルトだと、コンソールアプリを作ろうとするので、
[プロジェクト]-[プロパティ]-[構成のプロパティ]-[リンカー]-[システム]の一番上の行の[サブシステム]で、リンカエラーが出ます。Windows (/SUBSYSTEM:WINDOWS)を選ぶと、GUIのWindowsアプリケーションをビルドする準備を整えてくれるので、そこだけ注意してください。
エキシプリシット・リトル・エンディアンのファイルなら大丈夫なはずです。
プラナーインプリメンテーションは、RGBの標準配列に対応しています。
RRRRRGGGGGBBBBBとかはダメです。
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#pragma warning(disable:4996)
PSTR filename;
int get_file_size(const char* file_name)
{
FILE* fp = fopen(file_name, "rb");
if (fp == NULL) {
return -1LL;
}
if (fseek(fp, 0L, SEEK_END) == 0) {
fpos_t pos;
if (fgetpos(fp, &pos) == 0) {
fclose(fp);
return (int)pos;
}
}
fclose(fp);
return -1LL;
}
void func(HDC hdc)
{
int k = 0;
k = get_file_size(filename);
unsigned char* data = (unsigned char*)malloc(k);
FILE* fp = fopen(filename, "rb");
fread(data, 1, k, fp);
int s = 0;
int rows = 0;
int columns = 0;
int w_center = 0;
int w_width = 0;
for (int i = 0; i < k; i++)
{
if (data[i] == 0x28 && data[i + 1] == 0x00 && data[i + 2] == 0x10 && data[i + 3] == 0x00)
{
rows = data[i + 8];
rows += data[i + 9] * 256;
continue;
}
if (data[i] == 0x28 && data[i + 1] == 0x00 && data[i + 2] == 0x11 && data[i + 3] == 0x00)
{
columns = data[i + 8];
columns += data[i + 9] * 256;
continue;
}
if (data[i] == 0x28 && data[i + 1] == 0x00 && data[i + 2] == 0x50 && data[i + 3] == 0x10)
{
int array[4];
array[0] = data[i + 8] - (3 * 16);
array[1] = data[i + 8] - (3 * 16);
array[2] = data[i + 8] - (3 * 16);
array[3] = data[i + 8] - (3 * 16);
w_center = (array[0] * 1000) + (array[1] * 100) + (array[2] * 10) + (array[3]);
continue;
}
if (data[i] == 0x28 && data[i + 1] == 0x00 && data[i + 2] == 0x51 && data[i + 3] == 0x10)
{
int array[4];
array[0] = data[i + 8] - (3 * 16);
array[1] = data[i + 8] - (3 * 16);
array[2] = data[i + 8] - (3 * 16);
array[3] = data[i + 8] - (3 * 16);
w_width = (array[0] * 1000) + (array[1] * 100) + (array[2] * 10) + (array[3]);
continue;
}
if (data[i] == 0xE0 && data[i + 1] == 0x7F && data[i + 2] == 0x10 && data[i + 3] == 0x00)
{
s = i;
s += 12;
break;
}
}
fclose(fp);
int height = rows;
int width = columns;
int window_width = w_width;
int window_center = w_center;
unsigned char rgb[3];
for (int i = 0; i < width * height; i++)
{
int value = data[2 * i + s] + data[2 * i + 1 + s] * 256;
double val = value;
if (value >= window_width)
{
val = 255;
}
else if (value < 0)
{
val = 0;
}
else
{
val = val / window_width;
val = val * 256;
}
value = (int)val;
rgb[0] = (unsigned char)value;
rgb[1] = (unsigned char)value;
rgb[2] = (unsigned char)value;
long RGB = rgb[0] * 65536 + rgb[1] * 256 + rgb[2];
//5で割ってるのは、Rows,Columnsが3000のファイルがあったので、画面に収まらなかったために圧縮しました。通常のサイズで表示したいときは、/ 5を削除してください。
SetPixel(hdc, (i % width) / 5, (int)(i / width) / 5, RGB);
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
HDC hdc;
PAINTSTRUCT ps;
int iCount;
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
func(hdc);
EndPaint(hwnd, &ps);
return 0;
}
return DefWindowProc(hwnd, msg, wp, lp);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR lpCmdLine, int nCmdShow) {
filename = lpCmdLine;
HWND hwnd;
MSG msg;
WNDCLASS winc;
winc.style = CS_HREDRAW | CS_VREDRAW;
winc.lpfnWndProc = WndProc;
winc.cbClsExtra = winc.cbWndExtra = 0;
winc.hInstance = hInstance;
winc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winc.hCursor = LoadCursor(NULL, IDC_ARROW);
winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
winc.lpszMenuName = NULL;
winc.lpszClassName = TEXT("konecom");
if (!RegisterClass(&winc)) return -1;
hwnd = CreateWindow(
TEXT("konecom"), TEXT("konecom"),
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL
);
if (hwnd == NULL) return -1;
while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg);
return msg.wParam;
}
ビルドを通したら、
xxxx.exe <読影したいdcmファイル>
で、実行してください。