decorate.c revision 564a56979706a30a3d0f920fd5f538a408efd4f1
1/* 2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3% % 4% % 5% % 6% DDDD EEEEE CCCC OOO RRRR AAA TTTTT EEEEE % 7% D D E C O O R R A A T E % 8% D D EEE C O O RRRR AAAAA T EEE % 9% D D E C O O R R A A T E % 10% DDDD EEEEE CCCC OOO R R A A T EEEEE % 11% % 12% % 13% MagickCore Image Decoration Methods % 14% % 15% Software Design % 16% John Cristy % 17% July 1992 % 18% % 19% % 20% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization % 21% dedicated to making software imaging solutions freely available. % 22% % 23% You may not use this file except in compliance with the License. You may % 24% obtain a copy of the License at % 25% % 26% http://www.imagemagick.org/script/license.php % 27% % 28% Unless required by applicable law or agreed to in writing, software % 29% distributed under the License is distributed on an "AS IS" BASIS, % 30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 31% See the License for the specific language governing permissions and % 32% limitations under the License. % 33% % 34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35% 36% 37% 38*/ 39 40/* 41 Include declarations. 42*/ 43#include "MagickCore/studio.h" 44#include "MagickCore/cache-view.h" 45#include "MagickCore/color-private.h" 46#include "MagickCore/colorspace-private.h" 47#include "MagickCore/composite.h" 48#include "MagickCore/decorate.h" 49#include "MagickCore/exception.h" 50#include "MagickCore/exception-private.h" 51#include "MagickCore/image.h" 52#include "MagickCore/memory_.h" 53#include "MagickCore/monitor.h" 54#include "MagickCore/monitor-private.h" 55#include "MagickCore/pixel-accessor.h" 56#include "MagickCore/quantum.h" 57#include "MagickCore/quantum-private.h" 58#include "MagickCore/thread-private.h" 59#include "MagickCore/transform.h" 60 61/* 62 Define declarations. 63*/ 64#define AccentuateModulate ScaleCharToQuantum(80) 65#define HighlightModulate ScaleCharToQuantum(125) 66#define ShadowModulate ScaleCharToQuantum(135) 67#define DepthModulate ScaleCharToQuantum(185) 68#define TroughModulate ScaleCharToQuantum(110) 69 70/* 71%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 72% % 73% % 74% % 75% B o r d e r I m a g e % 76% % 77% % 78% % 79%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 80% 81% BorderImage() surrounds the image with a border of the color defined by 82% the bordercolor member of the image structure. The width and height 83% of the border are defined by the corresponding members of the border_info 84% structure. 85% 86% The format of the BorderImage method is: 87% 88% Image *BorderImage(const Image *image,const RectangleInfo *border_info, 89% const CompositeOperator compose,ExceptionInfo *exception) 90% 91% A description of each parameter follows: 92% 93% o image: the image. 94% 95% o border_info: define the width and height of the border. 96% 97% o compose: the composite operator. 98% 99% o exception: return any errors or warnings in this structure. 100% 101*/ 102MagickExport Image *BorderImage(const Image *image, 103 const RectangleInfo *border_info,const CompositeOperator compose, 104 ExceptionInfo *exception) 105{ 106 Image 107 *border_image, 108 *clone_image; 109 110 FrameInfo 111 frame_info; 112 113 assert(image != (const Image *) NULL); 114 assert(image->signature == MagickSignature); 115 if (image->debug != MagickFalse) 116 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 117 assert(border_info != (RectangleInfo *) NULL); 118 frame_info.width=image->columns+(border_info->width << 1); 119 frame_info.height=image->rows+(border_info->height << 1); 120 frame_info.x=(ssize_t) border_info->width; 121 frame_info.y=(ssize_t) border_info->height; 122 frame_info.inner_bevel=0; 123 frame_info.outer_bevel=0; 124 clone_image=CloneImage(image,0,0,MagickTrue,exception); 125 if (clone_image == (Image *) NULL) 126 return((Image *) NULL); 127 clone_image->matte_color=image->border_color; 128 border_image=FrameImage(clone_image,&frame_info,compose,exception); 129 clone_image=DestroyImage(clone_image); 130 if (border_image != (Image *) NULL) 131 border_image->matte_color=image->matte_color; 132 return(border_image); 133} 134 135/* 136%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 137% % 138% % 139% % 140% F r a m e I m a g e % 141% % 142% % 143% % 144%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 145% 146% FrameImage() adds a simulated three-dimensional border around the image. 147% The color of the border is defined by the matte_color member of image. 148% Members width and height of frame_info specify the border width of the 149% vertical and horizontal sides of the frame. Members inner and outer 150% indicate the width of the inner and outer shadows of the frame. 151% 152% The format of the FrameImage method is: 153% 154% Image *FrameImage(const Image *image,const FrameInfo *frame_info, 155% const CompositeOperator compose,ExceptionInfo *exception) 156% 157% A description of each parameter follows: 158% 159% o image: the image. 160% 161% o frame_info: Define the width and height of the frame and its bevels. 162% 163% o compose: the composite operator. 164% 165% o exception: return any errors or warnings in this structure. 166% 167*/ 168MagickExport Image *FrameImage(const Image *image,const FrameInfo *frame_info, 169 const CompositeOperator compose,ExceptionInfo *exception) 170{ 171#define FrameImageTag "Frame/Image" 172 173 CacheView 174 *image_view, 175 *frame_view; 176 177 Image 178 *frame_image; 179 180 MagickBooleanType 181 status; 182 183 MagickOffsetType 184 progress; 185 186 PixelInfo 187 accentuate, 188 highlight, 189 interior, 190 matte, 191 shadow, 192 trough; 193 194 register ssize_t 195 x; 196 197 size_t 198 bevel_width, 199 height, 200 width; 201 202 ssize_t 203 y; 204 205 /* 206 Check frame geometry. 207 */ 208 assert(image != (Image *) NULL); 209 assert(image->signature == MagickSignature); 210 if (image->debug != MagickFalse) 211 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 212 assert(frame_info != (FrameInfo *) NULL); 213 if ((frame_info->outer_bevel < 0) || (frame_info->inner_bevel < 0)) 214 ThrowImageException(OptionError,"FrameIsLessThanImageSize"); 215 bevel_width=(size_t) (frame_info->outer_bevel+frame_info->inner_bevel); 216 width=frame_info->width-frame_info->x-bevel_width; 217 height=frame_info->height-frame_info->y-bevel_width; 218 if ((width < image->columns) || (height < image->rows)) 219 ThrowImageException(OptionError,"FrameIsLessThanImageSize"); 220 /* 221 Initialize framed image attributes. 222 */ 223 frame_image=CloneImage(image,frame_info->width,frame_info->height,MagickTrue, 224 exception); 225 if (frame_image == (Image *) NULL) 226 return((Image *) NULL); 227 if (SetImageStorageClass(frame_image,DirectClass,exception) == MagickFalse) 228 { 229 frame_image=DestroyImage(frame_image); 230 return((Image *) NULL); 231 } 232 if (frame_image->matte_color.alpha != OpaqueAlpha) 233 frame_image->matte=MagickTrue; 234 frame_image->page=image->page; 235 if ((image->page.width != 0) && (image->page.height != 0)) 236 { 237 frame_image->page.width+=frame_image->columns-image->columns; 238 frame_image->page.height+=frame_image->rows-image->rows; 239 } 240 /* 241 Initialize 3D effects color. 242 */ 243 interior=image->border_color; 244 matte=image->matte_color; 245 accentuate=matte; 246 accentuate.red=(MagickRealType) (QuantumScale*((QuantumRange- 247 AccentuateModulate)*matte.red+(QuantumRange*AccentuateModulate))); 248 accentuate.green=(MagickRealType) (QuantumScale*((QuantumRange- 249 AccentuateModulate)*matte.green+(QuantumRange*AccentuateModulate))); 250 accentuate.blue=(MagickRealType) (QuantumScale*((QuantumRange- 251 AccentuateModulate)*matte.blue+(QuantumRange*AccentuateModulate))); 252 accentuate.black=(MagickRealType) (QuantumScale*((QuantumRange- 253 AccentuateModulate)*matte.black+(QuantumRange*AccentuateModulate))); 254 accentuate.alpha=matte.alpha; 255 highlight=matte; 256 highlight.red=(MagickRealType) (QuantumScale*((QuantumRange- 257 HighlightModulate)*matte.red+(QuantumRange*HighlightModulate))); 258 highlight.green=(MagickRealType) (QuantumScale*((QuantumRange- 259 HighlightModulate)*matte.green+(QuantumRange*HighlightModulate))); 260 highlight.blue=(MagickRealType) (QuantumScale*((QuantumRange- 261 HighlightModulate)*matte.blue+(QuantumRange*HighlightModulate))); 262 highlight.black=(MagickRealType) (QuantumScale*((QuantumRange- 263 HighlightModulate)*matte.black+(QuantumRange*HighlightModulate))); 264 highlight.alpha=matte.alpha; 265 shadow=matte; 266 shadow.red=QuantumScale*matte.red*ShadowModulate; 267 shadow.green=QuantumScale*matte.green*ShadowModulate; 268 shadow.blue=QuantumScale*matte.blue*ShadowModulate; 269 shadow.black=QuantumScale*matte.black*ShadowModulate; 270 shadow.alpha=matte.alpha; 271 trough=matte; 272 trough.red=QuantumScale*matte.red*TroughModulate; 273 trough.green=QuantumScale*matte.green*TroughModulate; 274 trough.blue=QuantumScale*matte.blue*TroughModulate; 275 trough.black=QuantumScale*matte.black*TroughModulate; 276 trough.alpha=matte.alpha; 277 status=MagickTrue; 278 progress=0; 279 image_view=AcquireCacheView(image); 280 frame_view=AcquireCacheView(frame_image); 281 height=(size_t) (frame_info->outer_bevel+(frame_info->y-bevel_width)+ 282 frame_info->inner_bevel); 283 if (height != 0) 284 { 285 register ssize_t 286 x; 287 288 register Quantum 289 *restrict q; 290 291 /* 292 Draw top of ornamental border. 293 */ 294 q=QueueCacheViewAuthenticPixels(frame_view,0,0,frame_image->columns, 295 height,exception); 296 if (q != (Quantum *) NULL) 297 { 298 /* 299 Draw top of ornamental border. 300 */ 301 for (y=0; y < (ssize_t) frame_info->outer_bevel; y++) 302 { 303 for (x=0; x < (ssize_t) (frame_image->columns-y); x++) 304 { 305 if (x < y) 306 SetPixelInfoPixel(frame_image,&highlight,q); 307 else 308 SetPixelInfoPixel(frame_image,&accentuate,q); 309 q+=GetPixelChannels(frame_image); 310 } 311 for ( ; x < (ssize_t) frame_image->columns; x++) 312 { 313 SetPixelInfoPixel(frame_image,&shadow,q); 314 q+=GetPixelChannels(frame_image); 315 } 316 } 317 for (y=0; y < (ssize_t) (frame_info->y-bevel_width); y++) 318 { 319 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) 320 { 321 SetPixelInfoPixel(frame_image,&highlight,q); 322 q+=GetPixelChannels(frame_image); 323 } 324 width=frame_image->columns-2*frame_info->outer_bevel; 325 for (x=0; x < (ssize_t) width; x++) 326 { 327 SetPixelInfoPixel(frame_image,&matte,q); 328 q+=GetPixelChannels(frame_image); 329 } 330 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) 331 { 332 SetPixelInfoPixel(frame_image,&shadow,q); 333 q+=GetPixelChannels(frame_image); 334 } 335 } 336 for (y=0; y < (ssize_t) frame_info->inner_bevel; y++) 337 { 338 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) 339 { 340 SetPixelInfoPixel(frame_image,&highlight,q); 341 q+=GetPixelChannels(frame_image); 342 } 343 for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++) 344 { 345 SetPixelInfoPixel(frame_image,&matte,q); 346 q+=GetPixelChannels(frame_image); 347 } 348 width=image->columns+((size_t) frame_info->inner_bevel << 1)- 349 y; 350 for (x=0; x < (ssize_t) width; x++) 351 { 352 if (x < y) 353 SetPixelInfoPixel(frame_image,&shadow,q); 354 else 355 SetPixelInfoPixel(frame_image,&trough,q); 356 q+=GetPixelChannels(frame_image); 357 } 358 for ( ; x < (ssize_t) (image->columns+2*frame_info->inner_bevel); x++) 359 { 360 SetPixelInfoPixel(frame_image,&highlight,q); 361 q+=GetPixelChannels(frame_image); 362 } 363 width=frame_info->width-frame_info->x-image->columns-bevel_width; 364 for (x=0; x < (ssize_t) width; x++) 365 { 366 SetPixelInfoPixel(frame_image,&matte,q); 367 q+=GetPixelChannels(frame_image); 368 } 369 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) 370 { 371 SetPixelInfoPixel(frame_image,&shadow,q); 372 q+=GetPixelChannels(frame_image); 373 } 374 } 375 (void) SyncCacheViewAuthenticPixels(frame_view,exception); 376 } 377 } 378 /* 379 Draw sides of ornamental border. 380 */ 381#if defined(MAGICKCORE_OPENMP_SUPPORT) 382 #pragma omp parallel for schedule(static,8) shared(progress,status) 383#endif 384 for (y=0; y < (ssize_t) image->rows; y++) 385 { 386 register ssize_t 387 x; 388 389 register Quantum 390 *restrict q; 391 392 size_t 393 width; 394 395 /* 396 Initialize scanline with matte color. 397 */ 398 if (status == MagickFalse) 399 continue; 400 q=QueueCacheViewAuthenticPixels(frame_view,0,frame_info->y+y, 401 frame_image->columns,1,exception); 402 if (q == (Quantum *) NULL) 403 { 404 status=MagickFalse; 405 continue; 406 } 407 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) 408 { 409 SetPixelInfoPixel(frame_image,&highlight,q); 410 q+=GetPixelChannels(frame_image); 411 } 412 for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++) 413 { 414 SetPixelInfoPixel(frame_image,&matte,q); 415 q+=GetPixelChannels(frame_image); 416 } 417 for (x=0; x < (ssize_t) frame_info->inner_bevel; x++) 418 { 419 SetPixelInfoPixel(frame_image,&shadow,q); 420 q+=GetPixelChannels(frame_image); 421 } 422 /* 423 Set frame interior to interior color. 424 */ 425 if ((compose != CopyCompositeOp) && ((compose != OverCompositeOp) || 426 (image->matte != MagickFalse))) 427 for (x=0; x < (ssize_t) image->columns; x++) 428 { 429 SetPixelInfoPixel(frame_image,&interior,q); 430 q+=GetPixelChannels(frame_image); 431 } 432 else 433 { 434 register const Quantum 435 *p; 436 437 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); 438 if (p == (const Quantum *) NULL) 439 { 440 status=MagickFalse; 441 continue; 442 } 443 for (x=0; x < (ssize_t) image->columns; x++) 444 { 445 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) 446 SetPixelRed(frame_image,GetPixelRed(image,p),q); 447 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) 448 SetPixelGreen(frame_image,GetPixelGreen(image,p),q); 449 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) 450 SetPixelBlue(frame_image,GetPixelBlue(image,p),q); 451 if ((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) 452 SetPixelBlack(frame_image,GetPixelBlack(image,p),q); 453 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) 454 SetPixelAlpha(frame_image,GetPixelAlpha(image,p),q); 455 p+=GetPixelChannels(image); 456 q+=GetPixelChannels(frame_image); 457 } 458 } 459 for (x=0; x < (ssize_t) frame_info->inner_bevel; x++) 460 { 461 SetPixelInfoPixel(frame_image,&highlight,q); 462 q+=GetPixelChannels(frame_image); 463 } 464 width=frame_info->width-frame_info->x-image->columns-bevel_width; 465 for (x=0; x < (ssize_t) width; x++) 466 { 467 SetPixelInfoPixel(frame_image,&matte,q); 468 q+=GetPixelChannels(frame_image); 469 } 470 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) 471 { 472 SetPixelInfoPixel(frame_image,&shadow,q); 473 q+=GetPixelChannels(frame_image); 474 } 475 if (SyncCacheViewAuthenticPixels(frame_view,exception) == MagickFalse) 476 status=MagickFalse; 477 if (image->progress_monitor != (MagickProgressMonitor) NULL) 478 { 479 MagickBooleanType 480 proceed; 481 482#if defined(MAGICKCORE_OPENMP_SUPPORT) 483 #pragma omp critical (MagickCore_FrameImage) 484#endif 485 proceed=SetImageProgress(image,FrameImageTag,progress++,image->rows); 486 if (proceed == MagickFalse) 487 status=MagickFalse; 488 } 489 } 490 height=(size_t) (frame_info->inner_bevel+frame_info->height- 491 frame_info->y-image->rows-bevel_width+frame_info->outer_bevel); 492 if (height != 0) 493 { 494 register ssize_t 495 x; 496 497 register Quantum 498 *restrict q; 499 500 /* 501 Draw bottom of ornamental border. 502 */ 503 q=QueueCacheViewAuthenticPixels(frame_view,0,(ssize_t) (frame_image->rows- 504 height),frame_image->columns,height,exception); 505 if (q != (Quantum *) NULL) 506 { 507 /* 508 Draw bottom of ornamental border. 509 */ 510 for (y=frame_info->inner_bevel-1; y >= 0; y--) 511 { 512 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) 513 { 514 SetPixelInfoPixel(frame_image,&highlight,q); 515 q+=GetPixelChannels(frame_image); 516 } 517 for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++) 518 { 519 SetPixelInfoPixel(frame_image,&matte,q); 520 q+=GetPixelChannels(frame_image); 521 } 522 for (x=0; x < y; x++) 523 { 524 SetPixelInfoPixel(frame_image,&shadow,q); 525 q+=GetPixelChannels(frame_image); 526 } 527 for ( ; x < (ssize_t) (image->columns+2*frame_info->inner_bevel); x++) 528 { 529 if (x >= (ssize_t) (image->columns+2*frame_info->inner_bevel-y)) 530 SetPixelInfoPixel(frame_image,&highlight,q); 531 else 532 SetPixelInfoPixel(frame_image,&accentuate,q); 533 q+=GetPixelChannels(frame_image); 534 } 535 width=frame_info->width-frame_info->x-image->columns-bevel_width; 536 for (x=0; x < (ssize_t) width; x++) 537 { 538 SetPixelInfoPixel(frame_image,&matte,q); 539 q+=GetPixelChannels(frame_image); 540 } 541 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) 542 { 543 SetPixelInfoPixel(frame_image,&shadow,q); 544 q+=GetPixelChannels(frame_image); 545 } 546 } 547 height=frame_info->height-frame_info->y-image->rows-bevel_width; 548 for (y=0; y < (ssize_t) height; y++) 549 { 550 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) 551 { 552 SetPixelInfoPixel(frame_image,&highlight,q); 553 q+=GetPixelChannels(frame_image); 554 } 555 width=frame_image->columns-2*frame_info->outer_bevel; 556 for (x=0; x < (ssize_t) width; x++) 557 { 558 SetPixelInfoPixel(frame_image,&matte,q); 559 q+=GetPixelChannels(frame_image); 560 } 561 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) 562 { 563 SetPixelInfoPixel(frame_image,&shadow,q); 564 q+=GetPixelChannels(frame_image); 565 } 566 } 567 for (y=frame_info->outer_bevel-1; y >= 0; y--) 568 { 569 for (x=0; x < y; x++) 570 { 571 SetPixelInfoPixel(frame_image,&highlight,q); 572 q+=GetPixelChannels(frame_image); 573 } 574 for ( ; x < (ssize_t) frame_image->columns; x++) 575 { 576 if (x >= (ssize_t) (frame_image->columns-y)) 577 SetPixelInfoPixel(frame_image,&shadow,q); 578 else 579 SetPixelInfoPixel(frame_image,&trough,q); 580 q+=GetPixelChannels(frame_image); 581 } 582 } 583 (void) SyncCacheViewAuthenticPixels(frame_view,exception); 584 } 585 } 586 frame_view=DestroyCacheView(frame_view); 587 image_view=DestroyCacheView(image_view); 588 if ((compose != CopyCompositeOp) && ((compose != OverCompositeOp) || 589 (image->matte != MagickFalse))) 590 { 591 x=(ssize_t) (frame_info->outer_bevel+(frame_info->x-bevel_width)+ 592 frame_info->inner_bevel); 593 y=(ssize_t) (frame_info->outer_bevel+(frame_info->y-bevel_width)+ 594 frame_info->inner_bevel); 595 (void) CompositeImage(frame_image,compose,image,x,y,exception); 596 } 597 return(frame_image); 598} 599 600/* 601%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 602% % 603% % 604% % 605% R a i s e I m a g e % 606% % 607% % 608% % 609%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 610% 611% RaiseImage() creates a simulated three-dimensional button-like effect 612% by lightening and darkening the edges of the image. Members width and 613% height of raise_info define the width of the vertical and horizontal 614% edge of the effect. 615% 616% The format of the RaiseImage method is: 617% 618% MagickBooleanType RaiseImage(const Image *image, 619% const RectangleInfo *raise_info,const MagickBooleanType raise, 620% ExceptionInfo *exception) 621% 622% A description of each parameter follows: 623% 624% o image: the image. 625% 626% o raise_info: Define the width and height of the raise area. 627% 628% o raise: A value other than zero creates a 3-D raise effect, 629% otherwise it has a lowered effect. 630% 631% o exception: return any errors or warnings in this structure. 632% 633*/ 634MagickExport MagickBooleanType RaiseImage(Image *image, 635 const RectangleInfo *raise_info,const MagickBooleanType raise, 636 ExceptionInfo *exception) 637{ 638#define AccentuateFactor ScaleCharToQuantum(135) 639#define HighlightFactor ScaleCharToQuantum(190) 640#define ShadowFactor ScaleCharToQuantum(190) 641#define RaiseImageTag "Raise/Image" 642#define TroughFactor ScaleCharToQuantum(135) 643 644 CacheView 645 *image_view; 646 647 MagickBooleanType 648 status; 649 650 MagickOffsetType 651 progress; 652 653 Quantum 654 foreground, 655 background; 656 657 ssize_t 658 y; 659 660 assert(image != (Image *) NULL); 661 assert(image->signature == MagickSignature); 662 if (image->debug != MagickFalse) 663 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 664 assert(raise_info != (RectangleInfo *) NULL); 665 if ((image->columns <= (raise_info->width << 1)) || 666 (image->rows <= (raise_info->height << 1))) 667 ThrowBinaryException(OptionError,"ImageSizeMustExceedBevelWidth", 668 image->filename); 669 foreground=(Quantum) QuantumRange; 670 background=(Quantum) 0; 671 if (raise == MagickFalse) 672 { 673 foreground=(Quantum) 0; 674 background=(Quantum) QuantumRange; 675 } 676 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 677 return(MagickFalse); 678 /* 679 Raise image. 680 */ 681 status=MagickTrue; 682 progress=0; 683 image_view=AcquireCacheView(image); 684#if defined(MAGICKCORE_OPENMP_SUPPORT) 685 #pragma omp parallel for schedule(static,1) shared(progress,status) 686#endif 687 for (y=0; y < (ssize_t) raise_info->height; y++) 688 { 689 register ssize_t 690 i, 691 x; 692 693 register Quantum 694 *restrict q; 695 696 if (status == MagickFalse) 697 continue; 698 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); 699 if (q == (Quantum *) NULL) 700 { 701 status=MagickFalse; 702 continue; 703 } 704 for (x=0; x < y; x++) 705 { 706 for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 707 { 708 PixelChannel 709 channel; 710 711 PixelTrait 712 traits; 713 714 channel=GetPixelChannelMapChannel(image,i); 715 traits=GetPixelChannelMapTraits(image,channel); 716 if ((traits & UpdatePixelTrait) != 0) 717 q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]* 718 HighlightFactor+(MagickRealType) foreground*(QuantumRange- 719 HighlightFactor))); 720 } 721 q+=GetPixelChannels(image); 722 } 723 for ( ; x < (ssize_t) (image->columns-y); x++) 724 { 725 for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 726 { 727 PixelChannel 728 channel; 729 730 PixelTrait 731 traits; 732 733 channel=GetPixelChannelMapChannel(image,i); 734 traits=GetPixelChannelMapTraits(image,channel); 735 if ((traits & UpdatePixelTrait) != 0) 736 q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]* 737 AccentuateFactor+(MagickRealType) foreground*(QuantumRange- 738 AccentuateFactor))); 739 } 740 q+=GetPixelChannels(image); 741 } 742 for ( ; x < (ssize_t) image->columns; x++) 743 { 744 for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 745 { 746 PixelChannel 747 channel; 748 749 PixelTrait 750 traits; 751 752 channel=GetPixelChannelMapChannel(image,i); 753 traits=GetPixelChannelMapTraits(image,channel); 754 if ((traits & UpdatePixelTrait) != 0) 755 q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]* 756 ShadowFactor+(MagickRealType) background*(QuantumRange- 757 ShadowFactor))); 758 } 759 q+=GetPixelChannels(image); 760 } 761 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) 762 status=MagickFalse; 763 if (image->progress_monitor != (MagickProgressMonitor) NULL) 764 { 765 MagickBooleanType 766 proceed; 767 768 proceed=SetImageProgress(image,RaiseImageTag,progress++,image->rows); 769 if (proceed == MagickFalse) 770 status=MagickFalse; 771 } 772 } 773#if defined(MAGICKCORE_OPENMP_SUPPORT) 774 #pragma omp parallel for schedule(static,1) shared(progress,status) 775#endif 776 for (y=(ssize_t) raise_info->height; y < (ssize_t) (image->rows-raise_info->height); y++) 777 { 778 register ssize_t 779 i, 780 x; 781 782 register Quantum 783 *restrict q; 784 785 if (status == MagickFalse) 786 continue; 787 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); 788 if (q == (Quantum *) NULL) 789 { 790 status=MagickFalse; 791 continue; 792 } 793 for (x=0; x < (ssize_t) raise_info->width; x++) 794 { 795 for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 796 { 797 PixelChannel 798 channel; 799 800 PixelTrait 801 traits; 802 803 channel=GetPixelChannelMapChannel(image,i); 804 traits=GetPixelChannelMapTraits(image,channel); 805 if ((traits & UpdatePixelTrait) != 0) 806 q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]* 807 HighlightFactor+(MagickRealType) foreground*(QuantumRange- 808 HighlightFactor))); 809 } 810 q+=GetPixelChannels(image); 811 } 812 for ( ; x < (ssize_t) (image->columns-raise_info->width); x++) 813 q+=GetPixelChannels(image); 814 for ( ; x < (ssize_t) image->columns; x++) 815 { 816 for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 817 { 818 PixelChannel 819 channel; 820 821 PixelTrait 822 traits; 823 824 channel=GetPixelChannelMapChannel(image,i); 825 traits=GetPixelChannelMapTraits(image,channel); 826 if ((traits & UpdatePixelTrait) != 0) 827 q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]* 828 ShadowFactor+(MagickRealType) background*(QuantumRange- 829 ShadowFactor))); 830 } 831 q+=GetPixelChannels(image); 832 } 833 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) 834 status=MagickFalse; 835 if (image->progress_monitor != (MagickProgressMonitor) NULL) 836 { 837 MagickBooleanType 838 proceed; 839 840 proceed=SetImageProgress(image,RaiseImageTag,progress++,image->rows); 841 if (proceed == MagickFalse) 842 status=MagickFalse; 843 } 844 } 845#if defined(MAGICKCORE_OPENMP_SUPPORT) 846 #pragma omp parallel for schedule(static,1) shared(progress,status) 847#endif 848 for (y=(ssize_t) (image->rows-raise_info->height); y < (ssize_t) image->rows; y++) 849 { 850 register ssize_t 851 i, 852 x; 853 854 register Quantum 855 *restrict q; 856 857 if (status == MagickFalse) 858 continue; 859 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); 860 if (q == (Quantum *) NULL) 861 { 862 status=MagickFalse; 863 continue; 864 } 865 for (x=0; x < (ssize_t) (image->rows-y); x++) 866 { 867 for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 868 { 869 PixelChannel 870 channel; 871 872 PixelTrait 873 traits; 874 875 channel=GetPixelChannelMapChannel(image,i); 876 traits=GetPixelChannelMapTraits(image,channel); 877 if ((traits & UpdatePixelTrait) != 0) 878 q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]* 879 HighlightFactor+(MagickRealType) foreground*(QuantumRange- 880 HighlightFactor))); 881 } 882 q+=GetPixelChannels(image); 883 } 884 for ( ; x < (ssize_t) (image->columns-(image->rows-y)); x++) 885 { 886 for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 887 { 888 PixelChannel 889 channel; 890 891 PixelTrait 892 traits; 893 894 channel=GetPixelChannelMapChannel(image,i); 895 traits=GetPixelChannelMapTraits(image,channel); 896 if ((traits & UpdatePixelTrait) != 0) 897 q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]* 898 TroughFactor+(MagickRealType) background*(QuantumRange- 899 TroughFactor))); 900 } 901 q+=GetPixelChannels(image); 902 } 903 for ( ; x < (ssize_t) image->columns; x++) 904 { 905 for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 906 { 907 PixelChannel 908 channel; 909 910 PixelTrait 911 traits; 912 913 channel=GetPixelChannelMapChannel(image,i); 914 traits=GetPixelChannelMapTraits(image,channel); 915 if ((traits & UpdatePixelTrait) != 0) 916 q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]* 917 ShadowFactor+(MagickRealType) background*(QuantumRange- 918 ShadowFactor))); 919 } 920 q+=GetPixelChannels(image); 921 } 922 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) 923 status=MagickFalse; 924 if (image->progress_monitor != (MagickProgressMonitor) NULL) 925 { 926 MagickBooleanType 927 proceed; 928 929#if defined(MAGICKCORE_OPENMP_SUPPORT) 930 #pragma omp critical (MagickCore_RaiseImage) 931#endif 932 proceed=SetImageProgress(image,RaiseImageTag,progress++,image->rows); 933 if (proceed == MagickFalse) 934 status=MagickFalse; 935 } 936 } 937 image_view=DestroyCacheView(image_view); 938 return(status); 939} 940