~ubuntu-branches/ubuntu/trusty/graphicsmagick/trusty-proposed

« back to all changes in this revision

Viewing changes to magick/shear.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2009-05-07 20:09:28 UTC
  • mfrom: (5.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090507200928-5rb3jyvrsi9x3zfl
Tags: 1.3.5-5
* debian/control: Update Conflicts/Replaces of -dev-compat package to
  follow libmagick-dev package split. Closes: #526482
* magick/GraphicsMagick-config.{in,1}: Do not expose compiler options
  used to build the library itself via GraphicsMagick-config. Only
  provide options that are actually useful to depending applications.
  Adjust documentation accordingly. Closes: #523596

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
% Copyright (C) 2003 GraphicsMagick Group
 
2
% Copyright (C) 2003, 2007 GraphicsMagick Group
3
3
% Copyright (C) 2002 ImageMagick Studio
4
4
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
5
5
%
42
42
  Include declarations.
43
43
*/
44
44
#include "magick/studio.h"
45
 
#include "magick/cache.h"
 
45
#include "magick/alpha_composite.h"
 
46
#include "magick/color.h"
46
47
#include "magick/decorate.h"
47
48
#include "magick/monitor.h"
 
49
#include "magick/pixel_cache.h"
48
50
#include "magick/render.h"
49
51
#include "magick/shear.h"
50
52
#include "magick/transform.h"
143
145
    (unsigned long) ceil(max.y-min.y-0.5),True,exception);
144
146
  if (affine_image == (Image *) NULL)
145
147
    return((Image *) NULL);
146
 
  SetImage(affine_image,TransparentOpacity);
 
148
  (void) SetImage(affine_image,TransparentOpacity);
147
149
  transform.sx=affine->sx;
148
150
  transform.rx=affine->rx;
149
151
  transform.ry=affine->ry;
150
152
  transform.sy=affine->sy;
151
153
  transform.tx=(-min.x);
152
154
  transform.ty=(-min.y);
153
 
  DrawAffineImage(affine_image,image,&transform);
 
155
  (void) DrawAffineImage(affine_image,image,&transform);
154
156
  return(affine_image);
155
157
}
156
158
 
280
282
%
281
283
*/
282
284
static Image *IntegralRotateImage(const Image *image,unsigned int rotations,
283
 
  ExceptionInfo *exception)
 
285
                                  ExceptionInfo *exception)
284
286
{
285
 
#define RotateImageText  "  Rotate image...  "
 
287
  char
 
288
    message[MaxTextExtent];
286
289
 
287
290
  Image
288
291
    *rotate_image;
289
292
 
290
 
  long
291
 
    y;
292
 
 
293
293
  RectangleInfo
294
294
    page;
295
295
 
296
 
  register const IndexPacket
297
 
    *indexes;
298
 
 
299
 
  IndexPacket
300
 
    *rotate_indexes;
301
 
 
302
 
  register const PixelPacket
303
 
    *p;
304
 
 
305
 
  register long
306
 
    x;
307
 
 
308
 
  register PixelPacket
309
 
    *q;
310
 
 
311
 
  const PixelPacket
312
 
    *tile_pixels;
313
 
              
314
 
  register IndexPacket
315
 
    *iq;
316
 
  
317
 
  register const IndexPacket
318
 
    *ip;
319
 
                          
320
 
  unsigned long
 
296
  long
321
297
    tile_width_max=128,
322
298
    tile_height_max=128;
323
 
  
324
 
  long
325
 
    tile_width,
326
 
    tile_height;
327
 
  
328
 
  long
329
 
    tile_x,
330
 
    tile_y;
331
299
 
332
300
  MagickPassFail
333
 
    status;
 
301
    status=MagickPass;
334
302
 
335
303
  /*
336
304
    Initialize rotated image attributes.
355
323
              width,
356
324
              height;
357
325
            
358
 
            if (GetMagickDimension(value,&width,&height) == 2)
 
326
            if (GetMagickDimension(value,&width,&height,NULL,NULL) == 2)
359
327
              {
360
328
                tile_height_max=(unsigned long) height;
361
329
                tile_width_max=(unsigned long) width;
379
347
        /*
380
348
          Rotate 0 degrees.
381
349
        */
 
350
        long
 
351
          y;
 
352
 
 
353
        unsigned long
 
354
          row_count=0;
 
355
 
 
356
        (void) strlcpy(message,"[%s] Rotate image 0 degrees...",sizeof(message));
 
357
#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
 
358
#  pragma omp parallel for schedule(static,8) shared(row_count, status)
 
359
#endif
382
360
        for (y=0; y < (long) image->rows; y++)
383
361
          {
 
362
            register const PixelPacket
 
363
              *p;
 
364
            
 
365
            register PixelPacket
 
366
              *q;
 
367
            
 
368
            register const IndexPacket
 
369
              *indexes;
 
370
            
 
371
            IndexPacket
 
372
              *rotate_indexes;
 
373
 
 
374
            MagickPassFail
 
375
              thread_status;
 
376
 
 
377
            thread_status=status;
 
378
            if (thread_status == MagickFail)
 
379
              continue;
 
380
 
384
381
            p=AcquireImagePixels(image,0,y,image->columns,1,exception);
385
 
            q=SetImagePixels(rotate_image,0,y,rotate_image->columns,1);
 
382
            q=SetImagePixelsEx(rotate_image,0,y,rotate_image->columns,1,exception);
386
383
            if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
387
 
              break;
388
 
            (void) memcpy(q,p,image->columns*sizeof(PixelPacket));
389
 
            indexes=GetIndexes(image);
390
 
            rotate_indexes=GetIndexes(rotate_image);
391
 
            if ((indexes != (IndexPacket *) NULL) &&
392
 
                (rotate_indexes != (IndexPacket *) NULL))
393
 
              (void) memcpy(rotate_indexes,indexes,image->columns*
394
 
                            sizeof(IndexPacket));
395
 
            if (!SyncImagePixels(rotate_image))
396
 
              break;
397
 
            if (QuantumTick(y,image->rows))
398
 
              if (!MagickMonitor(RotateImageText,y,image->rows,exception))
399
 
                break;
 
384
              thread_status=MagickFail;
 
385
            if (thread_status != MagickFail)
 
386
              {
 
387
                (void) memcpy(q,p,image->columns*sizeof(PixelPacket));
 
388
                indexes=AccessImmutableIndexes(image);
 
389
                rotate_indexes=AccessMutableIndexes(rotate_image);
 
390
                if ((indexes != (IndexPacket *) NULL) &&
 
391
                    (rotate_indexes != (IndexPacket *) NULL))
 
392
                  (void) memcpy(rotate_indexes,indexes,image->columns*
 
393
                                sizeof(IndexPacket));
 
394
 
 
395
                if (!SyncImagePixelsEx(rotate_image,exception))
 
396
                  thread_status=MagickFail;
 
397
              }
 
398
#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
 
399
#  pragma omp critical
 
400
#endif
 
401
            {
 
402
              row_count++;
 
403
              if (QuantumTick(row_count,image->rows))
 
404
                if (!MagickMonitorFormatted(row_count,image->rows,exception,
 
405
                                            message,image->filename))
 
406
                  thread_status=MagickFail;
 
407
                  
 
408
              if (thread_status == MagickFail)
 
409
                status=MagickFail;
 
410
            }
400
411
          }
401
412
        break;
402
413
      }
