void PrepareGuesses(HWND hWnd) { int i; bFinished = FALSE; iPieces = ImgCountObjects(lpImage); iGuessesLeft = iPieces * 60 / 100; switch (iPieces) { case 10+1: iGuessesLeft = 15; break; case 15+1: iGuessesLeft = 12; break; case 20+1: default: iGuessesLeft = 10; break; } SetDlgItemInt(hWnd, IDC_PUZZLE_CHANGES, iGuessesLeft, FALSE); lstrcpy( szGuessDisplay, szGuess ); for (i=0; i<lstrlen(szGuessDisplay); i++) if ( szGuessDisplay[i] > ' ' ) szGuessDisplay[i] = '*'; SetDlgItemText(hWnd, IDC_PUZZLE_NAME, szGuessDisplay); }
STATUS_CODE ApplyColorMap(LPIMAGE lpImage, LPCOLORMAP lpColorMap, BOOL fReMap, DITHER_TYPE DitherType, ITEMID idDirty) /************************************************************************/ { UNDO_TYPE UndoType; int iMaxWidth; FRMTYPEINFO OldTypeInfo, NewTypeInfo; LPOBJECT lpObject; RECT rEdit; CFrameTypeConvert TypeConvert; UndoType = UT_COLORMAP; if (fReMap) UndoType |= UT_DATA; if (!ImgEditInit(lpImage, ET_ALLOBJECTS, UndoType, NULL)) return(SC_UNDOERROR); ProgressBegin(ImgCountObjects(lpImage), idDirty-IDS_UNDOFIRST+IDS_PROGFIRST); if (fReMap) { ImgGetTypeInfo(lpImage, &OldTypeInfo); FrameSetTypeInfo(&NewTypeInfo, FDT_PALETTECOLOR, lpColorMap); iMaxWidth = 0; lpObject = NULL; while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO)) { if (RectWidth(&lpObject->rObject) > iMaxWidth) iMaxWidth = RectWidth(&lpObject->rObject); } if (!TypeConvert.Init(OldTypeInfo, NewTypeInfo, iMaxWidth, DitherType)) { ProgressEnd(); Message(IDS_EMEMALLOC); return(SC_MEMERROR); } } lpObject = NULL; while (lpObject = ImgGetNextObjectEx(lpImage, lpObject, YES, NO, YES)) { if (fReMap) PaletteMapPixmap(&lpObject->Pixmap, &TypeConvert); FrameSetColorMap(ObjGetEditFrame(lpObject), lpColorMap); rEdit = lpObject->rObject; ImgEditedObject(lpImage, lpObject, idDirty, &rEdit); } ImgColorMapChanged(lpImage); ProgressEnd(); return(SC_SUCCESS); }
void ImgEditUndo( LPIMAGE lpImage, BOOL fEditUndo, BOOL fMaskUndo ) /***********************************************************************/ { RECT rUndo, rUndoMask, rTemp; LPOBJECT lpBase, lpObject, lpNext; BOOL fNewSize, fSetupMiniViews, fRemoveMarquee, fUndoDelete; BOOL fUndoAlpha, fUndoData; int nDeleted; LPMASK lpMask; if (!lpImage) return; // Initialize things for updating the display fNewSize = fSetupMiniViews = fUndoDelete = NO; AstralSetRectEmpty(&rUndo); AstralSetRectEmpty(&rUndoMask); // loop through objects doing undo lpBase = ImgGetBase(lpImage); lpObject = NULL; while (lpObject = ImgGetNextObjectEx(lpImage, lpObject, NO, NO, fEditUndo)) { // See if this is an object we are undoing if (fEditUndo) { // check for special undo processing of a deleted object if (lpObject->fDeleted) { if (Control.UndoObjects && !ImgIsSelectedObject(lpImage, lpBase)) continue; } else if (Control.UndoObjects && !ImgIsSelectedObject(lpImage, lpObject)) continue; } // Only handle mask undo for the base object if (fMaskUndo) { if (lpObject != lpBase || lpObject->fBothDirty || !lpObject->AlphaDirty) continue; } fUndoData = fUndoAlpha = NO; // Do preprocess for doing a data undo if (fEditUndo) { if (lpObject->DataDirty) fUndoData = YES; // See if we need to undo the alpha for this object if ((lpObject != lpBase) && lpObject->lpAlpha && lpObject->AlphaDirty) fUndoAlpha = YES; if (!fUndoData && !fUndoAlpha) continue; // check to see and undoing/redoing deleted objects will change // the select state, if so undraw the object marquee if (lpObject == lpBase && lpObject->DataUndoType & UT_DELETEOBJECTS) { fUndoDelete = YES; fRemoveMarquee = NO; nDeleted = 0; lpNext = lpObject; while (lpNext = ImgGetNextObjectEx(lpImage, lpNext, YES, NO, YES)) { if (lpNext->fUndoDeleted) ++nDeleted; else if (lpNext->fDeleted && lpNext->fSelected) { fRemoveMarquee = YES; break; } } if (ImgGetSelObject(lpImage, NULL) == lpBase && !fRemoveMarquee) { if (ImgCountObjects(lpImage) - nDeleted <= 1) fRemoveMarquee = YES; } if (fRemoveMarquee) RemoveObjectMarqueeEx(lpImage, NO); } } else // fMaskUndo if (!lpObject->AlphaDirty) continue; else fUndoAlpha = YES; // do a preprocess for undoing the mask caused either by // a mask undo or by an edit function that also edits the mask if (((lpObject == lpBase) && fEditUndo && lpObject->fBothDirty) || fMaskUndo) { if ( lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK) ) { // if the undo is going to delete the mask, // we need to undraw the mask if (ImgGetMask(lpImage)) { RemoveMaskMarquee(lpImage); if (ImgGetMaskUpdateRect(lpImage, YES, NO, &rTemp)) AstralUnionRect(&rUndoMask, &rUndoMask, &rTemp); } // if the undo is going to create the mask, // we need to undraw the object marquees if // not in mask and object marquee mode else { if (!Control.UseMaskAndObjects) RemoveObjectMarqueeEx(lpImage, NO); } } } // Actually do the undo ObjEditUndo(lpImage, lpObject, fUndoData, fUndoAlpha); // do a postprocess for undoing the mask if ((lpMask = ImgGetMask(lpImage)) && (((lpObject == lpBase) && fEditUndo && lpObject->fBothDirty) || fMaskUndo)) { // if the undo is going to add the mask, we need to redraw the mask if (lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK) ) { if (ImgGetMaskUpdateRect(lpImage, YES, NO, &rTemp)) AstralUnionRect(&rUndoMask, &rUndoMask, &rTemp); } else // just redraw the undo area for the mask AstralUnionRect(&rUndoMask, &rUndoMask, &lpMask->Pixmap.UndoRect); } // Setup rectangle for undoing deletion of objects // Handled specially so that moved objects will still undo // and redo properly if (fEditUndo) { if (lpObject == lpBase && lpObject->DataUndoType & UT_DELETEOBJECTS) { lpNext = lpObject; while (lpNext = ImgGetNextObjectEx(lpImage, lpNext, YES, NO, YES)) { if (lpNext->fDeleted || lpNext->fUndoDeleted) AstralUnionRect(&rUndo, &rUndo, &lpNext->rObject); } fSetupMiniViews = YES; } if (lpObject->Pixmap.fNewFrame) { /* if new frame, cause window to be redisplayed */ if (lpObject == lpBase) fNewSize = YES; else { if (!fNewSize) { AstralUnionRect(&rUndo, &rUndo, &lpObject->rObject); AstralUnionRect(&rUndo, &rUndo, &lpObject->rUndoObject); } } } else { AstralSetRectEmpty(&rTemp); if (fUndoData) AstralUnionRect(&rTemp, &rTemp, &lpObject->Pixmap.UndoRect); if (fUndoAlpha) AstralUnionRect(&rTemp, &rTemp, &lpObject->lpAlpha->Pixmap.UndoRect); if (rTemp.right >= rTemp.left) { if (!fNewSize) { OffsetRect(&rTemp, lpObject->rObject.left, lpObject->rObject.top); AstralUnionRect(&rUndo, &rUndo, &rTemp); } } } } } // now redisplay whatever changes are necessary for the undo if (fNewSize) { SetupImagePalette(lpImage, NO, YES); if (lpBase->Pixmap.UndoFrame) { if ((FrameXSize(lpBase->Pixmap.UndoFrame) == FrameXSize(lpBase->Pixmap.EditFrame)) && (FrameYSize(lpBase->Pixmap.UndoFrame) == FrameYSize(lpBase->Pixmap.EditFrame))) fNewSize = NO; } if (fNewSize) UpdateImageSize(); else UpdateImageEx(lpImage, NULL, YES, YES, YES); if ( Tool.hRibbon ) SendMessage( Tool.hRibbon, WM_CONTROLENABLE, 0, 0L ); } else { if (rUndoMask.right >= rUndoMask.left) { File2DispRect(&rUndoMask, &rUndoMask); AstralToWindowsRect(&rUndoMask); InvalidateRect(lpImage->hWnd, NULL, NO); } if (rUndo.right >= rUndo.left) AnimateUndo( &rUndo ); } if (fUndoDelete) if ( Tool.hRibbon ) SendMessage( Tool.hRibbon, WM_CONTROLENABLE, 0, 0L ); if (fSetupMiniViews) SetupMiniViews(NULL, NO); }
BOOL ConvertImage(LPIMAGE lpImage, LPCONVERT_PARMS lpParms) /***********************************************************************/ { BOOL fRet = FALSE; LPFRAME lpDstFrame, lpBaseFrame; LPOBJECT lpBase, lpObject; BOOL fError, fOptimize, fProgressSet; INTERNAL_DATA data; int inDepth, iMaxWidth, nColors, i; LPCOLORMAP lpColorMap; LPRGB lpRGB; FRMTYPEINFO InTypeInfo, OutTypeInfo; CFrameTypeConvert TypeConvert; DITHER_TYPE DitherType = DT_DEFAULT; if (ImgInMaskEditMode(lpImage)) return(TRUE); lpColorMap = NULL; lpBase = ImgGetBase(lpImage); lpBaseFrame = ObjGetEditFrame(lpBase); inDepth = FrameDepth(lpBaseFrame); OutTypeInfo = lpParms->cmsInfo.dst; FrameGetTypeInfo(lpBaseFrame, &InTypeInfo); // are we try to convert to a color managed image? if (Control.CMSEnabled && IsDstPTSelected(&OutTypeInfo.ptInfo)) { // see if our image already has a color managed source if (!IsSrcPTSelected(&InTypeInfo.ptInfo)) { // nope, see if the source passed in is valid for this image if (IsSrcPTSelected(&lpParms->cmsInfo.src.ptInfo) && (lpParms->cmsInfo.src.DataType == InTypeInfo.DataType)) { InTypeInfo = lpParms->cmsInfo.src; } // go get a source from the user else { CMSINFO CmsInfo2; if( CmsGetSrcPTType( &InTypeInfo, &CmsInfo2) ) InTypeInfo = CmsInfo2.src; } } } else FrameSetTypeInfo(&InTypeInfo, InTypeInfo.DataType, InTypeInfo.ColorMap); // no conversion necessary if (FrameTypeInfoEqual(InTypeInfo, OutTypeInfo)) return(TRUE); DitherType = lpParms->DitherType; fOptimize = lpParms->ConvertType == CT_OPTIMIZED; fProgressSet = FALSE; if ( OutTypeInfo.DataType == FDT_PALETTECOLOR/* && inDepth >= 3 */) { if (lpParms->ConvertType == CT_CUSTOM) { FNAME szFileName; if ( !LookupExtFileN( lpParms->szPalette, szFileName, IDN_PALETTE, NO ) ) return(FALSE); if (!(lpColorMap = Palette_ReadColorMap(szFileName))) return(FALSE); } else { // allocate a map to carry around with image lpColorMap = FrameCreateColorMap(); if (!lpColorMap) { Message(IDS_EMEMALLOC); goto MemError; } lpColorMap->NumEntries = lpParms->iLevels; if (InTypeInfo.DataType == FDT_GRAYSCALE && lpColorMap->NumEntries == 256 && fOptimize) { DitherType = DT_NONE; lpRGB = lpColorMap->RGBData; for (i = 0; i < lpColorMap->NumEntries; ++i) { lpRGB->red = lpRGB->green = lpRGB->blue = i; ++lpRGB; } } else { // 1. CreateOptimizedPalette phase - only if fOptimize // 2. Mapping phase ProgressBegin(fOptimize ? 2 : 1, lpParms->Common.idDirty-IDS_UNDOFIRST+IDS_PROGFIRST); fProgressSet = TRUE; if (fOptimize) ProgressBegin(1, 0); if (!CreateOptimizedPalette(lpBase, ObjGetEditFrame(lpBase), lpColorMap->RGBData, &lpColorMap->NumEntries, fOptimize, fOptimize ? AstralClockCursor : NULL)) { if (fOptimize) ProgressEnd(); Message(IDS_EMEMALLOC); goto ExitFalse; } if (fOptimize) ProgressEnd(); } } if (lpColorMap->NumEntries <= 16) lpColorMap->NumEntries = 16; else lpColorMap->NumEntries = 256; FrameSetTypeInfo(&OutTypeInfo, FDT_PALETTECOLOR, lpColorMap); } if (!fProgressSet) ProgressBegin(1, lpParms->Common.idDirty-IDS_UNDOFIRST+IDS_PROGFIRST); fProgressSet = TRUE; iMaxWidth = 0; lpObject = NULL; while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO)) { if (RectWidth(&lpObject->rObject) > iMaxWidth) iMaxWidth = RectWidth(&lpObject->rObject); } if (!TypeConvert.Init(InTypeInfo, OutTypeInfo, iMaxWidth, DitherType)) { Message(IDS_EMEMALLOC); goto ExitFalse; } if (ImgMultipleObjects(lpImage)) { ProgressBegin(ImgCountObjects(lpImage), 0); if ( !ImgEditInit(lpImage, ET_ALLOBJECTS, UT_NEWDATA|UT_COLORMAP, lpBase) ) goto ExitFalse; fError = NO; lpObject = NULL; while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO)) { lpDstFrame = ConvertFrame(ObjGetEditFrame(lpObject), OutTypeInfo, &TypeConvert); if (!lpDstFrame) { fError = YES; break; } ImgEditedObjectFrame( lpImage, lpObject, lpParms->Common.idDirty, NULL, lpDstFrame, NULL); } if (fError) { lpObject = NULL; while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO)) { if (lpObject->Pixmap.UndoFrame) { lpDstFrame = lpObject->Pixmap.EditFrame; lpObject->Pixmap.EditFrame = lpObject->Pixmap.UndoFrame; lpObject->Pixmap.UndoFrame = NULL; FrameClose(lpDstFrame); } } } ProgressEnd(); } else { if ( !ImgEditInit(lpImage, ET_OBJECT, UT_NEWDATA|UT_COLORMAP, lpBase) ) goto ExitFalse; ProgressBegin(1, 0); lpDstFrame = ConvertFrame(lpBaseFrame, OutTypeInfo, &TypeConvert); ProgressEnd(); if (!lpDstFrame) goto ExitFalse; /* Setup the new image and bring up the new image window */ ImgEditedObjectFrame( lpImage, lpBase, lpParms->Common.idDirty, NULL, lpDstFrame, NULL); } switch (lpParms->cmsInfo.dst.DataType) { case FDT_LINEART: lpImage->DataType = IDC_SAVELA; break; case FDT_GRAYSCALE: lpImage->DataType = IDC_SAVECT; break; case FDT_PALETTECOLOR: lpImage->DataType = IDC_SAVE8BITCOLOR; break; case FDT_RGBCOLOR: lpImage->DataType = IDC_SAVE24BITCOLOR; break; case FDT_CMYKCOLOR: lpImage->DataType = IDC_SAVE32BITCOLOR; break; } ImgColorMapChanged(lpImage); lpParms->Common.UpdateType = UT_DATATYPE; fRet = TRUE; ExitFalse: if (fProgressSet) ProgressEnd(); MemError: if (lpColorMap) FrameDestroyColorMap(lpColorMap); return(fRet); }
int objwrt(LPIMAGE lpImage, LPSTR lpFileName, int idFileType, LPRECT lpRect, int flag, BOOL fCompressed) /************************************************************************/ { LPOBJECT lpObject; int ofp; LPLONG lngptr; LPWORD shtptr; FNAME temp; BOOL bEscapable; int nObjects, i, nPasses; long lObjStart; WORD wBytes; LPOBJOFFSETS lpOffsets; if (!lpImage) return( -1 ); lpObject = NULL; nObjects = nPasses = 0; while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO)) { if (lpObject->lpAlpha && (nObjects || Save.bSaveMask)) ++nPasses; ++nObjects; ++nPasses; } if (!(lpOffsets = (LPOBJOFFSETS)Alloc(sizeof(OBJOFFSETS)*nObjects))) { Message(IDS_EMEMALLOC); return(-1); } bEscapable = !FileExists(lpFileName); #ifdef _MAC // The Mac file system can't handle the following pathname: // Bad ---> "DIR:FILE.EXT" // Needs to be -> ":DIR:FILE.EXT" // Add the additional ':' here to specify starting at our directory. if (lpFileName[0] != ':') { STRING szName; lstrcpy(szName, lpFileName); lstrcpy(lpFileName+1, szName); lpFileName[0] = ':'; } #endif if ((ofp = _lcreat(lpFileName,0)) < 0) { FreeUp((LPTR)lpOffsets); Message( IDS_EOPEN, lpFileName ); return(-1); } ProgressBegin(nPasses, 0); // Fill in header info shtptr = (LPWORD)LineBuffer[0]; SetNextWord(&shtptr, 0x4949); /* byte order is LSB,MSB */ SetNextWord(&shtptr, OBJ_VERSION); /* Version Number */ SetNextWord(&shtptr, ImgCountObjects(lpImage)); /* Number of Objects */ lngptr = (LPLONG)shtptr; SetNextLong(&lngptr, OBJ_DATA_SIZE); /* size of object data */ SetNextLong(&lngptr, OBJ_HDR_SIZE); /* start of object data */ // Write out header info wBytes = (LPTR)lngptr - (LPTR)LineBuffer[0]; if ( _lwrite(ofp, LineBuffer[0], wBytes) != wBytes ) goto BadWrite; lObjStart = _llseek (ofp, 0L, 1); wBytes = OBJ_DATA_SIZE * ImgCountObjects(lpImage); if ( _lwrite(ofp, LineBuffer[0], wBytes) != wBytes ) goto BadWrite; lpObject = NULL; i = 0; while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO)) { lpOffsets[i].lDataOffset = _llseek (ofp, 0L, 1); lpOffsets[i].lAlphaOffset = 0L; if (TiffWriteFrame(ofp, lpFileName, NULL, lpObject->Pixmap.EditFrame, NULL, flag, fCompressed, bEscapable) < 0) goto BadWrite; if (!lpObject->lpAlpha || (!i && !Save.bSaveMask)) { ++i; continue; } lpOffsets[i].lAlphaOffset = _llseek (ofp, 0L, 1); if (TiffWriteFrame(ofp, lpFileName, NULL, lpObject->lpAlpha->Pixmap.EditFrame, NULL, IDC_SAVECT, fCompressed, bEscapable) < 0) goto BadWrite; ++i; } // fill in object data information and write it _llseek (ofp, lObjStart, 0); lpObject = NULL; i = 0; while (lpObject = ImgGetNextObject(lpImage, lpObject, YES, NO)) { shtptr = (LPWORD)LineBuffer[0]; SetNextWord(&shtptr, lpObject->ObjectType); SetNextWord(&shtptr, lpObject->rObject.left); SetNextWord(&shtptr, lpObject->rObject.top); SetNextWord(&shtptr, lpObject->rObject.right); SetNextWord(&shtptr, lpObject->rObject.bottom); SetNextWord(&shtptr, lpObject->Opacity); SetNextWord(&shtptr, lpObject->MergeMode); SetNextWord(&shtptr, lpObject->wGroupID); SetNextWord(&shtptr, idFileType); if (lpObject->lpAlpha) { SetNextWord(&shtptr, lpObject->lpAlpha->bInvert); SetNextWord(&shtptr, lpObject->lpAlpha->rMask.left); SetNextWord(&shtptr, lpObject->lpAlpha->rMask.top); SetNextWord(&shtptr, lpObject->lpAlpha->rMask.right); SetNextWord(&shtptr, lpObject->lpAlpha->rMask.bottom); } else { SetNextWord(&shtptr, 0); SetNextWord(&shtptr, 0); SetNextWord(&shtptr, 0); SetNextWord(&shtptr, 0); SetNextWord(&shtptr, 0); } lngptr = (LPLONG)shtptr; SetNextLong(&lngptr, lpOffsets[i].lDataOffset); SetNextLong(&lngptr, lpOffsets[i].lAlphaOffset); shtptr = (LPWORD)lngptr; SetNextWord(&shtptr, lpObject->fSelected); SetNextWord(&shtptr, lpObject->ObjectDataID); lngptr = (LPLONG)shtptr; SetNextLong(&lngptr, lpObject->dwObjectData); shtptr = (LPWORD)lngptr; ++i; // Write out Object data wBytes = OBJ_DATA_SIZE;; if ( _lwrite(ofp, LineBuffer[0], wBytes) != wBytes ) goto BadWrite; } FreeUp( (LPTR)lpOffsets ); _lclose(ofp); ProgressEnd(); return( 0 ); BadWrite: _lclose(ofp); FreeUp( (LPTR)lpOffsets ); lstrcpy(temp,lpFileName); FileDelete(temp); if (nPasses) ProgressEnd(); return( -1 ); }