/* * MandelVroom 2.0 * * (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA * * All rights reserved. * * Permission is hereby granted to distribute this program's source * executable, and documentation for non-comercial purposes, so long as the * copyright notices are not removed from the sources, executable or * documentation. This program may not be distributed for a profit without * the express written consent of the author Kevin L. Clague. * * This program is not in the public domain. * * Fred Fish is expressly granted permission to distribute this program's * source and executable as part of the "Fred Fish freely redistributable * Amiga software library." * * Permission is expressly granted for this program and it's source to be * distributed as part of the Amicus Amiga software disks, and the * First Amiga User Group's Hot Mix disks. * * contents: this file contains the functions to save projects to disk, * load projects from disk, and save icon files (if the program was started * from the WorkBench.) */ #include "mandp.h" extern struct NewScreen NewScreen; extern ULONG CalcTime; extern BYTE FromWB; ULONG BorderType; USHORT MandimageData1[] = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFC0, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFC0, 0xFFFF, 0xFFE3, 0xFFFF, 0xFFC0, 0xFFFF, 0xF101, 0x67FF, 0xFFC0, 0xFFF8, 0x7040, 0xC0F7, 0xFFC0, 0xF9D4, 0x4441, 0x414B, 0xFFC0, 0xF80F, 0x0F79, 0x8403, 0xFFC0, 0xDA0F, 0xFFFF, 0xEC01, 0xFFC0, 0x9743, 0xFFFF, 0xFE46, 0x0FC0, 0x8FFF, 0xFFFF, 0xFF80, 0x3FC0, 0xF03F, 0xFFEF, 0xFFC0, 0x7FC0, 0xB7FF, 0xFE00, 0x3F91, 0xDFC0, 0xFFFF, 0xF878, 0x3FC0, 0x07C0, 0x8FFF, 0xF8F0, 0x7F80, 0x17C0, 0xB7FF, 0xF0FF, 0xFFC0, 0x3FC0, 0xFFFF, 0xF83F, 0xFC03, 0x7FC0, 0xFFFF, 0xF70F, 0xD801, 0xFFC0, 0xFFFF, 0xFE00, 0x0000, 0xFFC0, 0xBFFF, 0xFE50, 0x415C, 0xFFC0, 0xBFFF, 0xFFFC, 0x90FF, 0xFFC0, 0xFFFF, 0xFFFD, 0xFEFF, 0xFFC0, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFC0, /**/ 0x01E0, 0xE1F0, 0xFC03, 0xFE00, 0x41E1, 0xC78F, 0xC03F, 0xF800, 0x61C7, 0x2BDD, 0xE1FF, 0x0000, 0x4394, 0x7FFF, 0xFD80, 0x0000, 0x4C57, 0xFFBF, 0x7FFD, 0xFFC0, 0x1FBB, 0xFFFF, 0xBFB4, 0x3FC0, 0x6FF0, 0xFCCF, 0xFFFC, 0xC1C0, 0x65F3, 0xF9C4, 0xB7FF, 0x9C00, 0x79FF, 0x8F33, 0x6BBD, 0xFB00, 0x70E7, 0xF136, 0x667F, 0xF9C0, 0x4FE0, 0x19D4, 0x0D3F, 0xD8C0, 0x4E9F, 0xC9FF, 0xC3EE, 0x3440, 0x6580, 0x67D7, 0xECBF, 0xFB00, 0x7A3E, 0x2FBF, 0x9EFF, 0xFF80, 0x69FF, 0xCF2A, 0xA3FF, 0xF580, 0x6700, 0x67E6, 0xC7FD, 0xB1C0, 0x583F, 0x1AF4, 0xA7FF, 0xF3C0, 0x31FF, 0xF5FF, 0xFFFF, 0x73C0, 0x53E0, 0x1DAF, 0xFEA7, 0x23C0, 0x4700, 0x00E7, 0xEF58, 0xE1C0, 0x4E07, 0xFFE3, 0x77E3, 0xC1C0, 0x383F, 0xFC00, 0x078F, 0x81C0, /**/ }; struct Image Mandimage1 = { 0, /* LeftEdge */ 0, /* TopEdge */ 58, /* Width */ 22, /* Height */ 2, /* Depth */ (USHORT *)MandimageData1, /* ImageData */ 0xFF, /* PlanePick */ 0x0, /* PlaneOnOff */ 0, /* [NextImage] */ }; struct DiskObject MandIcon = { WB_DISKMAGIC, /* do_Magic */ WB_DISKVERSION, /* do_Version */ /* Embedded Gadget Structure */ 0, /* [NextGadget] */ 23, /* LeftEdge */ 14, /* TopEdge */ 58, /* Width */ 23, /* Height */ 0x5, /* Flags */ 0x3, /* Activation */ 0x1, /* GadgetType */ (APTR)&Mandimage1, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ 0x0, /* [SpecialInfo] */ 0, /* GadgetID */ 0x0, /* [UserData] */ /* Rest of DiskObject structure */ 0x4, /* do_Type */ "MandelBrot:MandelVroom", /* do_Default Tool */ 0x0, /* [do_ToolTypes] */ 0x80000000, /* do_CurrentX */ 0x80000000, /* do_CurrentY */ 0x0, /* [do_DrawerData] */ 0x0, /* [do_ToolWindow] */ 10240 /* do_StackSize */ }; USHORT JuliaimageData1[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0F80, 0x0000, 0x0000, 0x0000, 0x0000, 0x7F60, 0x0000, 0x0000, 0x0000, 0x000F, 0xF07E, 0x0000, 0x0000, 0x0000, 0x0079, 0xC071, 0xC000, 0x0000, 0x0004, 0xFFDB, 0xFFFE, 0xFC00, 0x0000, 0x001C, 0x6FDF, 0xFFFF, 0xFF7D, 0x0000, 0x00FF, 0xF183, 0xFFE0, 0x73C3, 0xC000, 0x05FF, 0xF100, 0x7FE0, 0xC3FF, 0xFC00, 0x33C3, 0xFC00, 0x7FFE, 0x007C, 0x6D80, 0x1F85, 0xF800, 0xFFF8, 0x007F, 0x0670, 0x03F1, 0xFC06, 0x3FF0, 0x01FE, 0x03E0, 0x003B, 0xFF98, 0x0FF0, 0x021F, 0xDF80, 0x000F, 0x187C, 0x3FFF, 0xE6FE, 0xB000, 0x0003, 0xFFFD, 0xFFFF, 0xDFC1, 0xC000, 0x0000, 0x003E, 0x7FDF, 0x7FFF, 0x0000, 0x0000, 0x0006, 0x785B, 0x6000, 0x0000, 0x0000, 0x0000, 0xFC7E, 0x0000, 0x0000, 0x0000, 0x0000, 0x1BF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0380, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /**/ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0D80, 0x0000, 0x0000, 0x0000, 0x0000, 0x70E0, 0x0000, 0x0000, 0x0000, 0x000F, 0xFFFE, 0x0000, 0x0000, 0x0000, 0x007E, 0x3F8F, 0xC000, 0x0000, 0x0007, 0xFFF4, 0x0001, 0xFC00, 0x0000, 0x001F, 0x93E0, 0x0000, 0xFFF3, 0x0000, 0x00F0, 0x0FFC, 0x001F, 0xFC3D, 0xC000, 0x0660, 0x0FFF, 0x801F, 0xFC00, 0x7C00, 0x2C7C, 0x1FFF, 0x9FFF, 0xFF83, 0xF380, 0x1C7E, 0x07FF, 0xFFFF, 0xFF83, 0xF990, 0x03FE, 0x03FF, 0xFF8F, 0xFFC1, 0xFC60, 0x003C, 0x007F, 0xF00F, 0xFFE0, 0x3F80, 0x000F, 0xE7FB, 0xC000, 0x1F03, 0x7000, 0x0002, 0xFFFE, 0x0000, 0x3FFE, 0xC000, 0x0000, 0x003F, 0x80A1, 0xFFFF, 0x0000, 0x0000, 0x0007, 0xC7E6, 0xE000, 0x0000, 0x0000, 0x0000, 0xFFBE, 0x0000, 0x0000, 0x0000, 0x0000, 0x1C70, 0x0000, 0x0000, 0x0000, 0x0000, 0x0280, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /**/ }; struct Image Juliaimage1 = { 0, /* LeftEdge */ 0, /* TopEdge */ 78, /* Width */ 22, /* Height */ 2, /* Depth */ (USHORT *)JuliaimageData1, /* ImageData */ 0xFF, /* PlanePick */ 0x0, /* PlaneOnOff */ 0, /* [NextImage] */ }; struct DiskObject JuliaIcon = { WB_DISKMAGIC, /* do_Magic */ WB_DISKVERSION, /* do_Version */ /* Embedded Gadget Structure */ 0, /* [NextGadget] */ 23, /* LeftEdge */ 14, /* TopEdge */ 78, /* Width */ 23, /* Height */ 0x5, /* Flags */ 0x3, /* Activation */ 0x1, /* GadgetType */ (APTR)&Juliaimage1, /* GadgetRender */ NULL, /* SelectRender */ NULL, /* GadgetText */ 0x0, /* MutualExclude */ 0x0, /* [SpecialInfo] */ 0, /* GadgetID */ 0x0, /* [UserData] */ /* Rest of DiskObject structure */ 0x4, /* do_Type */ "MandelBrot:MandelVroom", /* do_Default Tool */ 0x0, /* [do_ToolTypes] */ 0x80000000, /* do_CurrentX */ 0x80000000, /* do_CurrentY */ 0x0, /* [do_DrawerData] */ 0x0, /* [do_ToolWindow] */ 10240 /* do_StackSize */ }; /* * Save all the data needed to restore the system to current state. */ int SaveCounts(SaveName, Pict) register char *SaveName; register struct Picture *Pict; { register FILE *SaveFile; USHORT ViewModes; UBYTE Depth; ULONG Version = VERSION; char ErrMsg[80]; /* * Change the mouse pointer to Sleepy pointer */ SetSleepyPointer(); /* * open the desired file for writing */ SaveFile = fopen(SaveName,"w"); if (SaveFile == (FILE *) NULL) { sprintf(ErrMsg, "Can't open file %s", SaveName); DispErrMsg(ErrMsg, 0); return(UNSUCCESSFUL); } Pict->LeftEdge = Pict->Window->LeftEdge; Pict->TopEdge = Pict->Window->TopEdge; /* * if there is data to save, save it */ if (Pict->Counts && ! (Pict->Flags & NO_RAM_GENERATE) ) { if (Pict->pNode.ln_Type == MANDPICT) { /* * Put out the file header */ fwrite((char *) "MAN4", 4, 1, SaveFile); } else { /* * Put out the file header */ fwrite((char *) "JUL4", 4, 1, SaveFile); } /* * Put out the revision number */ fwrite((char *) Version, sizeof(Version), 1, SaveFile); if (Pict->pNode.ln_Type == JULIAPICT) { /* * Put out the Julia point */ fwrite((char *) &Pict->Real, sizeof(double), 1, SaveFile); fwrite((char *) &Pict->Imag, sizeof(double), 1, SaveFile); } /* * Put out the location on the complex plane */ fwrite((char *) &Pict->RealLow, sizeof(double), 1, SaveFile); fwrite((char *) &Pict->ImagLow, sizeof(double), 1, SaveFile); fwrite((char *) &Pict->RealHigh, sizeof(double), 1, SaveFile); fwrite((char *) &Pict->ImagHigh, sizeof(double), 1, SaveFile); /* * Put out the Maximum iteration count for a given point */ fwrite((char *) &Pict->MaxIteration, sizeof(SHORT), 1, SaveFile); /* * Put out the generator type */ fwrite((char *) &Pict->MathMode, sizeof(Pict->MathMode), 1, SaveFile); /* * Put out the time it took to generate */ fwrite((char *) &CalcTime, sizeof(CalcTime), 1, SaveFile); /* * Put out the screen's viewmodes */ ViewModes = NewScreen.ViewModes; fwrite((char *) &ViewModes, sizeof(ViewModes), 1, SaveFile); /* * Put out the number of bit planes */ Depth = NewScreen.Depth; fwrite((char *) &Depth, sizeof(Depth), 1, SaveFile); /* * Put some window flags */ fwrite((char *) &BorderType, sizeof(BorderType), 1, SaveFile); /* * Save the Color Palette */ fwrite((char *) &Pict->RGBs, sizeof(Pict->RGBs), 1, SaveFile); /* * Save the number of contours */ fwrite((char *) &NumContours, sizeof(NumContours), 1, SaveFile); /* * Save the contour's heights */ fwrite((char *) Pict->Heights, sizeof(SHORT), (int) NumContours, SaveFile); /* * Save the contour's pen numbers (Color is a misnomer) */ fwrite((char *) Pict->Pens, sizeof(UBYTE), (int) NumContours, SaveFile); /* * Put out the image dimensions */ fwrite((char *) &Pict->CountX, sizeof(SHORT), 1, SaveFile); fwrite((char *) &Pict->CountY, sizeof(SHORT), 1, SaveFile); /* * Put out project's position */ fwrite((char *) &Pict->LeftEdge, sizeof(Pict->LeftEdge), 1, SaveFile); fwrite((char *) &Pict->TopEdge, sizeof(Pict->TopEdge), 1, SaveFile); fwrite((char *) &Pict->CurLine, sizeof(Pict->CurLine), 1, SaveFile); (void) WriteRLLTwo( SaveFile, Pict ); } else { DispErrMsg("No Picture to save",0); fclose(SaveFile); return(UNSUCCESSFUL); } fclose(SaveFile); if (FromWB) { FILE *IconFile; char IconName[80]; strcpy( IconName, SaveName ); strcat( IconName, ".info" ); if ((IconFile = fopen( IconName, "r" )) == NULL) { /* * OutPut an icon for the saved picture */ if (Pict->pNode.ln_Type == MANDPICT) (void) PutDiskObject(SaveName,&MandIcon); else (void) PutDiskObject(SaveName,&JuliaIcon); } else { fclose( IconFile ); } } return(SUCCESSFUL); } /* SaveCounts */ int WriteRLLTwo( SaveFile, Pict ) register FILE *SaveFile; register struct Picture *Pict; { LONG Words; Words = Compress( Pict ); fwrite( (char *) &Words, sizeof(LONG), 1, SaveFile); /* in case I ever recompile into 16 bit ints */ if (sizeof(int) == 2 && sizeof(int)*Words > 65535) { DispErrMsg("Programming error in Savemand\n", 0); return(UNSUCCESSFUL); } fwrite( (char *) Pict->Counts, (int) (sizeof(SHORT) * Words), 1, SaveFile); Decompress( Words, Pict ); return( SUCCESSFUL ); } /* Compress the data. Count up how many words in a row have the same value. * If the count is only one, then just put the data in the compressed array. * Otherwise, turn on the most significant bit in the Count, and put it * in the compressed array, then put the potential in the array. * * Advantages: * - Compressed data guaranteed to be as small or smaller than uncompressed * data. * - Compression can be done in place in memory, so it is fast without * requiring extra memory. * - Once compressed, the data can be written to disk with one fwrite, * therefore it should be quicker than previously used method that * compressed and wrote to disk at the same time. * - Maximum iteration count for Mandelbrot potential is 32767. The * previous method only allowed 1023. */ int Compress( Pict ) register struct Picture *Pict; { register SHORT *CountPtr,*CompressPtr; register SHORT Count; register USHORT Cur; register ULONG i; register ULONG Word = 0; i = Pict->CountsSize/sizeof(SHORT); CountPtr = CompressPtr = Pict->Counts; Cur = *CountPtr; Count = 1; while (--i) { CountPtr++; /* * Count up how many in a row have same height */ if (Cur == *CountPtr) { Count++; } else { if ( Count > 1 ) { *CompressPtr++ = Count | 0x8000; } *CompressPtr++ = Cur; Count = 1; Cur = *CountPtr; } } if ( Count > 1 ) { *CompressPtr++ = Count | 0x8000; } *CompressPtr++ = Cur; Word = CompressPtr - Pict->Counts; return( Word ); } /* * Load the state of the program from file */ int LoadCounts(LoadName, Pict ) register char *LoadName; register struct Picture *Pict; { register FILE *LoadFile; USHORT ViewModes; UBYTE Depth; char Header[5]; ULONG Version; char ErrMsg[80]; int rc; char *File, *ExtractName(); extern int Num_vp_Colors; extern USHORT NewViewModes; extern UBYTE NewDepth; extern struct MathTransBase *MathTransBase; extern LONG SPTIEEE; /* * Change the mouse pointer to Sleepy pointer */ SetSleepyPointer(); LoadFile = fopen(LoadName,"r"); Pict->GenState = FINISHEDSTATE; if (LoadFile == (FILE *) NULL) { /* * can't read a non-existant file */ sprintf(ErrMsg, "File %s not found", LoadName); DispErrMsg(ErrMsg, 0); return( UNSUCCESSFUL ); } /* * Read and check the file header */ (void) fread((char *) &Header[0], 4, 1, LoadFile); Header[4] = '\0'; if (strcmp(&Header[0], "MAND") != 0 && strcmp(&Header[0], "MAN1") != 0 && strcmp(&Header[0], "MAN2") != 0 && strcmp(&Header[0], "MAN3") != 0 && strcmp(&Header[0], "MAN4") != 0 && strcmp(&Header[0], "JUL3") != 0 && strcmp(&Header[0], "JUL4") != 0 ) { /* * File of improper format */ sprintf(ErrMsg, "File %s is not a MAND file",LoadName); DispErrMsg(ErrMsg, 0); fclose(LoadFile); return( UNSUCCESSFUL ); } /* * Read in the version */ (void) fread((char *) &Version, sizeof(Version), 1, LoadFile); if ( strcmp( &Header[0], "MAN2") == 0 || strcmp( &Header[0], "MAN3") == 0 || strcmp( &Header[0], "MAN4") == 0 || strcmp( &Header[0], "JUL3") == 0 || strcmp( &Header[0], "JUL4") == 0 ) { if ( strcmp( &Header[0], "JUL3") == 0 || strcmp( &Header[0], "JUL4") == 0 ) { Pict->pNode.ln_Type = JULIAPICT; (void) fread((char *) &Pict->Real, sizeof(double), 1, LoadFile); (void) fread((char *) &Pict->Imag, sizeof(double), 1, LoadFile); } else { Pict->pNode.ln_Type = MANDPICT; } /* * Read in the location in the complex plane */ (void) fread((char *) &Pict->RealLow, sizeof(double), 1, LoadFile); (void) fread((char *) &Pict->ImagLow, sizeof(double), 1, LoadFile); (void) fread((char *) &Pict->RealHigh, sizeof(double), 1, LoadFile); (void) fread((char *) &Pict->ImagHigh, sizeof(double), 1, LoadFile); } else { /* Must be old FFP code */ LONG startx, starty, endx, endy; LONG SPTieee(); /* * Read in the FFP form of location in the complex plane */ (void) fread((char *) &startx, sizeof(LONG), 1, LoadFile); (void) fread((char *) &starty, sizeof(LONG), 1, LoadFile); (void) fread((char *) &endx, sizeof(LONG), 1, LoadFile); (void) fread((char *) &endy, sizeof(LONG), 1, LoadFile); /* * Convert it to IEEE format */ if (OpenFFPLibs() != 0) return(UNSUCCESSFUL); startx = SPTieee( startx ); starty = SPTieee( starty ); endx = SPTieee( endx ); endy = SPTieee( endy ); /* * promote them to doubles */ Pict->RealLow = (double) *( (float *) &startx ); Pict->ImagLow = (double) *( (float *) &starty ); Pict->RealHigh = (double) *( (float *) &endx ); Pict->ImagHigh = (double) *( (float *) &endy ); } /* * Read in the maximum iteration count for a given point */ (void) fread((char *) &Pict->MaxIteration, sizeof(SHORT), 1, LoadFile); /* * Read in the generator type */ (void) fread((char *) &Pict->MathMode, sizeof(Pict->MathMode), 1, LoadFile); /* * Read in the calculation time */ (void) fread((char *) &CalcTime, sizeof(CalcTime), 1, LoadFile); /* * Read in the screen's viewmodes */ (void) fread((char *) &ViewModes, sizeof(ViewModes), 1, LoadFile); ViewModes &= HIRES | INTERLACE | EXTRA_HALFBRITE; Pict->ViewModes = ViewModes; /* * Read in the number of bit planes */ (void) fread((char *) &Depth, sizeof(Depth), 1, LoadFile); Pict->Depth = Depth; /* * Read in the window flags */ (void) fread((char *) &BorderType, sizeof(BorderType), 1, LoadFile); /* * Read in the color palette information */ (void) fread((char *) &Pict->RGBs[0], sizeof(Pict->RGBs), 1, LoadFile); /* * Read in the number of contours */ (void) fread((char *) &NumContours, sizeof(NumContours), 1, LoadFile); /* * Read in the heights */ (void) fread((char *) Pict->Heights, sizeof(SHORT), NumContours, LoadFile); /* * Read in the pen numbers (Color is a misnomer) */ (void) fread((char *) Pict->Pens, sizeof(UBYTE), NumContours, LoadFile); for ( ; NumContours < NUMCONTS; NumContours++ ) { *(Pict->Heights + NumContours) = 0; *(Pict->Pens + NumContours) = 0; } /* * Read in the image dimensions */ (void) fread((char *) &Pict->CountX, sizeof(SHORT), 1, LoadFile); (void) fread((char *) &Pict->CountY, sizeof(SHORT), 1, LoadFile); if ( strcmp( &Header[0], "MAN4") == 0 || strcmp( &Header[0], "JUL4") == 0 ) { /* * Read in the image dimensions */ (void) fread((char *) &Pict->LeftEdge, sizeof(Pict->LeftEdge), 1, LoadFile); (void) fread((char *) &Pict->TopEdge, sizeof(Pict->TopEdge), 1, LoadFile); (void) fread((char *) &Pict->CurLine, sizeof(Pict->CurLine), 1, LoadFile); if (Pict->CurLine > Pict->CountY) Pict->CurLine -= TOPMARG; } else { Pict->CurLine = Pict->CountY; } GetCountsMemory( Pict ); if (Pict->Counts == (SHORT *) NULL || (Pict->Flags & NO_RAM_GENERATE)) { DispErrMsg("Can't load counts. Out of RAM!!",0); fclose(LoadFile); return( UNSUCCESSFUL ); } if ( strcmp( &Header[0], "MAN3") == 0 || strcmp( &Header[0], "MAN4") == 0 || strcmp( &Header[0], "JUL3") == 0 || strcmp( &Header[0], "JUL4") == 0 ) { rc = ReadRLLTwo( LoadFile, Pict ); } else { rc = ReadRLLOne( LoadFile, Pict ); } fclose(LoadFile); if (rc != SUCCESSFUL) { return( rc ); } File = ExtractName( LoadName ); strncpy( Pict->Title, " ", 2); strncat( Pict->Title, File, sizeof(Pict->Title)-3); CalculateGaps( Pict ); NewViewModes = Pict->ViewModes; NewDepth = Pict->Depth; if ( MaybeNewScreen() == 0 ) { /* * Let's show it to them */ if (OpenPicture( Pict ) != 0) { return( UNSUCCESSFUL ); } else { LoadRGB4( vp, Pict->RGBs, Num_vp_Colors ); ReColor( Pict ); } } GetCurPict(); if (CurPict) { LoadRGB4( vp, CurPict->RGBs, Num_vp_Colors ); } InitBorderSubs(); return( SUCCESSFUL ); } /* LoadCounts */ /* Load count information in pseudo RLL format */ /* Bits 9-0 are iteration count. */ /* Bits 15-10 are how many iteration count of same height in a row */ int ReadRLLOne( LoadFile, Pict ) register FILE *LoadFile; register struct Picture *Pict; { register SHORT *CountPtr; register LONG i; register ULONG Count = 0; USHORT t; CountPtr = Pict->Counts; i = Pict->CountsSize / sizeof( SHORT ); while (i > 0) { if ( fread((char *) &t, sizeof(t), 1, LoadFile) == 0) { DispErrMsg("Premature EOF on source file",0); fclose(LoadFile); return( UNSUCCESSFUL); } Count = t >> 10; t = t & 0x3ff; for (; Count > 0; Count--) { *(CountPtr++) = t; i--; } } return( SUCCESSFUL ); } int ReadRLLTwo( LoadFile, Pict ) register FILE *LoadFile; register struct Picture *Pict; { LONG Words; if (fread((char *) &Words, sizeof(Words), 1, LoadFile) == 0) { DispErrMsg("Premature EOF on source file",0); fclose(LoadFile); return(UNSUCCESSFUL); } if (fread((char *) Pict->Counts,(int)(sizeof(SHORT)*Words),1,LoadFile) == 0){ DispErrMsg("Premature EOF on source file",0); fclose(LoadFile); return(UNSUCCESSFUL); } Decompress( Words, Pict ); return( SUCCESSFUL ); } /* This algorithm decompresses the data. The data array has * been malloced large enough to hold the decompressed data. The data * is read from the disk into the array in compressed format. This * decompresses the data in place. The data must be decompressed from the * back to the front. */ Decompress( Word, Pict ) LONG Word; struct Picture *Pict; { register SHORT *CountPtr, *CompressPtr; register SHORT Count,Cur; register LONG i; register SHORT j; /* Point to the last word of compressed data */ CompressPtr = Pict->Counts + Word - 1; i = Pict->CountsSize/sizeof(SHORT); /* Point to the last word of uncompressed data */ CountPtr = Pict->Counts + i - 1; /* While there is data to uncompress.... */ while (i > 1 && CountPtr >= Pict->Counts && CompressPtr >= Pict->Counts) { /* Pick up the last two words */ Cur = *CompressPtr--; Count = *CompressPtr; if (Count & 0x8000) { /* is it compressed? */ Count &= 0x7fff; /* extract count */ for ( j = 0; j < Count; j++) { /* Decompress it */ *CountPtr-- = Cur; i--; } CompressPtr--; } else { *CountPtr-- = Cur; /* just move it */ i--; } } }