405
416
        /*
406
417
          Rotate 90 degrees.
407
418
        */
408
 
        status=MagickPass;
 
419
        magick_int64_t
 
420
          tile;
 
421
 
 
422
        magick_uint64_t
 
423
          total_tiles;
 
424
 
 
425
        long
 
426
          tile_y;
 
427
 
 
428
        (void) strlcpy(message,"[%s] Rotate image 90 degrees...",sizeof(message));
 
429
        total_tiles=(((image->rows/tile_height_max)+1)*
 
430
                     ((image->columns/tile_width_max)+1));        
 
431
        tile=0;
 
432
#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
 
433
#  pragma omp parallel for schedule(static,1) shared(status, tile)
 
434
#endif
409
435
        for (tile_y=0; tile_y < (long) image->rows; tile_y+=tile_height_max)
410
436
          {
 
437
            long
 
438
              tile_x;
 
439
 
 
440
            MagickPassFail
 
441
              thread_status;
 
442
 
 
443
            thread_status=status;
 
444
            if (thread_status == MagickFail)
 
445
              continue;
 
446
 
411
447
            for (tile_x=0; tile_x < (long) image->columns; tile_x+=tile_width_max)
412
448
              {
413
449
                long
414
450
                  dest_tile_x,
415
451
                  dest_tile_y;
416
 
              
 
452
 
 
453
                long
 
454
                  tile_width,
 
455
                  tile_height;
 
456
 
 
457
                const PixelPacket
 
458
                  *tile_pixels;
 
459
 
 
460
                long
 
461
                  y;
 
462
 
417
463
                /*
418
464
                  Compute image region corresponding to tile.
419
465
                */
420
 
                if (tile_x+tile_width_max > image->columns)
 
466
                if ((unsigned long) tile_x+tile_width_max > image->columns)
421
467
                  tile_width=(tile_width_max-(tile_x+tile_width_max-image->columns));
422
468
                else
423
469
                  tile_width=tile_width_max;
424
 
                if (tile_y+tile_height_max > image->rows)
 
470
                if ((unsigned long) tile_y+tile_height_max > image->rows)
425
471
                  tile_height=(tile_height_max-(tile_y+tile_height_max-image->rows));
426
472
                else
427
473
                  tile_height=tile_height_max;
432
478
                                               tile_width,tile_height,exception);
433
479
                if (tile_pixels == (const PixelPacket *) NULL)
434
480
                  {
435
 
                    status=MagickFail;
 
481
                    thread_status=MagickFail;
436
482
                    break;
437
483
                  }
438
484
                /*
445
491
                */
446
492
                for (y=0; y < tile_width; y++)
447
493
                  {
448
 
                    q=SetImagePixels(rotate_image,dest_tile_x,dest_tile_y+y,tile_height,1);
 
494
                    register const PixelPacket
 
495
                      *p;
 
496
                    
 
497
                    register PixelPacket
 
498
                      *q;
 
499
 
 
500
                    register const IndexPacket
 
501
                      *indexes;
 
502
        
 
503
                    IndexPacket
 
504
                      *rotate_indexes;
 
505
 
 
506
                    register long
 
507
                      x;
 
508
 
 
509
                    q=SetImagePixelsEx(rotate_image,dest_tile_x,dest_tile_y+y,
 
510
                                       tile_height,1,exception);
449
511
                    if (q == (PixelPacket *) NULL)
450
512
                      {
451
 
                        status=MagickFail;
 
513
                        thread_status=MagickFail;
452
514
                        break;
453
515
                      }
454
516
                    /*
464
526
                    /*
465
527
                      Indexes
466
528
                    */
467
 
                    indexes=GetIndexes(image);
 
529
                    indexes=AccessImmutableIndexes(image);
468
530
                    if (indexes != (IndexPacket *) NULL)
469
531
                      {
470
 
                        rotate_indexes=GetIndexes(rotate_image);
 
532
                        rotate_indexes=AccessMutableIndexes(rotate_image);
471
533
                        if (rotate_indexes != (IndexPacket *) NULL)
472
534
                          {
 
535
                            register IndexPacket
 
536
                              *iq;
 
537
                            
 
538
                            register const IndexPacket
 
539
                              *ip;
 
540
 
473
541
                            iq=rotate_indexes;
474
542
                            ip=indexes+(tile_height-1)*tile_width + y;
475
543
                            for (x=tile_height; x != 0; x--) 
480
548
                              }
481
549
                          }
482
550
                      }
483
 
                    if (!SyncImagePixels(rotate_image))
 
551
                    if (!SyncImagePixelsEx(rotate_image,exception))
484
552
                      {
485
 
                        status=MagickFail;
 
553
                        thread_status=MagickFail;
486
554
                        break;
487
555
                      }
488
556
                  }
