Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Разработка простого графического редактора.doc
Скачиваний:
28
Добавлен:
28.06.2014
Размер:
137.73 Кб
Скачать

6.Текст программы.

Main.cpp

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "Main.h"

#include "PCXFiles.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

Graphics::TBitmap *BitMap;

PCXImage PCXImg;

TRect R,R0;

int X0,Y0,X1,Y1;

bool RBegin = false, REnd = false, RDrag = false;

int flag = false;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

PCXImg.create();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)

{

BitMap = new Graphics::TBitmap;

// задание свойств кисти основного и вспомогательного цветов

Image1->Canvas->Brush->Color = clBlack;

Image2->Canvas->Brush->Color = clWhite;

// заполнение окон основного и вспомогательного цветов

Image1->Canvas->FillRect(Rect(0,0,Image1->Width,Image1->Height));

Image2->Canvas->FillRect(Rect(0,0,Image2->Width,Image2->Height));

// задание ширины элемента палитры цветов

int HW = Image4->Width / 10;

// закраска элементов палитры цветов

for(int i = 1; i <=10; i++)

{

switch (i)

{

case 1:Image4->Canvas->Brush->Color = clBlack;

break;

case 2:Image4->Canvas->Brush->Color = clAqua;

break;

case 3:Image4->Canvas->Brush->Color = clBlue;

break;

case 4:Image4->Canvas->Brush->Color = clFuchsia;

break;

case 5:Image4->Canvas->Brush->Color = clGreen;

break;

case 6:Image4->Canvas->Brush->Color = clLime;

break;

case 7:Image4->Canvas->Brush->Color = clMaroon;

break;

case 8:Image4->Canvas->Brush->Color = clRed;

break;

case 9:Image4->Canvas->Brush->Color = clYellow;

break;

case 10:Image4->Canvas->Brush->Color = clWhite;

}

Image4->Canvas->Rectangle((i-1)*HW,0,i*HW,Image4->Height);

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::FormDestroy(TObject *Sender)

{

BitMap->Free();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::MOpenClick(TObject *Sender)

{

if (OpenDialog1->Execute())

{

if (PCXImg.load(OpenDialog1->FileName.c_str()))

flag = true;

PCXImg.recover(Image3);

BitMap->Assign(Image3->Picture->Graphic);

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::SBBrushClick(TObject *Sender)

{

if (((TSpeedButton *)Sender)->Down)

BitMap->Assign(Image3->Picture->Graphic);

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Image3MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y)

{

if((Sender == Image4) || SBColor->Down)

// режим установки основного и вспомогательного цветов

{

if(Button == mbLeft)

{

// установка основного цвета

Image1->Canvas->Brush->Color = ((TImage *)Sender)->Canvas->Pixels[X][Y];

Image1->Canvas->FillRect(Rect(0,0,Image1->Width,Image1->Height));

}

else

{

// установка вспомогательного цвета

Image2->Canvas->Brush->Color = ((TImage *)Sender)->Canvas->Pixels[X][Y];

Image2->Canvas->FillRect(Rect(0,0,Image2->Width,Image2->Height));

}

}

else

{

X0 = X;

Y0 = Y;

if (SBPen->Down)

{

// режим карандаша

Image3->Canvas->MoveTo(X,Y);

Image3->Canvas->Pen->Color = Image1->Canvas->Brush->Color;

if(SBPenStyle1->Down)

Image3->Canvas->Pen->Style = psDash;

else if(SBPenStyle2->Down)

Image3->Canvas->Pen->Style = psDot;

else if(SBPenStyle3->Down)

Image3->Canvas->Pen->Style = psDashDot;

else

Image3->Canvas->Pen->Style = psSolid;

}

else if (SBLine->Down)

// режим линии

{

X1 = X;

Y1 = Y;

Image3->Canvas->Pen->Mode = pmNotXor;

Image3->Canvas->Pen->Color = Image1->Canvas->Brush->Color;

if(SBPenStyle1->Down)

Image3->Canvas->Pen->Style = psDash;

else if(SBPenStyle2->Down)

Image3->Canvas->Pen->Style = psDot;

else if(SBPenStyle3->Down)

Image3->Canvas->Pen->Style = psDashDot;

else

Image3->Canvas->Pen->Style = psSolid;

}

else if (SBPoint1->Down)

{

//режим точки

Image3->Canvas->Pen->Color = Image1->Canvas->Brush->Color;

Image3->Canvas->Brush->Color = Image1->Canvas->Brush->Color;

if(SBBrushStyle1->Down)

Image3->Canvas->Brush->Style = bsCross;

else if(SBBrushStyle2->Down)

Image3->Canvas->Brush->Style = bsDiagCross;

else if(SBBrushStyle3->Down)

Image3->Canvas->Brush->Style = bsFDiagonal;

else if(SBBrushStyle4->Down)

Image3->Canvas->Brush->Style = bsBDiagonal;

else

Image3->Canvas->Brush->Style = bsSolid;

Image3->Canvas->Ellipse(X - 5, Y - 5, X + 5, Y + 5);

}

else if (SBPoint2->Down)

{

//режим точки

Image3->Canvas->Pen->Color = Image1->Canvas->Brush->Color;

Image3->Canvas->Brush->Color = Image1->Canvas->Brush->Color;

if(SBBrushStyle1->Down)

Image3->Canvas->Brush->Style = bsCross;

else if(SBBrushStyle2->Down)

Image3->Canvas->Brush->Style = bsDiagCross;

else if(SBBrushStyle3->Down)

Image3->Canvas->Brush->Style = bsFDiagonal;

else if(SBBrushStyle4->Down)

Image3->Canvas->Brush->Style = bsBDiagonal;

else

Image3->Canvas->Brush->Style = bsSolid;

Image3->Canvas->Ellipse(X - 12, Y - 12, X + 12, Y + 12);

}

else if (SBBrush->Down)

// режим закраски указанной области холста

{

if (Button==mbLeft)

Image3->Canvas->Brush->Color = Image1->Canvas->Brush->Color;

else Image3->Canvas->Brush->Color = Image2->Canvas->Brush->Color;

if(SBBrushStyle1->Down)

Image3->Canvas->Brush->Style = bsCross;

else if(SBBrushStyle2->Down)

Image3->Canvas->Brush->Style = bsDiagCross;

else if(SBBrushStyle3->Down)

Image3->Canvas->Brush->Style = bsFDiagonal;

else if(SBBrushStyle4->Down)

Image3->Canvas->Brush->Style = bsBDiagonal;

else

Image3->Canvas->Brush->Style = bsSolid;

Image3->Canvas->FloodFill(X,Y,Image3->Canvas->Pixels[X][Y],fsSurface);

}

else if (SBErase->Down)

{

// режим ластика

R = Rect(X-6,Y-6,X+6,Y+6);

Image3->Canvas->DrawFocusRect(R);

// Image3->Canvas->Brush->Color = Image2->Canvas->Brush->Color;

Image3->Canvas->Brush->Color = clWhite;

Image3->Canvas->Brush->Style = bsSolid;

Image3->Canvas->FillRect(Rect(X-5,Y-5,X+5,Y+5));

}

else if (SBRect->Down || SBRectang->Down || SBFillRec->Down)

{

// режим работы с рамкой

if (REnd)

// стирание прежней рамки

{

Image3->Canvas->DrawFocusRect(R);

if ((X < R.Right) && (X > R.Left) && (Y > R.Top) && (Y < R.Bottom))

// режим начала перетаскивания фрагмента

{

// установка флагов

RDrag = true;

REnd = false;

// запоминание начального положения перетаскиваемого фрагмента

R0 = R;

// запоминание изображения

BitMap->Assign(Image3->Picture->Graphic);

// установка цвета кисти

Image3->Canvas->Brush->Color = Image2->Canvas->Brush->Color;

MCopy->Enabled = false;

MCut->Enabled = false;

}

}

else

// режим начала рисования рамки фрагмента

{

RBegin = true;

REnd = false;

R.Top = X;

R.Bottom = X;

R.Left = Y;

R.Right = Y;

Image3->Canvas->DrawFocusRect(R);

}

}

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::UndoClick(TObject *Sender)

{

Image3->Picture->Assign(BitMap);

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Image3MouseMove(TObject *Sender, TShiftState Shift,

int X, int Y)

{

if (! Shift.Contains(ssLeft)) return;

// режим линии

if (SBLine->Down)

{

// стирание прежней линии

Image3->Canvas->MoveTo(X0,Y0);

Image3->Canvas->LineTo(X1,Y1);

// рисование новой линии

Image3->Canvas->MoveTo(X0,Y0);

Image3->Canvas->LineTo(X,Y);

// запоминание новых координат конца линии

X1 = X;

Y1 = Y;

}

else if (SBPen->Down)

Image3->Canvas->LineTo(X,Y);

else if (SBErase->Down)

{

// режим ластика

Image3->Canvas->DrawFocusRect(R);

R = Rect(X-6,Y-6,X+6,Y+6);

Image3->Canvas->DrawFocusRect(R);

Image3->Canvas->FillRect(Rect(X-5,Y-5,X+5,Y+5));

}

else if ((SBRect->Down && (RBegin || RDrag))

|| SBRectang->Down || SBFillRec->Down)

{

if (RBegin)

{

// Режим рисования рамки фрагмента

Image3->Canvas->DrawFocusRect(R);

if (X0 < X) { R.Left = X0; R.Right = X; }

else { R.Left = X; R.Right = X0; }

if (Y0 < Y) { R.Top = Y0; R.Bottom = Y; }

else { R.Top = Y; R.Bottom = Y0; }

Image3->Canvas->DrawFocusRect(R);

}

else if (SBRect->Down)

{

// Режим перетаскивания фрагмента

// восстановление изображения под перетаскиваемым фрагментом

Image3->Canvas->CopyRect(R,BitMap->Canvas,R);

// если не нажата клавиша Ctrl - стирание изображения в R0

if (! Shift.Contains(ssCtrl))

Image3->Canvas->FillRect(R0);

// формирование нового положения фрагмента

R.Left = R.Left + X - X0;

R.Right = R.Right + X - X0;

R.Top = R.Top + Y - Y0;

R.Bottom = R.Bottom + Y - Y0;

// запоминание положения курсора мыши

X0 = X;

Y0 = Y;

// рисование фрагмента в новом положении

Image3->Canvas->CopyRect(R,BitMap->Canvas,R0);

// рисование рамки

Image3->Canvas->DrawFocusRect(R);

}

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Image3MouseUp(TObject *Sender, TMouseButton Button,

TShiftState Shift, int X, int Y)

{

if (SBLine->Down)

{

Image3->Canvas->MoveTo(X0,Y0);

Image3->Canvas->LineTo(X1,Y1);

Image3->Canvas->Pen->Mode = pmCopy;

Image3->Canvas->MoveTo(X0,Y0);

Image3->Canvas->LineTo(X,Y);

}

else if (SBRect->Down)

{

if (RDrag) Image3->Canvas->DrawFocusRect(R);

if (RBegin && ! REnd)

{

REnd = true;

MCopy->Enabled = true;

MCut->Enabled = true;

}

}

else if (SBRectang->Down)

{

Image3->Canvas->Brush->Color = Image1->Canvas->Brush->Color;

/* if(SBBrushStyle1->Down)

Image3->Canvas->Brush->Style = bsCross;

else if(SBBrushStyle2->Down)

Image3->Canvas->Brush->Style = bsDiagCross;

else if(SBBrushStyle3->Down)

Image3->Canvas->Brush->Style = bsFDiagonal;

else if(SBBrushStyle4->Down)

Image3->Canvas->Brush->Style = bsBDiagonal;

else

Image3->Canvas->Brush->Style = bsSolid;

if(SBPenStyle1->Down)

Image3->Canvas->Pen->Style = psDash;

else if(SBPenStyle2->Down)

Image3->Canvas->Pen->Style = psDot;

else if(SBPenStyle3->Down)

Image3->Canvas->Pen->Style = psDashDot;

else

Image3->Canvas->Pen->Style = psSolid;

*/

Image3->Canvas->FrameRect(R);

}

else if (SBFillRec->Down)

{

Image3->Canvas->Brush->Color = Image2->Canvas->Brush->Color;

if(SBBrushStyle1->Down)

Image3->Canvas->Brush->Style = bsCross;

else if(SBBrushStyle2->Down)

Image3->Canvas->Brush->Style = bsDiagCross;

else if(SBBrushStyle3->Down)

Image3->Canvas->Brush->Style = bsFDiagonal;

else if(SBBrushStyle4->Down)

Image3->Canvas->Brush->Style = bsBDiagonal;

else

Image3->Canvas->Brush->Style = bsSolid;

Image3->Canvas->Pen->Color = Image1->Canvas->Brush->Color;

if(SBPenStyle1->Down)

Image3->Canvas->Pen->Style = psDash;

else if(SBPenStyle2->Down)

Image3->Canvas->Pen->Style = psDot;

else if(SBPenStyle3->Down)

Image3->Canvas->Pen->Style = psDashDot;

else

Image3->Canvas->Pen->Style = psSolid;

Image3->Canvas->Rectangle(R.Left,R.Top,R.Right,R.Bottom);

}

else if (SBErase->Down) Image3->Canvas->DrawFocusRect(R);

RBegin = false;

RDrag = false;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::MCutClick(TObject *Sender)

{

Graphics::TBitmap *BMCopy = new Graphics::TBitmap;

Image3->Canvas->DrawFocusRect(R);

BMCopy->Width = R.Right - R.Left;

BMCopy->Height = R.Bottom - R.Top;

try

{

BMCopy->Canvas->CopyRect(Rect(0,0,BMCopy->Width,BMCopy->Height),Image3->Canvas,R);

Image3->Canvas->DrawFocusRect(R);

/* BMCopy->SaveToClipBoardFormat(MyFormat,AData,APalette);

Clipboard->SetAsHandle(MyFormat,AData); */

Clipboard()->Assign(BMCopy);

if (Sender == MCut)

{

Image3->Canvas->Brush->Color = clWhite;

Image3->Canvas->FillRect(R);

}

}

__finally

{

BMCopy->Free();

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::MCopyClick(TObject *Sender)

{

Graphics::TBitmap *BMCopy = new Graphics::TBitmap;

Image3->Canvas->DrawFocusRect(R);

BMCopy->Width = R.Right - R.Left;

BMCopy->Height = R.Bottom - R.Top;

try

{

BMCopy->Canvas->CopyRect(Rect(0,0,BMCopy->Width,BMCopy->Height),Image3->Canvas,R);

Image3->Canvas->DrawFocusRect(R);

/* BMCopy->SaveToClipBoardFormat(MyFormat,AData,APalette);

Clipboard->SetAsHandle(MyFormat,AData); */

Clipboard()->Assign(BMCopy);

if (Sender == MCut)

{

Image3->Canvas->Brush->Color = clWhite;

Image3->Canvas->FillRect(R);

}

}

__finally

{

BMCopy->Free();

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::MPasteClick(TObject *Sender)

{

Graphics::TBitmap *BMCopy = new Graphics::TBitmap;

try

{

try

{

BMCopy->LoadFromClipboardFormat(CF_BITMAP,

Clipboard()->GetAsHandle(CF_BITMAP),0);

// BMCopy->Assign(Clipboard());

Image3->Canvas->CopyRect(Rect(0,0,BMCopy->Width,BMCopy->Height),

BMCopy->Canvas,Rect(0,0,BMCopy->Width,BMCopy->Height));

}

__finally

{

BMCopy->Free();

}

}

catch (EInvalidGraphic&)

{

ShowMessage("Ошибочный формат графики");

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::MSaveClick(TObject *Sender)

{

char fname[100];

int l;

PCXImg.synhr(Image3);

if (SaveDialog1->Execute())

{

strcpy(fname,Form1->SaveDialog1->FileName.c_str());

l=strlen(fname);

if(fname[l-4]!='.')

strcat(fname,".pcx");

PCXImg.save(fname);

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::ExitClick(TObject *Sender)

{

Application->Terminate();

}

//---------------------------------------------------------------------------

Main.h

//---------------------------------------------------------------------------

#ifndef MainH

#define MainH

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <ExtCtrls.hpp>

#include <Menus.hpp>

#include <Buttons.hpp>

#include <Dialogs.hpp>

#include <clipbrd.hpp>

//---------------------------------------------------------------------------

class TForm1 : public TForm

{

__published: // IDE-managed Components

TImage *Image3;

TImage *Image1;

TImage *Image2;

TImage *Image4;

TOpenDialog *OpenDialog1;

TSpeedButton *SBBrush;

TSpeedButton *SBColor;

TSpeedButton *SBRect;

TSpeedButton *SBRectang;

TSpeedButton *SBFillRec;

TSpeedButton *SBErase;

TSpeedButton *SBPen;

TSpeedButton *SBLine;

TSaveDialog *SaveDialog1;

TMainMenu *MainMenu1;

TMenuItem *MFile;

TMenuItem *MOpen;

TMenuItem *MSave;

TMenuItem *N1;

TMenuItem *Undo;

TMenuItem *MCut;

TMenuItem *MCopy;

TMenuItem *MPaste;

TSpeedButton *SBPoint1;

TSpeedButton *SBPoint2;

TSpeedButton *SBPenStyle1;

TSpeedButton *SBPenStyle2;

TSpeedButton *SBPenStyle3;

TSpeedButton *SBBrushStyle1;

TSpeedButton *SBBrushStyle2;

TSpeedButton *SBBrushStyle3;

TSpeedButton *SBBrushStyle4;

TMenuItem *Exit;

void __fastcall FormCreate(TObject *Sender);

void __fastcall FormDestroy(TObject *Sender);

void __fastcall MOpenClick(TObject *Sender);

void __fastcall SBBrushClick(TObject *Sender);

void __fastcall Image3MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y);

void __fastcall UndoClick(TObject *Sender);

void __fastcall Image3MouseMove(TObject *Sender, TShiftState Shift,

int X, int Y);

void __fastcall Image3MouseUp(TObject *Sender, TMouseButton Button,

TShiftState Shift, int X, int Y);

void __fastcall MCutClick(TObject *Sender);

void __fastcall MCopyClick(TObject *Sender);

void __fastcall MPasteClick(TObject *Sender);

void __fastcall MSaveClick(TObject *Sender);

void __fastcall ExitClick(TObject *Sender);

private: // User declarations

public: // User declarations

__fastcall TForm1(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm1 *Form1;

//---------------------------------------------------------------------------

#endif

PCXFiles.h

//---------------------------------------------------------------------------

#ifndef PCXFilesH

#define PCXFilesH

//---------------------------------------------------------------------------

#endif

#include <windows.h>

#include <stdio.h>

#include <math.h>

#define MAXX 640

#define MINX 1

#define MAXY 480

#define MINY 1

#define MIN(A,B) ((A)<(B)?(A):(B))

class PCXImage

{

private:

struct

{

char Manufacturer; // Постоянный флаг 10 = ZSoft .PCX

char Version; // 0 = Версия 2.5

// 2 = Версия 2.8 с информацией о палитре

// 3 = Версия 2.8 без информации о палитре

// 5 = Версия 3.0

char Encoding; // 1 = .PCX кодирование длинными сериями

char BitsPerLayer; // Число бит на пиксел в слое

short int Xmin; // Размеры изображения

short int Ymin; // Размеры изображения

short int Xmax; // Размеры изображения

short int Ymax; // Размеры изображения

short int HRes; // Горизонтальное разрешение создающего устройства

short int VRes; // Вертикальное разрешение создающего устройства

char Colormap[48]; // Набор цветовой палитры

char Reserved;

char NPlanes; // Число цветовых слоев

short int BytesPerLine; // Число байт на строку в цветовом слое

// (для PCX-файлов всегда должно быть четным)

short int Palette; // Как интерпретировать палитру:

// 1 = цветная/черно-белая,

// 2 = градации серого

char Filler[58]; // Заполняется нулями до конца заголовка

} head;

int *Image;

public:

PCXImage() { Image = NULL; }

~PCXImage() { delete []Image; }

void create();

void synhr(TImage * IM);

void del() { delete []Image, Image = NULL; }

void recover(TImage * IM);

char load(char *);

char save(char *);

};

PCXFiles.cpp

//---------------------------------------------------------------------------

#pragma hdrstop

#include "Main.h"

#include "PCXFiles.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

void PCXImage::create()

{

if (!Image)

{

head.Manufacturer = 10;

head.Version = 5;

head.Encoding = 1;

head.BitsPerLayer = 8;

head.Xmin = MINX;

head.Ymin = MINY;

head.Xmax = MAXX;

head.Ymax = MAXY;

head.NPlanes = 3;

head.BytesPerLine = MAXX;

head.Palette = 1;

for (int i = 0; i < 58; i++)

head.Filler[i] = 0;

Image = new int[MAXX * MAXY];

}

}

void PCXImage::synhr(TImage * IM)

{

if (Image)

{

short int XSIZE, YSIZE;

XSIZE = head.Xmax - head.Xmin + 1;

YSIZE = head.Ymax - head.Ymin + 1;

for (int i = 0; i < MIN(MAXY, YSIZE); i++)

for (int j = 0; j < MIN(MAXX, XSIZE); j++)

Image[i * XSIZE + j] = IM->Canvas->Pixels[1 + j][1 + i];

}

}

void PCXImage::recover(TImage * IM)

{

if (Image)

{

short int XSIZE, YSIZE;

XSIZE = head.Xmax - head.Xmin + 1;

YSIZE = head.Ymax - head.Ymin + 1;

for (int i = 0; i < MIN(IM->Height, YSIZE); i++)

for (int j = 0; j < MIN(IM->Width, XSIZE); j++)

IM->Canvas->Pixels[1 + j][1 + i] = (TColor)Image[i * XSIZE + j];

}

}

char PCXImage::load(char *fName)

{

FILE *fToRead;

short int XSIZE, YSIZE;

short int TotalBytes;

register char c, count;

register short int j, k;

char *bufStr;

if (fToRead = fopen(fName, "rb"))

{

if (Image) delete []Image;

fread(&head, 128, 1, fToRead);

XSIZE = head.Xmax - head.Xmin + 1;

YSIZE = head.Ymax - head.Ymin + 1;

Image = new int [XSIZE * YSIZE];

TotalBytes = head.NPlanes * head.BytesPerLine;

bufStr = new char[TotalBytes];

k = 0;

for (int i = 0; i < YSIZE; i++)

{

j = 0;

if (k)

{

for (; k < count && j < TotalBytes; k++)

bufStr[j++] = c;

if (k == count)

k = 0;

}

while (j < TotalBytes)

{

fread(&c, 1, 1, fToRead);

if (0xC0 == (c & 0xC0))

{

count = 0x3F & c;

fread(&c, 1, 1, fToRead);

for (; k < count && j < TotalBytes; k++)

bufStr[j++] = c;

if (k == count)

k = 0;

}

else

bufStr[j++] = c;

}

for (j = 0; j < XSIZE; j++)

{

Image[i * XSIZE + j] = 0;

for (char u = 0; u < head.NPlanes; u++)

Image[i * XSIZE + j] |= ((int)bufStr[u * head.BytesPerLine + j] & 0xFF) << u * 8;

}

}

fclose(fToRead);

delete []bufStr;

return 1;

}

else return 0;

}

char PCXImage::save(char *fName)

{

if (Image)

{

FILE *fToWrite;

short int XSIZE, YSIZE;

short int TotalBytes;

register char cur, last, count;

register short int j, k;

char *bufStr;

const int cRGB[3] = {0xFF, 0xFF00, 0xFF0000};

if (fToWrite = fopen(fName, "wb"))

{

fwrite(&head, 128, 1, fToWrite);

XSIZE = head.Xmax - head.Xmin + 1;

YSIZE = head.Ymax - head.Ymin + 1;

TotalBytes = head.NPlanes * head.BytesPerLine;

bufStr = new char[TotalBytes];

for (int i = 0; i < YSIZE; i++)

{

for (j = 0; j < head.BytesPerLine; j++)

for (k = 0; k < head.NPlanes; k++)

if (j < XSIZE)

bufStr[k * head.BytesPerLine + j] = ((Image[i * XSIZE + j] & cRGB[k]) >> k * 8) & 0xFF;

else bufStr[k * head.BytesPerLine + j] = 0;

last = bufStr[0];

count = 1;

for (j = 1; j < TotalBytes; j++)

{

cur = bufStr[j];

if (cur == last)

{

count++;

if (count == 63)

{

count = 0xFF;

fwrite(&count, 1, 1, fToWrite);

fwrite(&last, 1, 1, fToWrite);

count = 0;

}

}

else

{

if (count)

if((count == 1) && (0xC0 != (0xC0 & last)))

fwrite(&last, 1, 1, fToWrite);

else

{

count = 0xC0 | count;

fwrite(&count, 1, 1, fToWrite);

fwrite(&last, 1, 1, fToWrite);

}

last = cur;

count = 1;

}

}

if (count)

if((count == 1) && (0xC0 != (0xC0 & last)))

fwrite(&last, 1, 1, fToWrite);

else

{

count = 0xC0 | count;

fwrite(&count, 1, 1, fToWrite);

fwrite(&last, 1, 1, fToWrite);

}

}

fclose(fToWrite);

delete []bufStr;

return 1;

}

else return 0;

}

else return 0;

}

21