//------------------------------------------------------------------------------- // // SetupFilterRecordForProxy // // Called by the UI routine to set up the gFilterRecord with the proxy view // information. CalcProxyScaleFactor sizes the proxy rectangle and calculates the // scale factor. Then set up gFilterRecord and call advanceState() to init the // inData with the pixel data for the display. // // Global Inputs and Outputs: // FilterRecord *gFilterRecord inRect, inRowBytes, maskRect, etc. has all // the information needed to call // advanceState so inData points to the proxy // pixel data and maskRect points to the // selection data // //------------------------------------------------------------------------------- void SetupFilterRecordForProxy(void) { CalcProxyScaleFactor(); SetInRect(GetFilterRect()); // gFilterRecord->inRect = gFilterRecord->filterRect; VRect tempRect = GetInRect(); ScaleRect(tempRect, 1, (int16)gData->scaleFactor); SetInRect(tempRect); SetMaskRect(GetInRect()); // gFilterRecord->maskRect = gFilterRecord->inRect; // Fixed numbers are 16.16 values // the first 16 bits represent the whole number // the last 16 bits represent the fraction gFilterRecord->inputRate = (int32)gData->scaleFactor << 16; gFilterRecord->maskRate = (int32)gData->scaleFactor << 16; gFilterRecord->inputPadding = 255; gFilterRecord->maskPadding = gFilterRecord->inputPadding; gData->proxyWidth = gData->proxyRect.right - gData->proxyRect.left; gData->proxyHeight = gData->proxyRect.bottom - gData->proxyRect.top; gData->proxyPlaneSize = gData->proxyWidth * gData->proxyHeight; }
//------------------------------------------------------------------------------- // // DoContinue // // If we get here we probably did something wrong. This selector was needed // before advanceState() was in the FilterRecord*. Now that we use advanceState() // there is nothing for us to do but set all the rectangles to 0 and return. // //------------------------------------------------------------------------------- void DoContinue(void) { VRect zeroRect = { 0, 0, 0, 0 }; SetInRect(zeroRect); SetOutRect(zeroRect); SetMaskRect(zeroRect); }
static int16 RunPlugin(const int16 iSelector) { string sError; try { if(gFilterRecord->bigDocumentData != NULL) gFilterRecord->bigDocumentData->PluginUsing32BitCoordinates = true; switch(iSelector) { case filterSelectorParameters: break; case filterSelectorPrepare: break; case filterSelectorStart: { Run(); printf("UI shutdown\n"); break; } case filterSelectorContinue: { VRect zeroRect = { 0, 0, 0, 0 }; SetInRect(gFilterRecord, zeroRect); SetOutRect(gFilterRecord, zeroRect); SetMaskRect(gFilterRecord, zeroRect); break; } case filterSelectorFinish: break; } } catch(const std::bad_alloc &) { return memFullErr; } catch(const PhotoshopErrorException &e) { return e.m_iErr; } catch(const exception &e) { /* Don't let any exceptions propagate back into Photoshop. */ sError = e.what(); } catch(...) { sError = "Unknown exception"; } if(sError.empty()) return noErr; PlatformData *pPlatform = (PlatformData *) gFilterRecord->platformData; HWND hWnd = (HWND) pPlatform->hwnd; MessageBox(hWnd, sError.c_str(), plugInName, MB_OK); /* Is it OK to return userCanceledErr for a non-cancellation error? The only * difference seems to be that this doesn't display a "couldn't be completed because * of a program error" dialog, which is what we want since we already displayed * the error. */ return userCanceledErr; }
//------------------------------------------------------------------------------- // // DoFilter // // Randomly change the pixel values based on the parameters the user gave us from // our dialog box or scripting. We do this a tile at a time making sure the rect. // we ask for is in the bounds of the filterRect. // //------------------------------------------------------------------------------- void DoFilter(void) { // make the random number generated trully random srand((unsigned)time(NULL)); int32 tileHeight = gFilterRecord->outTileHeight; int32 tileWidth = gFilterRecord->outTileWidth; if (tileWidth == 0 || tileHeight == 0) { *gResult = filterBadParameters; return; } VRect filterRect = GetFilterRect(); int32 rectWidth = filterRect.right - filterRect.left; int32 rectHeight = filterRect.bottom - filterRect.top; CreateDissolveBuffer(tileWidth, tileHeight); // round up to the nearest horizontal and vertical tile count int32 tilesVert = (tileHeight - 1 + rectHeight) / tileHeight; int32 tilesHoriz = (tileWidth - 1 + rectWidth) / tileWidth; // Fixed numbers are 16.16 values // the first 16 bits represent the whole number // the last 16 bits represent the fraction gFilterRecord->inputRate = (int32)1 << 16; gFilterRecord->maskRate = (int32)1 << 16; // variables for the progress bar, our plug in is so fast // we probably don't need these int32 progressTotal = tilesVert * tilesHoriz; int32 progressDone = 0; // loop through each tile makeing sure we don't go over the bounds // of the rectHeight or rectWidth for (int32 vertTile = 0; vertTile < tilesVert; vertTile++) { for (int32 horizTile = 0; horizTile < tilesHoriz; horizTile++) { UpdateDissolveBuffer(tileWidth, tileHeight); VRect filterRect = GetFilterRect(); VRect inRect = GetInRect(); inRect.top = vertTile * tileHeight + filterRect.top; inRect.left = horizTile * tileWidth + filterRect.left; inRect.bottom = inRect.top + tileHeight; inRect.right = inRect.left + tileWidth; if (inRect.bottom > rectHeight) inRect.bottom = rectHeight; if (inRect.right > rectWidth) inRect.right = rectWidth; SetInRect(inRect); // duplicate what's in the inData with the outData SetOutRect(inRect); // get the maskRect if the user has given us a selection if (gFilterRecord->haveMask) { SetMaskRect(inRect); } for (int16 plane = 0; plane < gFilterRecord->planes; plane++) { // we want one plane at a time, small memory foot print is good gFilterRecord->outLoPlane = gFilterRecord->inLoPlane = plane; gFilterRecord->outHiPlane = gFilterRecord->inHiPlane = plane; // update the gFilterRecord with our latest request *gResult = gFilterRecord->advanceState(); if (*gResult != noErr) return; // muck with the pixels in the outData buffer uint8 color = 255; int16 expectedPlanes = CSPlanesFromMode(gFilterRecord->imageMode, 0); if (plane < expectedPlanes) color = gData->color[plane]; DissolveRectangle(gFilterRecord->outData, gFilterRecord->outRowBytes, gFilterRecord->maskData, gFilterRecord->maskRowBytes, GetOutRect(), color, gFilterRecord->depth); } // uh, update the progress bar gFilterRecord->progressProc(++progressDone, progressTotal); // see if the user is impatient or didn't mean to do that if (gFilterRecord->abortProc()) { *gResult = userCanceledErr; return; } } } DeleteDissolveBuffer(); }