489
 
                if (status == MagickFail)
490
 
                  break;
 
557
 
 
558
#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
 
559
#  pragma omp critical
 
560
#endif
 
561
                {
 
562
                  tile++;
 
563
                  if (QuantumTick(tile,total_tiles))
 
564
                    if (!MagickMonitorFormatted(tile,total_tiles,exception,
 
565
                                                message,image->filename))
 
566
                      thread_status=MagickFail;
 
567
                  
 
568
                  if (thread_status == MagickFail)
 
569
                    status=MagickFail;
 
570
                }
491
571
              }
492
 
            if (status == MagickFail)
493
 
              break;
494
572
          }
495
573
        Swap(page.width,page.height);
496
574
        Swap(page.x,page.y);
502
580
        /*
503
581
          Rotate 180 degrees.
504
582
        */
 
583
        long
 
584
          y;
 
585
 
 
586
        unsigned long
 
587
          row_count=0;
 
588
 
 
589
        (void) strlcpy(message,"[%s] Rotate image 180 degrees...",sizeof(message));
 
590
#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
 
591
#  pragma omp parallel for schedule(static,8) shared(row_count, status)
 
592
#endif
505
593
        for (y=0; y < (long) image->rows; y++)
506
594
          {
 
595
            register const PixelPacket
 
596
              *p;
 
597
 
 
598
            register PixelPacket
 
599
              *q;
 
600
 
 
601
            register const IndexPacket
 
602
              *indexes;
 
603
        
 
604
            IndexPacket
 
605
              *rotate_indexes;
 
606
 
 
607
            register long
 
608
              x;
 
609
 
 
610
            MagickPassFail
 
611
              thread_status;
 
612
 
 
613
            thread_status=status;
 
614
            if (thread_status == MagickFail)
 
615
              continue;
 
616
 
507
617
            p=AcquireImagePixels(image,0,y,image->columns,1,exception);
508
 
            q=SetImagePixels(rotate_image,0,(long) (image->rows-y-1),
509
 
                             image->columns,1);
 
618
            q=SetImagePixelsEx(rotate_image,0,(long) (image->rows-y-1),
 
619
                               image->columns,1,exception);
510
620
            if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
511
 
              break;
512
 
            q+=image->columns;
513
 
            indexes=GetIndexes(image);
514
 
            rotate_indexes=GetIndexes(rotate_image);
515
 
            if ((indexes != (IndexPacket *) NULL) &&
516
 
                (rotate_indexes != (IndexPacket *) NULL))
517
 
              for (x=0; x < (long) image->columns; x++)
518
 
                rotate_indexes[image->columns-x-1]=indexes[x];
519
 
            for (x=0; x < (long) image->columns; x++)
520
 
              *--q=(*p++);
521
 
            if (!SyncImagePixels(rotate_image))
522
 
              break;
523
 
            if (QuantumTick(y,image->rows))
524
 
              if (!MagickMonitor(RotateImageText,y,image->rows,exception))
525
 
                break;
 
621
              thread_status=MagickFail;
 
622
            if (thread_status != MagickFail)
 
623
              {
 
624
                q+=image->columns;
 
625
                indexes=AccessImmutableIndexes(image);
 
626
                rotate_indexes=AccessMutableIndexes(rotate_image);
 
627
                if ((indexes != (IndexPacket *) NULL) &&
 
628
                    (rotate_indexes != (IndexPacket *) NULL))
 
629
                  for (x=0; x < (long) image->columns; x++)
 
630
                    rotate_indexes[image->columns-x-1]=indexes[x];
 
631
                for (x=0; x < (long) image->columns; x++)
 
632
                  *--q=(*p++);
 
633
                if (!SyncImagePixelsEx(rotate_image,exception))
 
634
                  thread_status=MagickFail;
 
635
              }
 
636
#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
 
637
#  pragma omp critical
 
638
#endif
 
639
            {
 
640
              row_count++;
 
641
              if (QuantumTick(row_count,image->rows))
 
642
                if (!MagickMonitorFormatted(row_count,image->rows,exception,
 
643
                                            message,image->filename))
 
644
                  thread_status=MagickFail;
 
645
                  
 
646
              if (thread_status == MagickFail)
 
647
                status=MagickFail;
 
648
            }
526
649
          }
527
650
        page.x=(long) (page.width-rotate_image->columns-page.x);
528
651
        page.y=(long) (page.height-rotate_image->rows-page.y);
533
656
        /*
534
657
          Rotate 270 degrees.
535
658
        */
536
 
        status=MagickPass;
 
659
 
 
660
        magick_int64_t
 
661
          tile;
 
662
 
 
663
        magick_uint64_t
 
664
          total_tiles;
 
665
 
 
666
        long
 
667
          tile_y;
 
668
 
 
669
        (void) strlcpy(message,"[%s] Rotate image 270 degrees...",sizeof(message));
 
670
        total_tiles=(((image->rows/tile_height_max)+1)*
 
671
                     ((image->columns/tile_width_max)+1));
 
672
        tile=0;
 
673
#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
 
674
#  pragma omp parallel for schedule(static,1) shared(status, tile)
 
675
#endif
537
676
        for (tile_y=0; tile_y < (long) image->rows; tile_y+=tile_height_max)
538
677
          {
 
678
            long
 
679
              tile_x;
 
680
 
 
681
            MagickPassFail
 
682
              thread_status;
 
683
 
 
684
            thread_status=status;
 
685
            if (thread_status == MagickFail)
 
686
              continue;
 
687
 
539
688
            for (tile_x=0; tile_x < (long) image->columns; tile_x+=tile_width_max)
540
689
              {
541
690
                long
 
691
                  tile_width,
 
692
                  tile_height;
 
693
 
 
694
                long
542
695
                  dest_tile_x,
543
696
                  dest_tile_y;
544
697
 
 
698
                long
 
699
                  y;
 
700
 
 
701
                const PixelPacket
 
702
                  *tile_pixels;
 
703
                    
545
704
                /*
546
705
                  Compute image region corresponding to tile.
547
706
                */
548
 
                if (tile_x+tile_width_max > image->columns)
 
707
                if ((unsigned long) tile_x+tile_width_max > image->columns)
549
708
                  tile_width=(tile_width_max-(tile_x+tile_width_max-image->columns));
550
709
                else
551
710
                  tile_width=tile_width_max;
552
 
                if (tile_y+tile_height_max > image->rows)
 
711
                if ((unsigned long) tile_y+tile_height_max > image->rows)
553
712
                  tile_height=(tile_height_max-(tile_y+tile_height_max-image->rows));
554
713
                else
555
714
                  tile_height=tile_height_max;
560
719
                                               tile_width,tile_height,exception);
561
720
                if (tile_pixels == (const PixelPacket *) NULL)
562
721
                  {
563
 
                    status=MagickFail;
 
722
                    thread_status=MagickFail;
564
723
                    break;
565
724
                  }
566
725
                /*
573
732
                */
574
733
                for (y=0; y < tile_width; y++)
575
734
                  {
576
 
                    q=SetImagePixels(rotate_image,dest_tile_x,dest_tile_y+y,tile_height,1);
 
735
                    register const PixelPacket
 
736
                      *p;
 
737
                    
 
738
                    register PixelPacket
 
739
                      *q;
 
740
 
 
741
                    register const IndexPacket
 
742
                      *indexes;
 
743
 
 
744
                    register long
 
745
                      x;
 
746
 
 
747
                    IndexPacket
 
748
                      *rotate_indexes;
 
749
 
 
750
                    q=SetImagePixelsEx(rotate_image,dest_tile_x,dest_tile_y+y,
 
751
                                       tile_height,1,exception);
577
752
                    if (q == (PixelPacket *) NULL)
578
753
                      {
579
 
                        status=MagickFail;
 
754
                        thread_status=MagickFail;
580
755
                        break;
581
756
                      }
582
757
                    /*
592
767
                    /*
593
768
                      Indexes
594
769
                    */
595
 
                    indexes=GetIndexes(image);
 
770
                    indexes=AccessImmutableIndexes(image);
596
771
                    if (indexes != (IndexPacket *) NULL)
597
772
                      {
598
 
                        rotate_indexes=GetIndexes(rotate_image);
 
773
                        rotate_indexes=AccessMutableIndexes(rotate_image);
599
774
                        if (rotate_indexes != (IndexPacket *) NULL)
600
775
                          {
 
776
                            register IndexPacket
 
777
                              *iq;
 
778
                            
 
779
                            register const IndexPacket
 
780
                              *ip;
 
781
 
601
782
                            iq=rotate_indexes;
602
783
                            ip=indexes+(tile_width-1-y);
603
784
                            for (x=tile_height; x != 0; x--)
608
789
                              }
609
790
                          }
610
791
                      }
611
 
                    if (!SyncImagePixels(rotate_image))
 
792
                    if (!SyncImagePixelsEx(rotate_image,exception))
612
793
                      {
613
 
                        status=MagickFail;
 
794
                        thread_status=MagickFail;
614
795
                        break;
615
796
                      }
616
797
                  }
617
 
                if (status == MagickFail)
618
 
                  break;
 
798
 
 
799
#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
 
800
#  pragma omp critical
 
801
#endif
 
802
                {
 
803
                  tile++;
 
804
                  if (QuantumTick(tile,total_tiles))
 
805
                    if (!MagickMonitorFormatted(tile,total_tiles,exception,
 
806
                                                message,image->filename))
 
807
                      thread_status=MagickFail;
 
808
                }
 
809
 
 
810
                if (thread_status == MagickFail)
 
811
                  {
 
812
                    status=MagickFail;
 
813
                    break;
 
814
                  }
619
815
              }
620
 
            if (status == MagickFail)
621
 
              break;
622
816
          }
623
817
        Swap(page.width,page.height);
624
818
        Swap(page.x,page.y);
667
861
%
668
862
*/
669
863
 
670
 
static inline PixelPacket BlendComposite(const PixelPacket *p,
671
 
  const PixelPacket *q,const double alpha)
672
 
{
673
 
  double
674
 
    color;
675
 
 
676
 
  PixelPacket
677
 
    composite;
678
 
 
679
 
  color=((double) p->red*(MaxRGB-alpha)+q->red*alpha)/MaxRGB;
680
 
  composite.red=(Quantum)
681
 
    ((color < 0) ? 0 : (color > MaxRGB) ? MaxRGB : color+0.5);
682
 
  color=((double) p->green*(MaxRGB-alpha)+q->green*alpha)/MaxRGB;
683
 
  composite.green=(Quantum)
684
 
    ((color < 0) ? 0 : (color > MaxRGB) ? MaxRGB : color+0.5);
685
 
  color=((double) p->blue*(MaxRGB-alpha)+q->blue*alpha)/MaxRGB;
686
 
  composite.blue=(Quantum)
687
 
    ((color < 0) ? 0 : (color > MaxRGB) ? MaxRGB : color+0.5);
688
 
  composite.opacity=p->opacity;
689
 
  return(composite);
690
 
}
691
 
 
692
864
static void XShearImage(Image *image,const double degrees,
693
 
  const unsigned long width,const unsigned long height,const long x_offset,
694
 
  long y_offset)
 
865
                        const unsigned long width,const unsigned long height,
 
866
                        const long x_offset,long y_offset)
695
867
{
696
 
#define XShearImageText  "  X Shear image...  "
697
 
 
698
 
  double
699
 
    alpha,
700
 
    displacement;
701
 
 
702
 
  enum {LEFT, RIGHT}
703
 
    direction;
 
868
#define XShearImageText  "[%s] X Shear image...  "
704
869
 
705
870
  long
706
 
    step,
707
871
    y;
708
872
 
709
 
  PixelPacket
710
 
    pixel;
711
 
 
712
 
  register long
713
 
    i;
 
873
  unsigned long
 
874
    row_count=0;
714
875
 
715
876
  unsigned int
716
877
    is_grayscale;
717
878
 
718
 
  register PixelPacket
719
 
    *p,
720
 
    *q;
 
879
  MagickPassFail
 
880
    status=MagickPass;
721
881
 
722
882
  assert(image != (Image *) NULL);
723
883
  is_grayscale=image->is_grayscale;
724
884
 
725
 
  y_offset--;
 
885
#if defined(HAVE_OPENMP)
 
886
#  pragma omp parallel for schedule(dynamic,8) shared(row_count, status)
 
887
#endif
726
888
  for (y=0; y < (long) height; y++)
727
 
  {
728
 
    y_offset++;
729
 
    displacement=degrees*(y-height/2.0);
730
 
    if (displacement == 0.0)
731
 
      continue;
732
 
    if (displacement > 0.0)
733
 
      direction=RIGHT;
734
 
    else
735
 
      {
736
 
        displacement*=(-1.0);
737
 
        direction=LEFT;
738
 
      }
739
 
    step=(long) floor(displacement);
740
 
    alpha=(double) MaxRGB*(displacement-step);
741
 
    if (alpha == 0.0)
742
 
      {
743
 
        /*
744
 
          No fractional displacement-- just copy.
745
 
        */
746
 
        switch (direction)
747
 
        {
748
 
          case LEFT:
 
889
    {
 
890
      double
 
891
        alpha,
 
892
        displacement;
 
893
 
 
894
      long
 
895
        step;
 
896
 
 
897
      PixelPacket
 
898
        pixel;
 
899
 
 
900
      register long
 
901
        i;
 
902
 
 
903
      register PixelPacket
 
904
        *p,
 
905
        *q;
 
906
 
 
907
      enum
 
908
        {
 
909
          LEFT,
 
910
          RIGHT
 
911
        } direction;
 
912
 
 
913
      MagickPassFail
 
914
        thread_status;
 
915
      
 
916
      thread_status=status;
 
917
      if (thread_status == MagickFail)
 
918
        continue;
 
919
 
 
920
      displacement=degrees*(y-height/2.0);
 
921
      if (displacement == 0.0)
 
922
        continue;
 
923
      if (displacement > 0.0)
 
924
        direction=RIGHT;
 
925
      else
 
926
        {
 
927
          displacement*=(-1.0);
 
928
          direction=LEFT;
 
929
        }
 
930
      step=(long) floor(displacement);
 
931
      alpha=(double) MaxRGB*(displacement-step);
 
932
      if (alpha == 0.0)
 
933
        {
 
934
          /*
 
935
            No fractional displacement-- just copy.
 
936
          */
 
937
          switch (direction)
 
938
            {
 
939
            case LEFT:
 
940
              {
 
941
                /*
 
942
                  Transfer pixels left-to-right.
 
943
                */
 
944
                if (step > x_offset)
 
945
                  break;
 
946
                p=GetImagePixelsEx(image,0,y+y_offset,image->columns,1,&image->exception);
 
947
                if (p == (PixelPacket *) NULL)
 
948
                  {
 
949
                    thread_status=MagickFail;
 
950
                    break;
 
951
                  }
 
952
                p+=x_offset;
 
953
                q=p-step;
 
954
                (void) memcpy(q,p,width*sizeof(PixelPacket));
 
955
                q+=width;
 
956
                for (i=0; i < (long) step; i++)
 
957
                  *q++=image->background_color;
 
958
                break;
 
959
              }
 
960
            case RIGHT:
 
961
              {
 
962
                /*
 
963
                  Transfer pixels right-to-left.
 
964
                */
 
965
                p=GetImagePixelsEx(image,0,y+y_offset,image->columns,1,&image->exception);
 
966
                if (p == (PixelPacket *) NULL)
 
967
                  {
 
968
                    thread_status=MagickFail;
 
969
                    break;
 
970
                  }
 
971
                p+=x_offset+width;
 
972
                q=p+step;
 
973
                for (i=0; i < (long) width; i++)
 
974
                  *--q=(*--p);
 
975
                for (i=0; i < (long) step; i++)
 
976
                  *--q=image->background_color;
 
977
                break;
 
978
              }
 
979
            }
 
980
          if (!SyncImagePixelsEx(image,&image->exception))
 
981
            thread_status=MagickFail;
 
982
 
 
983
#if defined(HAVE_OPENMP)
 
984
#  pragma omp critical
 
985
#endif
 
986
          {
 
987
            row_count++;
 
988
            if (QuantumTick(row_count,height))
 
989
              if (!MagickMonitorFormatted(row_count,height,&image->exception,
 
990
                                          XShearImageText,image->filename))
 
991
                thread_status=MagickFail;
 
992
            
 
993
            if (thread_status == MagickFail)
 
994
              status=MagickFail;
 
995
          }
 
996
 
 
997
          continue;
 
998
        }
 
999
      /*
 
1000
        Fractional displacement.
 
1001
      */
 
1002
      step++;
 
1003
      pixel=image->background_color;
 
1004
      switch (direction)
 
1005
        {
 
1006
        case LEFT:
749
1007
          {
750
1008
            /*
751
1009
              Transfer pixels left-to-right.
752
1010
            */
753
1011
            if (step > x_offset)
754
1012
              break;
755
 
            p=GetImagePixels(image,0,y_offset,image->columns,1);
 
1013
            p=GetImagePixelsEx(image,0,y+y_offset,image->columns,1,&image->exception);
756
1014
            if (p == (PixelPacket *) NULL)
757
 
              break;
 
1015
              {
 
1016
                thread_status=MagickFail;
 
1017
                break;
 
1018
              }
758
1019
            p+=x_offset;
759
1020
            q=p-step;
760
 
            (void) memcpy(q,p,width*sizeof(PixelPacket));
761
 
            q+=width;
762
 
            for (i=0; i < (long) step; i++)
 
1021
            for (i=0; i < (long) width; i++)
 
1022
              {
 
1023
                if ((x_offset+i) < step)
 
1024
                  {
 
1025
                    pixel=(*++p);
 
1026
                    q++;
 
1027
                    continue;
 
1028
                  }
 
1029
                BlendCompositePixel(q,&pixel,p,alpha);
 
1030
                q++;
 
1031
                pixel=(*p++);
 
1032
              }
 
1033
            BlendCompositePixel(q,&pixel,&image->background_color,alpha);
 
1034
            q++;
 
1035
            for (i=0; i < (step-1); i++)
763
1036
              *q++=image->background_color;
764
1037
            break;
765
1038
          }
766
 
          case RIGHT:
 
1039
        case RIGHT:
767
1040
          {
768
1041
            /*
769
1042
              Transfer pixels right-to-left.
770
1043
            */
771
 
            p=GetImagePixels(image,0,y_offset,image->columns,1);
 
1044
            p=GetImagePixelsEx(image,0,y+y_offset,image->columns,1,&image->exception);
772
1045
            if (p == (PixelPacket *) NULL)
773
 
              break;
 
1046
              {
 
1047
                thread_status=MagickFail;
 
1048
                break;
 
1049
              }
774
1050
            p+=x_offset+width;
775
1051
            q=p+step;
776
1052
            for (i=0; i < (long) width; i++)
777
 
              *--q=(*--p);
778
 
            for (i=0; i < (long) step; i++)
 
1053
              {
 
1054
                p--;
 
1055
                q--;
 
1056
                if ((x_offset+width+step-i) >= image->columns)
 
1057
                  continue;
 
1058
                BlendCompositePixel(q,&pixel,p,alpha);
 
1059
                pixel=(*p);
 
1060
              }
 
1061
            --q;
 
1062
            BlendCompositePixel(q,&pixel,&image->background_color,alpha);
 
1063
            for (i=0; i < (step-1); i++)
779
1064
              *--q=image->background_color;
780
1065
            break;
781
1066
          }
782
1067
        }
783
 
        if (!SyncImagePixels(image))
784
 
          break;
785
 
        continue;
786
 
      }
787
 
    /*
788
 
      Fractional displacement.
789
 
    */
790
 
    step++;
791
 
    pixel=image->background_color;
792
 
    switch (direction)
793
 
    {
794
 
      case LEFT:
795
 
      {
796
 
        /*
797
 
          Transfer pixels left-to-right.
798
 
        */
799
 
        if (step > x_offset)
800
 
          break;
801
 
        p=GetImagePixels(image,0,y_offset,image->columns,1);
802
 
        if (p == (PixelPacket *) NULL)
803
 
          break;
804
 
        p+=x_offset;
805
 
        q=p-step;
806
 
        for (i=0; i < (long) width; i++)
807
 
        {
808
 
          if ((x_offset+i) < step)
809
 
            {
810
 
              pixel=(*++p);
811
 
              q++;
812
 
              continue;
813
 
            }
814
 
          *q++=BlendComposite(&pixel,p,alpha);
815
 
          pixel=(*p++);
816
 
        }
817
 
        *q++=BlendComposite(&pixel,&image->background_color,alpha);
818
 
        for (i=0; i < (step-1); i++)
819
 
          *q++=image->background_color;
820
 
        break;
821
 
      }
822
 
      case RIGHT:
823
 
      {
824
 
        /*
825
 
          Transfer pixels right-to-left.
826
 
        */
827
 
        p=GetImagePixels(image,0,y_offset,image->columns,1);
828
 
        if (p == (PixelPacket *) NULL)
829
 
          break;
830
 
        p+=x_offset+width;
831
 
        q=p+step;
832
 
        for (i=0; i < (long) width; i++)
833
 
        {
834
 
          p--;
835
 
          q--;
836
 
          if ((x_offset+width+step-i) >= image->columns)
837
 
            continue;
838
 
          *q=BlendComposite(&pixel,p,alpha);
839
 
          pixel=(*p);
840
 
        }
841
 
        *--q=BlendComposite(&pixel,&image->background_color,alpha);
842
 
        for (i=0; i < (step-1); i++)
843
 
          *--q=image->background_color;
844
 
        break;
 
1068
      if (!SyncImagePixelsEx(image,&image->exception))
 
1069
        thread_status=MagickFail;
 
1070
#if defined(HAVE_OPENMP)
 
1071
#  pragma omp critical
 
1072
#endif
 
1073
      {
 
1074
        row_count++;
 
1075
        if (QuantumTick(row_count,height))
 
1076
          if (!MagickMonitorFormatted(row_count,height,&image->exception,
 
1077
                                      XShearImageText,image->filename))
 
1078
            thread_status=MagickFail;
 
1079
        
 
1080
        if (thread_status == MagickFail)
 
1081
          status=MagickFail;
845
1082
      }
846
1083
    }
847
 
    if (!SyncImagePixels(image))
848
 
      break;
849
 
    if (QuantumTick(y,height))
850
 
      if (!MagickMonitor(XShearImageText,y,height,&image->exception))
851
 
        break;
852
 
  }
853
1084
  if (is_grayscale && IsGray(image->background_color))
854
1085
    image->is_grayscale=True;
855
1086
}
889
1120
%
890
1121
*/
891
1122
static void YShearImage(Image *image,const double degrees,
892
 
  const unsigned long width,const unsigned long height,long x_offset,
893
 
  const long y_offset)
 
1123
                        const unsigned long width,const unsigned long height,long x_offset,
 
1124
                        const long y_offset)
894
1125
{
895
 
#define YShearImageText  "  Y Shear image...  "
896
 
 
897
 
  double
898
 
    alpha,
899
 
    displacement;
900
 
 
901
 
  enum {UP, DOWN}
902
 
    direction;
 
1126
#define YShearImageText  "[%s] Y Shear image..."
903
1127
 
904
1128
  long
905
 
    step,
906
1129
    y;
907
1130
 
908
 
  register PixelPacket
909
 
    *p,
910
 
    *q;
911
 
 
912
 
  register long
913
 
    i;
 
1131
  unsigned long
 
1132
    row_count=0;
914
1133
 
915
1134
  unsigned int
916
1135
    is_grayscale;
917
1136
 
918
 
  PixelPacket
919
 
    pixel;
 
1137
  MagickPassFail
 
1138
    status=MagickPass;
920
1139
 
921
1140
  assert(image != (Image *) NULL);
922
1141
  is_grayscale=image->is_grayscale;
923
 
  x_offset--;
 
1142
 
 
1143
#if defined(HAVE_OPENMP)
 
1144
#  pragma omp parallel for schedule(dynamic,8) shared(row_count, status)
 
1145
#endif
924
1146
  for (y=0; y < (long) width; y++)
925
 
  {
926
 
    x_offset++;
927
 
    displacement=degrees*(y-width/2.0);
928
 
    if (displacement == 0.0)
929
 
      continue;
930
 
    if (displacement > 0.0)
931
 
      direction=DOWN;
932
 
    else
933
 
      {
934
 
        displacement*=(-1.0);
935
 
        direction=UP;
936
 
      }
937
 
    step=(long) floor(displacement);
938
 
    alpha=(double) MaxRGB*(displacement-step);
939
 
    if (alpha == 0.0)
940
 
      {
941
 
        /*
942
 
          No fractional displacement-- just copy the pixels.
943
 
        */
944
 
        switch (direction)
945
 
        {
946
 
          case UP:
 
1147
    {
 
1148
      double
 
1149
        alpha,
 
1150
        displacement;
 
1151
 
 
1152
      enum
 
1153
        {
 
1154
          UP,
 
1155
          DOWN
 
1156
        } direction;
 
1157
 
 
1158
      long
 
1159
        step;
 
1160
 
 
1161
      register PixelPacket
 
1162
        *p,
 
1163
        *q;
 
1164
 
 
1165
      register long
 
1166
        i;
 
1167
 
 
1168
      PixelPacket
 
1169
        pixel;
 
1170
 
 
1171
      MagickPassFail
 
1172
        thread_status;
 
1173
      
 
1174
      thread_status=status;
 
1175
      if (thread_status == MagickFail)
 
1176
        continue;
 
1177
 
 
1178
      displacement=degrees*(y-width/2.0);
 
1179
      if (displacement == 0.0)
 
1180
        continue;
 
1181
      if (displacement > 0.0)
 
1182
        direction=DOWN;
 
1183
      else
 
1184
        {
 
1185
          displacement*=(-1.0);
 
1186
          direction=UP;
 
1187
        }
 
1188
      step=(long) floor(displacement);
 
1189
      alpha=(double) MaxRGB*(displacement-step);
 
1190
      if (alpha == 0.0)
 
1191
        {
 
1192
          /*
 
1193
            No fractional displacement-- just copy the pixels.
 
1194
          */
 
1195
          switch (direction)
 
1196
            {
 
1197
            case UP:
 
1198
              {
 
1199
                /*
 
1200
                  Transfer pixels top-to-bottom.
 
1201
                */
 
1202
                if (step > y_offset)
 
1203
                  break;
 
1204
                p=GetImagePixelsEx(image,y+x_offset,0,1,image->rows,&image->exception);
 
1205
                if (p == (PixelPacket *) NULL)
 
1206
                  {
 
1207
                    thread_status=MagickFail;
 
1208
                    break;
 
1209
                  }
 
1210
                p+=y_offset;
 
1211
                q=p-step;
 
1212
                (void) memcpy(q,p,height*sizeof(PixelPacket));
 
1213
                q+=height;
 
1214
                for (i=0; i < (long) step; i++)
 
1215
                  *q++=image->background_color;
 
1216
                break;
 
1217
              }
 
1218
            case DOWN:
 
1219
              {
 
1220
                /*
 
1221
                  Transfer pixels bottom-to-top.
 
1222
                */
 
1223
                p=GetImagePixelsEx(image,y+x_offset,0,1,image->rows,&image->exception);
 
1224
                if (p == (PixelPacket *) NULL)
 
1225
                  {
 
1226
                    thread_status=MagickFail;
 
1227
                    break;
 
1228
                  }
 
1229
                p+=y_offset+height;
 
1230
                q=p+step;
 
1231
                for (i=0; i < (long) height; i++)
 
1232
                  *--q=(*--p);
 
1233
                for (i=0; i < (long) step; i++)
 
1234
                  *--q=image->background_color;
 
1235
                break;
 
1236
              }
 
1237
            }
 
1238
          if (!SyncImagePixelsEx(image,&image->exception))
 
1239
            thread_status=MagickFail;
 
1240
 
 
1241
#if defined(HAVE_OPENMP)
 
1242
#  pragma omp critical
 
1243
#endif
 
1244
          {
 
1245
            row_count++;
 
1246
            if (QuantumTick(row_count,width))
 
1247
              if (!MagickMonitorFormatted(row_count,width,&image->exception,
 
1248
                                          YShearImageText,image->filename))
 
1249
                thread_status=MagickFail;
 
1250
            
 
1251
            if (thread_status == MagickFail)
 
1252
              status=MagickFail;
 
1253
          }
 
1254
 
 
1255
          continue;
 
1256
        }
 
1257
      /*
 
1258
        Fractional displacment.
 
1259
      */
 
1260
      step++;
 
1261
      pixel=image->background_color;
 
1262
      switch (direction)
 
1263
        {
 
1264
        case UP:
947
1265
          {
948
1266
            /*
949
1267
              Transfer pixels top-to-bottom.
950
1268
            */
951
1269
            if (step > y_offset)
952
1270
              break;
953
 
            p=GetImagePixels(image,x_offset,0,1,image->rows);
 
1271
            p=GetImagePixelsEx(image,y+x_offset,0,1,image->rows,&image->exception);
954
1272
            if (p == (PixelPacket *) NULL)
955
 
              break;
 
1273
              {
 
1274
                thread_status=MagickFail;
 
1275
                break;
 
1276
              }
956
1277
            p+=y_offset;
957
1278
            q=p-step;
958
 
            (void) memcpy(q,p,height*sizeof(PixelPacket));
959
 
            q+=height;
960
 
            for (i=0; i < (long) step; i++)
 
1279
            for (i=0; i < (long) height; i++)
 
1280
              {
 
1281
                if ((y_offset+i) < step)
 
1282
                  {
 
1283
                    pixel=(*++p);
 
1284
                    q++;
 
1285
                    continue;
 
1286
                  }
 
1287
                BlendCompositePixel(q,&pixel,p,alpha);
 
1288
                q++;
 
1289
                pixel=(*p++);
 
1290
              }
 
1291
            BlendCompositePixel(q,&pixel,&image->background_color,alpha);
 
1292
            q++;
 
1293
            for (i=0; i < (step-1); i++)
961
1294
              *q++=image->background_color;
962
1295
            break;
963
1296
          }
964
 
          case DOWN:
 
1297
        case DOWN:
965
1298
          {
966
1299
            /*
967
1300
              Transfer pixels bottom-to-top.
968
1301
            */
969
 
            p=GetImagePixels(image,x_offset,0,1,image->rows);
 
1302
            p=GetImagePixelsEx(image,y+x_offset,0,1,image->rows,&image->exception);
970
1303
            if (p == (PixelPacket *) NULL)
971
 
              break;
 
1304
              {
 
1305
                thread_status=MagickFail;
 
1306
                break;
 
1307
              }
972
1308
            p+=y_offset+height;
973
1309
            q=p+step;
974
1310
            for (i=0; i < (long) height; i++)
975
 
              *--q=(*--p);
976
 
            for (i=0; i < (long) step; i++)
 
1311
              {
 
1312
                p--;
 
1313
                q--;
 
1314
                if ((y_offset+height+step-i) >= image->rows)
 
1315
                  continue;
 
1316
                BlendCompositePixel(q,&pixel,p,alpha);
 
1317
                pixel=(*p);
 
1318
              }
 
1319
            --q;
 
1320
            BlendCompositePixel(q,&pixel,&image->background_color,alpha);
 
1321
            for (i=0; i < (step-1); i++)
977
1322
              *--q=image->background_color;
978
1323
            break;
979
1324
          }
980
1325
        }
981
 
        if (!SyncImagePixels(image))
982
 
          break;
983
 
        continue;
984
 
      }
985
 
    /*
986
 
      Fractional displacment.
987
 
    */
988
 
    step++;
989
 
    pixel=image->background_color;
990
 
    switch (direction)
991
 
    {
992
 
      case UP:
993
 
      {
994
 
        /*
995
 
          Transfer pixels top-to-bottom.
996
 
        */
997
 
        if (step > y_offset)
998
 
          break;
999
 
        p=GetImagePixels(image,x_offset,0,1,image->rows);
1000
 
        if (p == (PixelPacket *) NULL)
1001
 
          break;
1002
 
        p+=y_offset;
1003
 
        q=p-step;
1004
 
        for (i=0; i < (long) height; i++)
1005
 
        {
1006
 
          if ((y_offset+i) < step)
1007
 
            {
1008
 
              pixel=(*++p);
1009
 
              q++;
1010
 
              continue;
1011
 
            }
1012
 
          *q++=BlendComposite(&pixel,p,alpha);
1013
 
          pixel=(*p++);
1014
 
        }
1015
 
        *q++=BlendComposite(&pixel,&image->background_color,alpha);
1016
 
        for (i=0; i < (step-1); i++)
1017
 
          *q++=image->background_color;
1018
 
        break;
1019
 
      }
1020
 
      case DOWN:
1021
 
      {
1022
 
        /*
1023
 
          Transfer pixels bottom-to-top.
1024
 
        */
1025
 
        p=GetImagePixels(image,x_offset,0,1,image->rows);
1026
 
        if (p == (PixelPacket *) NULL)
1027
 
          break;
1028
 
        p+=y_offset+height;
1029
 
        q=p+step;
1030
 
        for (i=0; i < (long) height; i++)
1031
 
        {
1032
 
          p--;
1033
 
          q--;
1034
 
          if ((y_offset+height+step-i) >= image->rows)
1035
 
            continue;
1036
 
          *q=BlendComposite(&pixel,p,alpha);
1037
 
          pixel=(*p);
1038
 
        }
1039
 
        *--q=BlendComposite(&pixel,&image->background_color,alpha);
1040
 
        for (i=0; i < (step-1); i++)
1041
 
          *--q=image->background_color;
1042
 
        break;
 
1326
      if (!SyncImagePixelsEx(image,&image->exception))
 
1327
        thread_status=MagickFail;
 
1328
 
 
1329
#if defined(HAVE_OPENMP)
 
1330
#  pragma omp critical
 
1331
#endif
 
1332
      {
 
1333
        row_count++;
 
1334
        if (QuantumTick(row_count,width))
 
1335
          if (!MagickMonitorFormatted(row_count,width,&image->exception,
 
1336
                                      YShearImageText,image->filename))
 
1337
            thread_status=MagickFail;
 
1338
        
 
1339
        if (thread_status == MagickFail)
 
1340
          status=MagickFail;
1043
1341
      }
1044
1342
    }
1045
 
    if (!SyncImagePixels(image))
1046
 
      break;
1047
 
    if (QuantumTick(y,width))
1048
 
      if (!MagickMonitor(YShearImageText,y,width,&image->exception))
1049
 
        break;
1050
 
  }
1051
1343
  if (is_grayscale && IsGray(image->background_color))
1052
1344
    image->is_grayscale=True;
1053
1345
}