Diff of /file.c [000000] .. [2a97a8]  Maximize  Restore

Switch to unified view

a b/file.c
1
/* Panorama_Tools -   Generate, Edit and Convert Panoramic Images
2
   Copyright (C) 1998,1999 - Helmut Dersch  der@fh-furtwangen.de
3
   
4
   This program is free software; you can redistribute it and/or modify
5
   it under the terms of the GNU General Public License as published by
6
   the Free Software Foundation; either version 2, or (at your option)
7
   any later version.
8
9
   This program is distributed in the hope that it will be useful,
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
   GNU General Public License for more details.
13
14
   You should have received a copy of the GNU General Public License
15
   along with this program; if not, write to the Free Software
16
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
17
18
/*------------------------------------------------------------*/
19
20
// Functions to read and write Photoshop, and write tiffs
21
22
23
#include "filter.h"
24
25
26
27
28
29
#define WRITEUCHAR( theChar )         ch = theChar; count = 1; mywrite(fnum,count,&ch);
30
31
32
#define WRITESHORT( theShort )        svar = theShort; d = data; SHORTNUMBER( svar, d ); \
33
                                  count = 2; mywrite  (fnum,count,data);
34
 
35
36
#define WRITELONG( theLong )      var = theLong; d = data; LONGNUMBER( var, d ); \
37
                                  count = 4; mywrite  (fnum,count,data);
38
39
#define READLONG( theLong )               count = 4; myread(src,count,data);  \
40
                                          d = data; NUMBERLONG( var, d );     \
41
                                          theLong = var;
42
                                  
43
#define READSHORT( theShort )             count = 2; myread(src,count,data);  \
44
                                          d = data; NUMBERSHORT( svar, d );   \
45
                                          theShort = svar;
46
47
#define READUCHAR( theChar )              count = 1; myread(src,count,&ch); theChar = ch; 
48
                                          
49
50
51
// local functions
52
53
static int                writeImageDataPlanar    ( Image *im, file_spec fnum );
54
static int                readImageDataPlanar     (Image *im, file_spec fnum ) ;
55
static int                ParsePSDHeader          ( char *header, Image *im );
56
static int                writeChannelData        ( Image *im, file_spec fnum, int channel, PTRect *r );
57
static int                writeLayerAndMask       ( Image *im, file_spec fnum );
58
static void           getImageRectangle       ( Image *im, PTRect *r );
59
static int                fileCopy                ( file_spec src, file_spec dest, int numBytes, unsigned char *buf);
60
static void           orAlpha                 ( unsigned char* alpha, unsigned char *buf, Image *im, PTRect *r );
61
static void           writeWhiteBackground    ( int width, int height, file_spec fnum );
62
static int                addLayer                ( Image *im, file_spec src, file_spec fnum , stBuf *sB);
63
64
65
66
67
68
#define PSDHLENGTH 26
69
70
// Save image as single layer PSD file
71
// Image is background
72
int writePSD(Image *im, fullPath *sfile )
73
{
74
  file_spec   fnum;
75
  char    data[12], *d;
76
  short   svar;
77
  long    count;
78
  unsigned long   var;
79
  unsigned char  ch;
80
  int     channels, BitsPerChannel;
81
  
82
  GetChannels( im, channels );
83
  GetBitsPerChannel( im, BitsPerChannel );
84
  
85
  if(  myopen( sfile, write_bin, fnum )   )
86
  {   
87
      PrintError("Error Writing Image File");
88
      return -1;
89
  }
90
91
  // Write PSD Header
92
  WRITELONG( '8BPS' );
93
  WRITESHORT( 1 );
94
  WRITELONG( 0 ); WRITESHORT( 0 );
95
96
  WRITEUCHAR( 0 );
97
  WRITEUCHAR( channels );// No of channels
98
      
99
  WRITELONG( im->height );
100
  WRITELONG( im->width  );
101
          
102
  WRITESHORT( BitsPerChannel );           // BitsPerChannel
103
  
104
  switch( im->dataformat )
105
  {
106
      case _Lab:  WRITESHORT( 9 );
107
                  break;
108
      case _RGB:  WRITESHORT( 3 );
109
                  break;
110
      default:    WRITESHORT( 3 );            
111
  }
112
  WRITELONG( 0 );             // Color Mode
113
  WRITELONG( 0 );             // Image Resources
114
          
115
      
116
  WRITELONG( 0 );             // Layer & Mask 
117
  
118
  // Image data 
119
  
120
  writeImageDataPlanar( im,  fnum );
121
122
  myclose (fnum );
123
  return 0;
124
}
125
126
127
// Save image as single layer PSD file
128
// Image is layer in front of white background
129
int writePSDwithLayer(Image *im, fullPath *sfile )
130
{
131
  file_spec   fnum;
132
  char    data[12], *d;
133
  long    count;
134
  unsigned long   var;
135
  unsigned char  ch;
136
  short   svar;
137
  int     BitsPerChannel;
138
139
  TwoToOneByte( im ); // Multilayer image format doesn't support 16bit channels
140
  
141
  GetBitsPerChannel( im, BitsPerChannel );
142
  
143
  if(  myopen( sfile, write_bin, fnum )   )
144
  {   
145
      PrintError("Error Writing Image File");
146
      return -1;
147
  }
148
149
  // Write PSD Header
150
  WRITELONG( '8BPS' );
151
  WRITESHORT( 1 );
152
  WRITELONG( 0 ); WRITESHORT( 0 );
153
154
  WRITEUCHAR( 0 );
155
  WRITEUCHAR( 3 );            // No of channels; Background always white, 3 channels
156
      
157
  WRITELONG( im->height );
158
  WRITELONG( im->width  );
159
          
160
  WRITESHORT( BitsPerChannel );           // BitsPerChannel
161
  switch( im->dataformat )
162
  {
163
      case _Lab:  WRITESHORT( 9 );
164
                  break;
165
      case _RGB:  WRITESHORT( 3 );
166
                  break;
167
      default:    WRITESHORT( 3 );            
168
  }
169
  WRITELONG( 0 );             // Color Mode
170
  WRITELONG( 0 );             // Image Resources
171
          
172
  writeLayerAndMask( im, fnum );
173
174
  writeWhiteBackground( im->width * BitsPerChannel/8, im->height, fnum );
175
      
176
177
  myclose (fnum );
178
  return 0;
179
}
180
181
182
// Add image as additional layer into PSD-file
183
int addLayerToFile( Image *im, fullPath* sfile, fullPath* dfile, stBuf *sB)
184
{
185
  file_spec   src;
186
  file_spec   fnum;
187
  Image       sim;            //  background image
188
  char        header[128], *h;
189
  long        count, len, i, srcCount = 0, result = 0;
190
  unsigned char **buf;
191
  unsigned long var;
192
  char        data[12], *d;
193
  int         BitsPerChannel;
194
195
  TwoToOneByte( im ); // Multilayer image format doesn't support 16bit channels
196
  
197
  GetBitsPerChannel( im, BitsPerChannel );
198
  
199
200
  if( myopen( sfile,read_bin, src ) )
201
  {   
202
      PrintError("Error Opening Image File");
203
      return -1;
204
  }
205
      
206
  // Read psd header
207
208
  h = header;
209
  count = PSDHLENGTH;
210
  
211
  myread( src,count,h); srcCount += count;
212
  if( count != PSDHLENGTH )
213
  {
214
      PrintError("Error Reading Image File");
215
      myclose( src );
216
      return -1;
217
  }
218
  
219
  if( ParsePSDHeader( header, &sim ) != 0 )
220
  {
221
      PrintError("Wrong File Format");
222
      myclose( src );
223
      return -1;
224
  }
225
  
226
  // Check if image can be inserted
227
  if( sim.width != im->width || sim.height != im->height )
228
  {   
229
      PrintError("Can't add layer: Images have different size");
230
      return -1;
231
  }
232
  
233
  // Read (and ignore) Color mode data
234
  READLONG( len ); srcCount += (4 + len);
235
  count = 1;
236
  for( i=0; i<len; i++ )
237
  {
238
      myread(src,count,h);
239
  }
240
241
  // Read (and ingnore) Image resources
242
  READLONG( len ); srcCount += (4 + len);
243
  count = 1;
244
  for( i=0; i<len; i++ )
245
  {
246
      myread(src,count,h);
247
  }
248
249
  myclose( src );
250
251
  if( myopen( sfile, read_bin, src ) )
252
  {   
253
      PrintError("Error Opening Image File");
254
      return -1;
255
  }
256
257
  if( myopen( dfile, write_bin, fnum ) )
258
  {   
259
      PrintError("Error Opening Image File");
260
      return -1;
261
  }
262
263
  // Read and write Fileheader
264
  buf = (unsigned char**)mymalloc( srcCount );
265
  if( buf == NULL )
266
  {
267
      PrintError("Not enough memory");
268
      result = -1;
269
      goto _addLayerToFile_exit;
270
  }
271
  fileCopy( src, fnum, srcCount, *buf );  
272
  myfree( (void**)buf );
273
274
  // Add one layer    
275
    if( addLayer( im, src, fnum, sB ) != 0 )
276
  {
277
      result = -1;
278
      goto _addLayerToFile_exit;
279
  }
280
281
  
282
  writeWhiteBackground( sim.width * BitsPerChannel/8, sim.height, fnum );
283
  
284
285
_addLayerToFile_exit:
286
  myclose( src ); myclose( fnum );
287
  return result;
288
}
289
290
291
292
293
static int writeImageDataPlanar( Image *im, file_spec fnum )
294
{
295
  register int            x,y,idy, bpp;
296
  unsigned char           **channel;
297
  register unsigned char  *ch, *idata;
298
  int                     color;
299
  long                    count;
300
  short                   svar;
301
  char                    data[12], *d;
302
  int                     BitsPerChannel, channels;
303
  
304
  GetBitsPerChannel( im, BitsPerChannel );
305
  GetChannels( im,channels);
306
  
307
  bpp = im->bitsPerPixel / 8;
308
          
309
310
311
  // Write Compression info
312
  
313
  WRITESHORT( 0 ); // Raw data
314
315
316
  // Buffer to hold data in one channel
317
  
318
  count = im->width * im->height * BitsPerChannel / 8;
319
  
320
  channel = (unsigned char**)mymalloc( count );
321
  
322
  if( channel == NULL )
323
  {
324
      PrintError("Not Enough Memory");
325
      return -1;
326
  }
327
328
  if( BitsPerChannel ==  8 )
329
  {
330
      for( color = 0; color<3; color++)
331
      {
332
          ch = *channel; idata = &(*im->data)[color + channels - 3];
333
      
334
          for(y=0; y<im->height;y++)
335
          {
336
              idy = y * im->bytesPerLine;
337
              for(x=0; x<im->width;x++)
338
              {
339
                  *ch++ = idata [ idy + x * bpp ];
340
              }
341
          }
342
  
343
          mywrite( fnum, count, *channel );
344
      }
345
  }
346
  else // 16
347
  {
348
      for( color = 0; color<3; color++)
349
      {
350
          ch = *channel; idata = &(*im->data)[2*(color + channels - 3)];
351
      
352
          for(y=0; y<im->height;y++)
353
          {
354
              idy = y * im->bytesPerLine;
355
              for(x=0; x<im->width;x++)
356
              {
357
                  *ch++ = idata [ idy + x * bpp ];
358
                  *ch++ = idata [ idy + x * bpp + 1];
359
              }
360
          }
361
  
362
          mywrite( fnum, count, *channel );
363
      }
364
  }
365
  
366
      
367
368
  if( im->bitsPerPixel == 32 )
369
  {
370
      // Write 1byte alpha channel
371
      
372
      ch = *channel; idata = &(*im->data)[0];
373
      
374
      for(y=0; y<im->height;y++)
375
      {
376
          idy = y * im->bytesPerLine;
377
          for(x=0; x<im->width;x++)
378
              {
379
                  *ch++ = idata [ idy + x * bpp ];
380
              }
381
      }
382
  
383
      mywrite( fnum, count, *channel );
384
  }
385
  else if( im->bitsPerPixel == 64 )
386
  {
387
      // Write 2byte alpha channel
388
      
389
      ch = *channel; idata = &(*im->data)[0];
390
      
391
      for(y=0; y<im->height;y++)
392
      {
393
          idy = y * im->bytesPerLine;
394
          for(x=0; x<im->width;x++)
395
              {
396
                  *ch++ = idata [ idy + x * bpp ];
397
                  *ch++ = idata [ idy + x * bpp + 1];
398
              }
399
      }
400
  
401
      mywrite( fnum, count, *channel );
402
  }
403
  
404
  myfree( (void**)channel );
405
  return 0;
406
}
407
408
409
// Write white background, RLE-compressed
410
411
static void writeWhiteBackground( int width, int height, file_spec fnum )
412
{
413
  short           svar;
414
  long            count,  w8, w;
415
  char            data[12], *d, scanline[256];
416
  
417
  int numChannels = 3, i, bytecount, dim = height*numChannels;
418
  
419
  WRITESHORT( 1 );    // RLE compressed
420
421
  w8 = width;
422
  
423
  d = scanline;
424
  // Set up scanline
425
  for(w=w8; w>128; w-=128)
426
  {
427
      *d++ = -127; *d++ = (char)255;
428
  }
429
430
  switch(w)
431
  {
432
      case 0: break;
433
      case 1: *d++=0;         *d++ = (char)255;
434
              break;
435
      default: *d++=1-w;      *d++ = (char)255;
436
              break;
437
  }
438
  
439
  bytecount = d - scanline;
440
  
441
  // Scanline counts (rows*channels)
442
  for(i=0; i < dim; i++)
443
  {
444
      WRITESHORT( bytecount );
445
  }
446
447
  // RLE compressed data
448
  count = bytecount;
449
  for(i=0; i < dim; i++)
450
  {
451
      mywrite( fnum, count, scanline );
452
  }
453
  
454
}
455
456
// image is allocated, but not image data
457
// mode = 0: only load image struct
458
// mode = 1: also allocate and load data
459
460
int readPSD(Image *im, fullPath *sfile, int mode)
461
{
462
  file_spec   src;
463
  char    header[128], *h;
464
  long    count, len, i;
465
  unsigned long var;
466
  char    data[12], *d;
467
  
468
  
469
  if( myopen( sfile, read_bin, src ) )
470
  {   
471
      PrintError("Error Opening Image File");
472
      return -1;
473
  }
474
      
475
  // Read psd header
476
477
  h = header;
478
  count = PSDHLENGTH;
479
  
480
  myread( src,count,h);
481
  if( count != PSDHLENGTH )
482
  {
483
      PrintError("Error Reading Image File");
484
      myclose( src );
485
      return -1;
486
  }
487
  
488
  if( ParsePSDHeader( header, im ) != 0 )
489
  {
490
      PrintError("Wrong File Format");
491
      myclose( src );
492
      return -1;
493
  }
494
495
  if( mode == 0 )
496
  {
497
      myclose( src );
498
      return 0;
499
  }
500
  
501
  im->data = (unsigned char**) mymalloc( im->dataSize );
502
  if( im->data == NULL )
503
  {
504
      PrintError("Not enough memory to read image");
505
      myclose( src );
506
      return -1;
507
  }
508
  // Read (and ingnore) Color mode data
509
  READLONG( len );
510
  count = 1;
511
  for( i=0; i<len; i++ )
512
      myread(src,count,h);
513
514
  // Read (and ingnore) Image resources
515
  READLONG( len );
516
  count = 1;
517
  for( i=0; i<len; i++ )
518
      myread(src,count,h);
519
      
520
  // Read (and ingnore) Layer mask info
521
  READLONG( len );
522
  count = 1;
523
  for( i=0; i<len; i++ )
524
      myread(src,count,h);
525
      
526
  
527
  if( readImageDataPlanar( im, src ) != 0 )
528
  {
529
      PrintError("Error reading image");
530
      myclose( src );
531
      return -1;
532
  }
533
  
534
  myclose (src );
535
  return 0;
536
}
537
538
static int ParsePSDHeader( char *header, Image *im )
539
{
540
  register char *h = header;
541
  short s;
542
  int channels;
543
  
544
  if( *h++ != '8' || *h++ != 'B' || *h++ != 'P' || *h++ != 'S' ||
545
      *h++ != 0   || *h++ != 1   ||
546
      *h++ != 0   || *h++ != 0   || *h++ != 0   || *h++ != 0   || *h++ != 0   || *h++ != 0 )
547
      return -1;
548
  
549
  NUMBERSHORT( s, h );
550
  
551
  channels = s;
552
  
553
  if( channels < 3 ) //!= 3 && channels != 4 )
554
  {
555
      PrintError( "Number of channels must be 3 or larger" );
556
      return -1;
557
  }
558
  if( channels > 4 ) channels = 4;
559
  
560
  NUMBERLONG( im->height, h );
561
  NUMBERLONG( im->width,  h );
562
  
563
  
564
  NUMBERSHORT( s, h );
565
  
566
567
  if( s!= 8 && s!= 16)
568
  {
569
      PrintError( "Depth must be 8 or 16 Bits per Channel" );
570
      return -1;
571
  }
572
573
  im->bitsPerPixel = s * channels;
574
  
575
  NUMBERSHORT( s, h );
576
  
577
  switch( s )
578
  {
579
      case 3:     im->dataformat = _RGB; break;
580
      case 9:     im->dataformat = _Lab; break;
581
      default:    PrintError( "Color mode must be RGB or Lab" );return -1;
582
  }
583
  
584
  im->bytesPerLine = im->width * im->bitsPerPixel/8;
585
  im->dataSize = im->height * im->bytesPerLine;
586
  
587
  return 0;
588
}
589
590
591
static int readImageDataPlanar(Image *im, file_spec src ) 
592
{
593
  register int            x,y,idy, bpp;
594
  unsigned char           **channel = NULL;
595
  register unsigned char  *h, *idata;
596
  int                     result = 0, i, chnum,BitsPerChannel, channels;
597
  long                    count;
598
  short                   svar;
599
  char                    data[12], *d ;
600
  
601
  GetBitsPerChannel( im, BitsPerChannel );
602
  GetChannels( im, channels );
603
  bpp = im->bitsPerPixel / 8;
604
605
606
607
608
  // Read Compression info
609
  
610
611
  READSHORT( svar );  
612
  if( svar!= 0 )
613
  {
614
      PrintError("Image data must not be compressed");
615
      return -1;
616
  }
617
  
618
  // Allocate memory for one channel
619
  
620
  count = im->width * im->height * BitsPerChannel/8 ;
621
  channel = (unsigned char**)mymalloc( count );
622
  
623
  if( channel == NULL )
624
  {
625
      PrintError("Not Enough Memory");
626
      return -1;
627
  }
628
629
  
630
  for(i = 0; i < channels; i++)       // Read each channel
631
  {
632
      chnum = i + channels - 3; 
633
      if(chnum == 4) chnum = 0;   // Order: r g b (alpha)
634
      
635
636
      myread(src,count,*channel);
637
      if( count != im->width * im->height * BitsPerChannel/8)
638
      { 
639
          PrintError("Error Reading Image Data");
640
          result = -1;
641
          goto readImageDataPlanar_exit;
642
      }
643
      
644
      h = *channel; 
645
      
646
      if( BitsPerChannel == 8 )
647
      {
648
          idata = &(*im->data)[chnum];
649
          for(y=0; y<im->height;y++)
650
          {
651
              idy = y * im->bytesPerLine;
652
              for(x=0; x<im->width;x++)
653
              {
654
                  idata [ idy + x * bpp ] = *h++;
655
              }
656
          }
657
      }
658
      else // 16
659
      {
660
          idata = &(*im->data)[chnum*2];
661
          for(y=0; y<im->height;y++)
662
          {
663
              idy = y * im->bytesPerLine;
664
              for(x=0; x<im->width;x++)
665
              {
666
                  idata [ idy + x * bpp ]     = *h++;
667
                  idata [ idy + x * bpp + 1]  = *h++;
668
              }
669
          }
670
      }
671
  }
672
  
673
readImageDataPlanar_exit:
674
  if( channel != NULL )
675
      myfree( (void**)channel );
676
  return result;
677
}
678
679
680
681
682
683
// Write image as separate first layer
684
685
static int writeLayerAndMask( Image *im, file_spec fnum )
686
{
687
  unsigned long   var;
688
  PTRect          theRect;
689
  int             channelLength;
690
  long            count;
691
  short           svar;
692
  char            data[12], *d;
693
  unsigned char   ch;
694
  int             i, chnum, lenLayerInfo, numLayers,BitsPerChannel,channels;
695
  int             oddSized = 0;
696
  
697
698
  GetBitsPerChannel( im, BitsPerChannel );
699
  GetChannels( im, channels );
700
701
  getImageRectangle( im, &theRect );
702
703
  numLayers = 1;
704
  
705
  channelLength = (theRect.right-theRect.left) * (theRect.bottom-theRect.top) * BitsPerChannel/8  + 2;    
706
  
707
  
708
  lenLayerInfo = 2 + numLayers * (4*4 + 2 + channels * 6 + 4 + 4 + 4 * 1 + 4 + 12 + channels * channelLength);
709
      
710
  
711
  WRITELONG( lenLayerInfo + 4 + 4 );
712
  // Layer info. See table 2–13.
713
714
  if( lenLayerInfo/2 != (lenLayerInfo+1)/2 ) // odd
715
  {
716
      lenLayerInfo += 1; oddSized = 1;
717
  }
718
  
719
  // Length of the layers info section, rounded up to a multiple of 2.
720
  WRITELONG( lenLayerInfo );
721
  
722
  // 2 bytes Count Number of layers. If <0, then number of layers is absolute value,
723
  // and the first alpha channel contains the transparency data for
724
  // the merged result.
725
  WRITESHORT( numLayers );
726
  
727
  // ********** Layer Structure ********************************* //  
728
729
730
  WRITELONG( theRect.top );                   // Layer top 
731
  WRITELONG( theRect.left );                  // Layer left
732
  WRITELONG( theRect.bottom ) ;               // Layer bottom 
733
  WRITELONG( theRect.right  ) ;               // Layer right 
734
735
  WRITESHORT( channels ); // The number of channels in the layer.
736
737
  // ********** Channel information ***************************** //
738
      
739
  WRITESHORT( 0 );            // red
740
  WRITELONG( channelLength )  // Length of following channel data.
741
  WRITESHORT( 1 );            // green
742
  WRITELONG( channelLength )  // Length of following channel data.
743
  WRITESHORT( 2 );            // blue
744
  WRITELONG( channelLength )  // Length of following channel data.
745
  if( channels == 4 ) // alpha channel
746
  {
747
      WRITESHORT( -1 ); //-2 );       // transparency mask
748
      WRITELONG( channelLength )  // Length of following channel data.
749
  }
750
751
  // ********** End Channel information ***************************** //
752
  
753
  WRITELONG( '8BIM'); // Blend mode signature Always 8BIM.
754
  WRITELONG( 'norm'); // Blend mode key
755
756
  WRITEUCHAR(255); // 1 byte Opacity 0 = transparent ... 255 = opaque
757
  WRITEUCHAR( 0 ); // 1 byte Clipping 0 = base, 1 = non–base
758
  WRITEUCHAR( 1 ); // 1 byte Flags bit 0 = transparency protected bit 1 = visible
759
  WRITEUCHAR( 0 ); // 1 byte (filler) (zero)
760
761
  WRITELONG( 12);     // Extra data size Length of the extra data field. 
762
  WRITELONG( 0 );     // Layer Mask data
763
  WRITELONG( 0 );     // Layer blending ranges
764
765
  WRITEUCHAR( 3 ); WRITEUCHAR( 'L' );WRITEUCHAR( '0' );WRITEUCHAR( '1' );// Layer name
766
  
767
  
768
  // ************* End Layer Structure ******************************* //
769
770
  // ************* Write Channel Image data ************************** //
771
772
  for(i = 0; i < channels; i++)
773
  {
774
      chnum = i + channels - 3;
775
      if(chnum == 4) chnum = 0; // Order: r g b (alpha)
776
      if( writeChannelData( im, fnum, chnum, &theRect ) ) 
777
          return -1;
778
  }
779
  if( oddSized )          // pad byte
780
  {
781
      WRITEUCHAR( 0 );
782
  }
783
784
  // ************* End Write Channel Image data ************************** //
785
  
786
  // ************* Global layer mask info ******************************** //
787
  
788
  WRITELONG(  0 );        // Length of global layer mask info section.
789
  
790
  // WRITESHORT( 0 );     // 2 bytes Overlay color space
791
  // WRITESHORT( 0 );     // 4 * 2 byte color components
792
  // WRITESHORT( 0 );     
793
  // WRITESHORT( 0 );     
794
  // WRITESHORT( 0 );
795
  // WRITESHORT( 0 );     // 2 bytes Opacity 0 = transparent, 100 = opaque.
796
  // WRITEUCHAR( 128 );       // 1 byte Kind 0=Color selected—i.e. inverted; 
797
                          // 1=Color protected;128=use value stored per layer.
798
                          //  This value is preferred. The others are for back-ward
799
                          // compatibility with beta versions.
800
  // WRITEUCHAR( 0 );
801
802
  return 0;
803
804
}
805
806
807
808
809
static int writeChannelData( Image *im, file_spec fnum, int channel, PTRect *theRect )
810
{
811
  register int            x,y,idy, bpp,BitsPerChannel,channels;
812
  unsigned char           **ch;
813
  register unsigned char  *c, *idata;
814
  long                    count;
815
  short                   svar;
816
  char                    data[12], *d;
817
818
  GetBitsPerChannel( im, BitsPerChannel );
819
  GetChannels( im, channels );
820
  
821
  // Write Compression info
822
823
  WRITESHORT( 0 );     // Raw data
824
825
  bpp = im->bitsPerPixel/8;
826
827
  count = (theRect->right - theRect->left) * (theRect->bottom - theRect->top) * BitsPerChannel/8;
828
  
829
  ch = (unsigned char**)mymalloc( count );
830
  
831
  if( ch == NULL )
832
  {
833
      PrintError("Not Enough Memory");
834
      return -1;
835
  }
836
837
  c = *ch; idata = &((*(im->data))[channel*BitsPerChannel/8]);
838
  
839
  if(BitsPerChannel == 8)
840
  {
841
      for(y=theRect->top; y<theRect->bottom;y++)
842
      {
843
          idy = y * im->bytesPerLine;
844
          for(x=theRect->left; x<theRect->right;x++)
845
          {
846
              *c++ = idata [ idy + x * bpp ];
847
          }
848
      }
849
  }
850
  else // 16
851
  {
852
      for(y=theRect->top; y<theRect->bottom;y++)
853
      {
854
          idy = y * im->bytesPerLine;
855
          for(x=theRect->left; x<theRect->right;x++)
856
          {
857
              *c++ = idata [ idy + x * bpp ];
858
              *c++ = idata [ idy + x * bpp + 1 ];
859
          }
860
      }
861
  }   
862
  mywrite( fnum, count, *ch );
863
  
864
      
865
  myfree( (void**)ch );
866
  return 0;
867
}
868
869
870
// Return the smallest rectangle enclosing the image; 
871
// Use alpha channel and rgb data 
872
static void getImageRectangle( Image *im, PTRect *theRect )
873
{
874
  register unsigned char *alpha, *data;
875
  register int cx,x,y,cy,bpp,channels;
876
  int BitsPerChannel;
877
878
  GetChannels( im, channels );
879
  GetBitsPerChannel( im, BitsPerChannel );
880
  bpp = im->bitsPerPixel/8;
881
882
883
  theRect->top            = 0;
884
  theRect->left           = 0;
885
  theRect->bottom         = im->height;
886
  theRect->right          = im->width;
887
888
  if( channels == 4 ){ //  alpha channel present
889
890
      if( BitsPerChannel == 8 ){
891
          for(y=0; y<im->height; y++){
892
              for(x=0, alpha = *(im->data) + y * im->bytesPerLine; 
893
                  x<im->width; 
894
                  x++, alpha += 4){
895
                  if( * (int*) alpha ){
896
                      theRect->top = y;
897
                      goto _get_bottom;
898
                  }
899
              }
900
          }
901
      }else{ // 16
902
          for(y=0; y<im->height; y++){
903
              for(x=0, alpha = *(im->data) + y * im->bytesPerLine; 
904
                  x<im->width; 
905
                  x++, alpha += 8){
906
                  if( * (int*) alpha || * (int*) (alpha+4) ){
907
                      theRect->top = y;
908
                      goto _get_bottom;
909
                  }
910
              }
911
          }
912
      }
913
      
914
915
  _get_bottom:
916
      if( BitsPerChannel == 8 ){
917
          for(y=im->height-1; y>=0; y--){
918
              for(x=0, alpha = *(im->data) + y * im->bytesPerLine; 
919
                  x<im->width; 
920
                  x++, alpha += 4){
921
                  if( * (int*) alpha ){
922
                      theRect->bottom = y+1;
923
                      goto _get_left;
924
                  }
925
              }
926
          }
927
      }else{ // 16
928
          for(y=im->height-1; y>=0; y--){
929
              for(x=0, alpha = *(im->data) + y * im->bytesPerLine; 
930
                  x<im->width; 
931
                  x++, alpha += 8){
932
                  if( * (int*) alpha || * (int*) (alpha+4) ){
933
                      theRect->bottom = y+1;
934
                      goto _get_left;
935
                  }
936
              }
937
          }
938
      }
939
      
940
  _get_left:
941
      if( BitsPerChannel == 8 ){
942
          for(x=0; x<im->width; x++){
943
              for(y=0, alpha = *(im->data) + x*bpp; 
944
                  y<im->height; 
945
                  y++, alpha += im->bytesPerLine){
946
                  if( * (int*) alpha ){
947
                      theRect->left = x;
948
                      goto _get_right;
949
                  }
950
              }
951
          }
952
      }else{ // 16
953
          for(x=0; x<im->width; x++){
954
              for(y=0, alpha = *(im->data) + x*bpp; 
955
                  y<im->height; 
956
                  y++, alpha += im->bytesPerLine){
957
                  if( * (int*) alpha || * (int*) (alpha+4) ){
958
                      theRect->left = x;
959
                      goto _get_right;
960
                  }
961
              }
962
          }
963
      }   
964
  _get_right:
965
      if( BitsPerChannel == 8 ){
966
          for(x=im->width-1; x>=0; x--){
967
              for(y=0, alpha = *(im->data) + x*bpp; 
968
                  y<im->height; 
969
                  y++, alpha += im->bytesPerLine){
970
                  if( * (int*) alpha ){
971
                      theRect->right = x + 1;
972
                      goto _get_exit;
973
                  }
974
              }
975
          }
976
      }else{ // 16
977
          for(x=im->width-1; x>=0; x--){
978
              for(y=0, alpha = *(im->data) + x*bpp; 
979
                  y<im->height; 
980
                  y++, alpha += im->bytesPerLine){
981
                  if( * (int*) alpha || * (int*) (alpha+4) ){
982
                      theRect->right = x + 1;
983
                      goto _get_exit;
984
                  }
985
              }
986
          }
987
      }
988
  }
989
  else //  no alpha channel: Use non black rectangle
990
  {
991
      alpha       = *(im->data);
992
993
      if( BitsPerChannel == 8 )
994
      {
995
          for(y=0; y<im->height; y++)
996
          {
997
              cy = y * im->bytesPerLine;
998
              for(x=0; x<im->width; x++)
999
              {
1000
                  data = alpha + cy + bpp*x;
1001
                  if( *data || *(data+1) || *(data+2) )
1002
                  {
1003
                      theRect->top = y;
1004
                      goto _get_bottom_noalpha;
1005
                  }
1006
              }
1007
          }
1008
      }
1009
      else // 16
1010
      {
1011
          for(y=0; y<im->height; y++)
1012
          {
1013
              cy = y * im->bytesPerLine;
1014
              for(x=0; x<im->width; x++)
1015
              {
1016
                  data = alpha + cy + bpp*x;
1017
                  if( *((USHORT*)data) || *(((USHORT*)data)+1) || *(((USHORT*)data)+2) )
1018
                  {
1019
                      theRect->top = y;
1020
                      goto _get_bottom_noalpha;
1021
                  }
1022
              }
1023
          }
1024
      }
1025
1026
  _get_bottom_noalpha:
1027
      if( BitsPerChannel == 8 )
1028
      {
1029
          for(y=im->height-1; y>=0; y--)
1030
          {
1031
              cy = y * im->bytesPerLine;
1032
              for(x=0; x<im->width; x++)
1033
              {
1034
                  data = alpha + cy + bpp*x;
1035
                  if( *data || *(data+1) || *(data+2) )
1036
                  {
1037
                      theRect->bottom = y+1;
1038
                      goto _get_left_noalpha;
1039
                  }
1040
              }
1041
          }
1042
      }
1043
      else // 16
1044
      {
1045
          for(y=im->height-1; y>=0; y--)
1046
          {
1047
              cy = y * im->bytesPerLine;
1048
              for(x=0; x<im->width; x++)
1049
              {
1050
                  data = alpha + cy + bpp*x;
1051
                  if( *((USHORT*)data) || *(((USHORT*)data)+1) || *(((USHORT*)data)+2) )
1052
                  {
1053
                      theRect->bottom = y+1;
1054
                      goto _get_left_noalpha;
1055
                  }
1056
              }
1057
          }
1058
      }
1059
      
1060
  _get_left_noalpha:
1061
      if( BitsPerChannel == 8 )
1062
      {
1063
          for(x=0; x<im->width; x++)
1064
          {
1065
              cx = bpp * x;
1066
              for(y=0; y<im->height; y++)
1067
              {
1068
                  data = alpha + y * im->bytesPerLine + cx;
1069
                  if( *data || *(data+1) || *(data+2) )
1070
                  {
1071
                      theRect->left = x;
1072
                      goto _get_right_noalpha;
1073
                  }
1074
              }
1075
          }
1076
      }
1077
      else // 16
1078
      {
1079
          for(x=0; x<im->width; x++)
1080
          {
1081
              cx = bpp * x;
1082
              for(y=0; y<im->height; y++)
1083
              {
1084
                  data = alpha + y * im->bytesPerLine + cx;
1085
                  if( *((USHORT*)data) || *(((USHORT*)data)+1) || *(((USHORT*)data)+2) )
1086
                  {
1087
                      theRect->left = x;
1088
                      goto _get_right_noalpha;
1089
                  }
1090
              }
1091
          }
1092
      }
1093
  
1094
  _get_right_noalpha:
1095
      if( BitsPerChannel == 8 )
1096
      {
1097
          for(x=im->width-1; x>=0; x--)
1098
          {
1099
              cx = bpp * x;
1100
              for(y=0; y<im->height; y++)
1101
              {
1102
                  data = alpha + y * im->bytesPerLine + cx;
1103
                  if( *data || *(data+1) || *(data+2) )
1104
                  {
1105
                      theRect->right = x + 1;
1106
                      goto _get_exit;
1107
                  }
1108
              }
1109
          }
1110
      }
1111
      else // 16
1112
      {
1113
          for(x=im->width-1; x>=0; x--)
1114
          {
1115
              cx = bpp * x;
1116
              for(y=0; y<im->height; y++)
1117
              {
1118
                  data = alpha + y * im->bytesPerLine + cx;
1119
                  if( *((USHORT*)data) || *(((USHORT*)data)+1) || *(((USHORT*)data)+2) )
1120
                  {
1121
                      theRect->right = x + 1;
1122
                      goto _get_exit;
1123
                  }
1124
              }
1125
          }
1126
      }
1127
  }
1128
  _get_exit: ;
1129
}     
1130
1131
1132
1133
                                  
1134
// Image is added to layer structure of file.
1135
// There must be one valid layer structure, and the
1136
// filepointer is at the beginning of it in both src and dest
1137
1138
static int addLayer( Image *im, file_spec src, file_spec fnum, stBuf *sB )
1139
{
1140
  unsigned long   var;
1141
  PTRect          theRect, *nRect = NULL;
1142
  int             channelLength,  bpp, oddSized = 0;
1143
  int             result = 0;
1144
  long            count;
1145
  short           svar;
1146
  char            data[12], *d;
1147
  unsigned char   ch;
1148
  int             i, k, lenLayerInfo, numLayers,channels,BitsPerChannel;
1149
  int             *chlength = NULL, *nchannel = NULL, 
1150
                  *cnames = NULL, *nodd = NULL;
1151
  unsigned char   **alpha = NULL, **buf = NULL;
1152
1153
  GetChannels( im, channels );
1154
  GetBitsPerChannel( im, BitsPerChannel );
1155
  bpp = im->bitsPerPixel/8;
1156
  
1157
  if( channels == 4 ) // Alpha channel present
1158
  {
1159
      if( sB->seam == _middle )   // we have to stitch
1160
          alpha = (unsigned char**) mymalloc( im->width * im->height * BitsPerChannel/8);
1161
  }
1162
1163
  if( alpha != NULL )
1164
  {
1165
      memset( *alpha, 0 , im->width * im->height * BitsPerChannel/8);
1166
  }
1167
1168
  getImageRectangle( im, &theRect );
1169
  channelLength = (theRect.right-theRect.left) * (theRect.bottom-theRect.top)  + 2;
1170
  
1171
  
1172
  // Read layerinfo up to channeldata
1173
  READLONG( var );            // Length of the miscellaneous information section (ignored)
1174
  READLONG( var );            // Length of the layers info section, rounded up to a multiple of 2(ignored)
1175
  READSHORT( numLayers );     // Number of layers
1176
1177
  chlength = (int*) malloc( numLayers * sizeof( int ));
1178
  nchannel = (int*) malloc( numLayers * sizeof( int ));
1179
  cnames   = (int*) malloc( numLayers * sizeof( int ));
1180
  nodd     = (int*) malloc( numLayers * sizeof( int ));
1181
  nRect    = (PTRect*) malloc( numLayers * sizeof( PTRect ));
1182
  if( chlength == NULL || nchannel== NULL || nRect == NULL ||
1183
      cnames == NULL || nodd == NULL)
1184
  {
1185
      PrintError("Not enough memory 1");
1186
      result = -1;
1187
      goto _addLayer_exit;
1188
  }
1189
  lenLayerInfo = 2;
1190
  for(i=0; i<numLayers; i++) 
1191
  {
1192
      READLONG( nRect[i].top   )  ;           // Layer top 
1193
      READLONG( nRect[i].left  )  ;           // Layer left
1194
      READLONG( nRect[i].bottom)  ;           // Layer bottom 
1195
      READLONG( nRect[i].right )  ;           // Layer right 
1196
1197
      READSHORT( nchannel[i] );           // The number of channels in the layer.
1198
1199
      // ********** Channel information ***************************** //
1200
      
1201
      READSHORT( svar );                  // red
1202
      READLONG(chlength[i]);              // Length of following channel data.
1203
      READSHORT( svar );                  // green
1204
      READLONG(chlength[i]);              // Length of following channel data.
1205
      READSHORT( svar );                  // blue
1206
      READLONG(chlength[i]);              // Length of following channel data.
1207
      if( nchannel[i] > 3 ) // 1st alpha channel
1208
      {
1209
          READSHORT( svar );              // transparency mask
1210
          READLONG( chlength[i]);         // Length of following channel data.
1211
      }
1212
      if( nchannel[i] > 4 ) // 2nd alpha channel
1213
      {
1214
          READSHORT( svar );              // transparency mask
1215
          READLONG( chlength[i]);         // Length of following channel data.
1216
      }
1217
      
1218
      // ********** End Channel information ***************************** //
1219
  
1220
      READLONG( var );                     // Blend mode signature Always 8BIM.
1221
      READLONG( var );                     // Blend mode key
1222
1223
      READLONG( var );                    // Four flag bytes
1224
1225
      READLONG( var );                    // Extra data size Length of the extra data field. This is the
1226
      READLONG( var );                    // Layer Mask data
1227
      READLONG( var );                    // Layer blending ranges
1228
1229
      READLONG( cnames[i] );              // Layer name
1230
      
1231
      var = 4*4 + 2 + nchannel[i] * 6 + 4 + 4 + 4 * 1 + 4 + 12 + nchannel[i] * chlength[i]; // length
1232
      if( var/2 != (var+1)/2 ) // odd
1233
      {
1234
          nodd[i] = 1; var++;
1235
          //READUCHAR( ch );
1236
      }
1237
      else
1238
      {
1239
          nodd[i] = 0;
1240
      }
1241
      lenLayerInfo += var;
1242
  }
1243
  
1244
  // length of new channel
1245
  
1246
  if(0)//alpha != NULL)
1247
      var = 4*4 + 2 + (channels+1) * 6 + 4 + 4 + 4 * 1 + 4 + 12 + (channels+1) * channelLength;
1248
  else
1249
      var = 4*4 + 2 + channels * 6 + 4 + 4 + 4 * 1 + 4 + 12 + channels * channelLength;
1250
1251
  if( var/2 != (var+1)/2 ) // odd
1252
  {
1253
      oddSized = 1; var++;
1254
          // PrintError("odd");
1255
  }
1256
  lenLayerInfo += var;
1257
      
1258
  //printf("Writing Length of Layerinfo: %d\n", lenLayerInfo);
1259
  if( lenLayerInfo/2 != (lenLayerInfo+1)/2 ) // odd, should never happen
1260
  {
1261
      //PrintError("odd");
1262
      lenLayerInfo += 1;
1263
  }
1264
  
1265
  WRITELONG( lenLayerInfo + 4 + 4 );
1266
  // Length of the layers info section, rounded up to a multiple of 2.
1267
  WRITELONG( lenLayerInfo ); ;
1268
  //printf("Corrected to: %d\n", lenLayerInfo);
1269
  
1270
  // 2 bytes Count Number of layers. If <0, then number of layers is absolute value,
1271
  // and the first alpha channel contains the transparency data for
1272
  // the merged result.
1273
  WRITESHORT( numLayers + 1); 
1274
  // Write previous layers, read channel data 
1275
  for(i=0; i<numLayers; i++) 
1276
  {
1277
      WRITELONG( nRect[i].top    );           // Layer top 
1278
      WRITELONG( nRect[i].left   );           // Layer left
1279
      WRITELONG( nRect[i].bottom );           // Layer bottom 
1280
      WRITELONG( nRect[i].right  );           // Layer right 
1281
1282
      WRITESHORT( nchannel[i] );      // The number of channels in the layer.
1283
1284
      // ********** Channel information ***************************** //
1285
      
1286
      WRITESHORT( 0 );                    // red
1287
      WRITELONG( chlength[i] );           // Length of following channel data.
1288
      WRITESHORT( 1 );                    // green
1289
      WRITELONG( chlength[i] );           // Length of following channel data.
1290
      WRITESHORT( 2 );                    // blue
1291
      WRITELONG( chlength[i] );           // Length of following channel data.
1292
      if( nchannel[i] > 3 ) // alpha channel
1293
      {
1294
          WRITESHORT( -2);                // transparency mask
1295
          WRITELONG( chlength[i] );       // Length of following channel data.
1296
      }
1297
      // ********** End Channel information ***************************** //
1298
  
1299
      WRITELONG( '8BIM'); // Blend mode signature Always 8BIM.
1300
      WRITELONG( 'norm'); // Blend mode key
1301
1302
      WRITEUCHAR(255); // 1 byte Opacity 0 = transparent ... 255 = opaque
1303
      WRITEUCHAR( 0 ); // 1 byte Clipping 0 = base, 1 = non–base
1304
      WRITEUCHAR( 1 ); // 1 byte Flags bit 0 = transparency protected bit 1 = visible
1305
      WRITEUCHAR( 0 ); // 1 byte (filler) (zero)
1306
1307
      WRITELONG( 12);     // Extra data size Length of the extra data field. This is the
1308
      WRITELONG( 0 );     // Layer Mask data
1309
      WRITELONG( 0 );     // Layer blending ranges
1310
1311
      WRITELONG( cnames[i] );     // Layer name
1312
      
1313
      //printf("Writing layer %d: top %d, left %d, bottom %d, right %d, size %d\n", i, 
1314
      //nRect[i].top, nRect[i].left, nRect[i].bottom, nRect[i].right, chlength[i]);
1315
  }
1316
  // ************** The New Layer ************************************ //
1317
  // ********** Layer Structure ********************************* //  
1318
1319
      //printf("Adding layer : top %d, left %d, bottom %d, right %d, size %d\n",  
1320
      //theRect.top, theRect.left, theRect.bottom, theRect.right, channelLength);
1321
1322
1323
  WRITELONG( theRect.top );                   // Layer top 
1324
  WRITELONG( theRect.left );                  // Layer left
1325
  WRITELONG( theRect.bottom ) ;               // Layer bottom 
1326
  WRITELONG( theRect.right  ) ;               // Layer right 
1327
1328
  if( alpha!= NULL )
1329
  {
1330
      WRITESHORT( channels);//+1 ); // The number of channels in the layer.
1331
  }
1332
  else
1333
  {
1334
      WRITESHORT( channels ); // The number of channels in the layer.
1335
  }   
1336
1337
  // ********** Channel information ***************************** //
1338
      
1339
  WRITESHORT( 0 );            // red
1340
  WRITELONG( channelLength )  // Length of following channel data.
1341
  WRITESHORT( 1 );            // green
1342
  WRITELONG( channelLength )  // Length of following channel data.
1343
  WRITESHORT( 2 );            // blue
1344
  WRITELONG( channelLength )  // Length of following channel data.
1345
  if( bpp == 4 ) // alpha channel
1346
  {
1347
      WRITESHORT( -2 ); //2 );        // transparency mask
1348
      WRITELONG( channelLength )  // Length of following channel data.
1349
  }
1350
1351
  // ********** End Channel information ***************************** //
1352
  
1353
  WRITELONG( '8BIM'); // Blend mode signature Always 8BIM.
1354
  WRITELONG( 'norm'); // Blend mode key
1355
1356
  WRITEUCHAR(255); // 1 byte Opacity 0 = transparent ... 255 = opaque
1357
  WRITEUCHAR( 0 ); // 1 byte Clipping 0 = base, 1 = non–base
1358
  WRITEUCHAR( 1 ); // 1 byte Flags bit 0 = transparency protected bit 1 = visible
1359
  WRITEUCHAR( 0 ); // 1 byte (filler) (zero)
1360
1361
  WRITELONG( 12);     // Extra data size Length of the extra data field. This is the
1362
  WRITELONG( 0 );     // Layer Mask data
1363
  WRITELONG( 0 );     // Layer blending ranges
1364
  
1365
  sprintf(&(data[1]), "L%02d", numLayers+1 ); data[0] = 3;
1366
  count = 4; 
1367
  mywrite( fnum, count, data ); // Layer Name
1368
  
1369
  
1370
  // ************* End Layer Structure ******************************* //
1371
1372
  // ************* Write Channel Image data ************************** //
1373
1374
  for( i=0; i< numLayers; i++)
1375
  {
1376
      buf = (unsigned char**) mymalloc( chlength[i] );
1377
      if( buf == NULL )
1378
      {
1379
          PrintError("Not enough memory, %d bytes needed", (int)chlength[i]);
1380
          result = -1;
1381
          goto _addLayer_exit;
1382
      }
1383
      for( k=0; k< nchannel[i]; k++ )
1384
      {
1385
          fileCopy( src, fnum, chlength[i], *buf );
1386
          //printf("Compression Layer %d Channel %d: %d\n", i,k,(int)*((short*)*buf));
1387
          
1388
          if( k == 3) // found an alpha channel
1389
          {
1390
              if( alpha!= NULL )
1391
              {
1392
                  orAlpha( *alpha, &((*buf)[2]), im, &(nRect[i]) );
1393
              }
1394
          }
1395
      }
1396
      myfree( (void**)buf );
1397
      if( nodd[i] )   // pad byte
1398
      {
1399
          READUCHAR( ch );
1400
          WRITEUCHAR( 0 );
1401
      }
1402
  }
1403
  
1404
  // Write color channels
1405
  for( i=0; i<3; i++)
1406
  {
1407
      if( writeChannelData( im, fnum, i + channels - 3, &theRect ) ) 
1408
      {
1409
          result = -1;
1410
          goto _addLayer_exit;
1411
      }
1412
  }
1413
  
1414
  if( channels > 3 )  // Alpha channel present
1415
  {       
1416
#if 0
1417
      if( writeChannelData( im, fnum, 0, &theRect ) ) 
1418
      {
1419
          result = -1;
1420
          goto _addLayer_exit;
1421
      }
1422
#endif
1423
      if( sB->seam == _middle && alpha != NULL ) // Create stitching mask
1424
      {
1425
          mergeAlpha( im, *alpha, sB->feather, &theRect );
1426
#if 0
1427
          {
1428
              static nim = 0;
1429
              fullPath fp;
1430
              makePathToHost( &fp );
1431
              sprintf( (char*)fp.name, "Test.%d", nim++);
1432
              c2pstr((char*)fp.name);
1433
              mycreate( &fp, '8BIM', '8BPS' );
1434
               writePSD(im, &fp );
1435
          }
1436
#endif
1437
      }
1438
      if( writeChannelData( im, fnum, 0, &theRect ) ) 
1439
      {
1440
          result = -1;
1441
          goto _addLayer_exit;
1442
      }
1443
  }
1444
  if( oddSized )  // pad byte
1445
  {
1446
      WRITEUCHAR( 0 );
1447
  }
1448
      
1449
  // ************* End Write Channel Image data ************************** //
1450
  
1451
  // ************* Global layer mask info ******************************** //
1452
  
1453
  READLONG( var );    WRITELONG(  0 );        // Length of global layer mask info section.
1454
  //READSHORT( svar );    WRITESHORT( 0 );        // 2 bytes Overlay color space
1455
  //READSHORT( svar );    WRITESHORT( 0 );        // 4 * 2 byte color components
1456
  //READSHORT( svar );    WRITESHORT( 0 );        
1457
  //READSHORT( svar );    WRITESHORT( 0 );        
1458
  //READSHORT( svar );    WRITESHORT( 0 );
1459
  //READSHORT( svar );    WRITESHORT( 0 );        // 2 bytes Opacity 0 = transparent, 100 = opaque.
1460
  //READSHORT( svar );    WRITEUCHAR( 128 );      // 1 byte Kind 0=Color selected—i.e. inverted; 
1461
                                              // 1=Color protected;128=use value stored per layer.
1462
                                              //  This value is preferred. The others are for back-ward
1463
                                              // compatibility with beta versions.
1464
                      //WRITEUCHAR( 0 );
1465
  
1466
  
1467
_addLayer_exit:   
1468
  if( alpha       != NULL )   myfree( (void**)alpha );
1469
  if( chlength    != NULL )   free(chlength); 
1470
  if( nchannel    != NULL )   free(nchannel);
1471
  if( nRect       != NULL )   free(nRect);
1472
  if( cnames      != NULL )   free(cnames);
1473
  if( nodd        != NULL )   free(nodd);
1474
1475
  return result;
1476
}
1477
1478
1479
static int fileCopy( file_spec src, file_spec dest, int numBytes, unsigned char *buf )
1480
{
1481
  long count = numBytes;
1482
  
1483
  myread(  src, count, buf );
1484
  mywrite( dest, count, buf );
1485
  return 0;
1486
}
1487
1488
1489
// Or two alpha channels: one in alpha (same size as image im)
1490
// one in buf comprising the rectangle top,bottom,left,right
1491
// store result in alpha
1492
1493
static void orAlpha( unsigned char* alpha, unsigned char *buf, Image *im, PTRect *theRect )
1494
{
1495
  register int x,y,ay,by,w;
1496
  int BitsPerChannel;
1497
  
1498
  GetBitsPerChannel( im, BitsPerChannel );
1499
1500
  if( im->bitsPerPixel != 32 && im->bitsPerPixel != 64) return;
1501
  
1502
  w = (theRect->right - theRect->left);
1503
  
1504
  if( BitsPerChannel == 8 )
1505
  {
1506
      for(y=theRect->top; y<theRect->bottom; y++)
1507
      {
1508
          ay = y * im->width;
1509
          by = (y - theRect->top) * w;
1510
          {
1511
              for(x=theRect->left; x<theRect->right; x++)
1512
              {
1513
                  if( buf[ by + x - theRect->left ] )
1514
                      alpha[ ay + x ] = 255U;
1515
              }
1516
          }
1517
      }
1518
  }
1519
  else // 16
1520
  {
1521
      for(y=theRect->top; y<theRect->bottom; y++)
1522
      {
1523
          ay = y * im->width * 2;
1524
          by = (y - theRect->top) * w * 2;
1525
          {
1526
              for(x=theRect->left; x<theRect->right; x++)
1527
              {
1528
                  if( *((USHORT*)(buf+ by + 2*(x - theRect->left))) )
1529
                      *((USHORT*)(alpha + ay + 2*x) ) = 65535U;
1530
              }
1531
          }
1532
      }
1533
  }
1534
}
1535
1536
1537
1538
void FindScript( aPrefs *thePrefs )
1539
{
1540
  FindFile( &(thePrefs->scriptFile) );
1541
}
1542
1543
int LoadOptions( cPrefs * thePrefs )
1544
{ 
1545
  fullPath path;
1546
  file_spec fnum;
1547
  struct correct_Prefs loadPrefs;
1548
  long    count;
1549
  int result;
1550
  
1551
  if( FindFile( &path ) )
1552
  {
1553
      return -1;
1554
  }
1555
  
1556
  if( myopen( &path, read_bin, fnum ))
1557
  {
1558
      PrintError("Could not open file");
1559
      return -1;
1560
  }
1561
  
1562
  count = sizeof( struct correct_Prefs);
1563
  myread(  fnum, count, &loadPrefs );
1564
1565
  if( count != sizeof( struct correct_Prefs) || loadPrefs.magic != 20 )
1566
  {
1567
      PrintError( "Wrong format!");
1568
      result = -1;
1569
  }
1570
  else
1571
  {
1572
      memcpy((char*) thePrefs, (char*)&loadPrefs, sizeof(struct correct_Prefs));
1573
      result = 0;
1574
  }
1575
  myclose(fnum);
1576
1577
  return result;
1578
}
1579
1580
1581
char* LoadScript( fullPath* scriptFile )
1582
{
1583
  fullPath    sfile;
1584
  int         result = FALSE, i;
1585
  file_spec   fnum;
1586
  long        count;
1587
  char        *script = NULL, ch;
1588
  
1589
  memset( &sfile, 0, sizeof( fullPath ) );
1590
  if( memcmp( scriptFile, &sfile, sizeof( fullPath ) ) == 0 )
1591
  {
1592
      PrintError("No Scriptfile selected");
1593
      goto _loadError;
1594
  }
1595
1596
  if( myopen( scriptFile, read_text, fnum ))
1597
  {
1598
      PrintError("Error Opening Scriptfile");
1599
      goto _loadError;
1600
  }
1601
  
1602
  count = 1; i=0; // Get file length
1603
  
1604
  while( count == 1 )
1605
  {
1606
      myread(  fnum, count, &ch ); 
1607
      if(count==1) i++;
1608
  }
1609
  myclose(fnum);
1610
1611
  count = i;
1612
  script = (char*)malloc( count+1 );
1613
  if( script == NULL )
1614
  {
1615
      PrintError("Not enough memory to load scriptfile");
1616
      goto _loadError;
1617
  }
1618
  if( myopen( scriptFile, read_text, fnum ))
1619
  {
1620
      PrintError("Error Opening Scriptfile");
1621
      goto _loadError;
1622
  }
1623
  
1624
  
1625
  myread(fnum,count,script);
1626
  script[count] = 0;
1627
  myclose(fnum);
1628
  return script;
1629
  
1630
_loadError:
1631
  return (char*)NULL;
1632
}
1633
1634
1635
int WriteScript( char* res, fullPath* scriptFile, int launch )
1636
{
1637
  fullPath    sfile;
1638
  int         result = FALSE;
1639
  file_spec   fnum;
1640
  long        count;
1641
1642
  memset( &sfile, 0, sizeof( fullPath ) );
1643
  if( memcmp( scriptFile, &sfile, sizeof( fullPath ) ) == 0 )
1644
  {
1645
      PrintError("No Scriptfile selected");
1646
      goto _writeError;
1647
  }
1648
1649
  memcpy(  &sfile, scriptFile, sizeof (fullPath) );
1650
  mydelete( &sfile );
1651
  mycreate(&sfile,'ttxt','TEXT');
1652
1653
  if( myopen( &sfile, write_text, fnum ) )
1654
  {
1655
      PrintError("Error Opening Scriptfile");
1656
      goto _writeError;
1657
  }
1658
  
1659
  count = strlen( res );
1660
  mywrite( fnum, count, res );    
1661
  myclose (fnum );
1662
1663
  if( launch == 1 )
1664
  {
1665
      showScript( &sfile);
1666
  }
1667
  return 0;
1668
  
1669
1670
_writeError:
1671
  return -1;
1672
}
1673
1674
1675
void SaveOptions( cPrefs * thePrefs )
1676
{
1677
  fullPath    path;
1678
  file_spec   fspec;
1679
  long        count;
1680
  
1681
  memset( &path, 0, sizeof( fullPath ));
1682
  if( SaveFileAs( &path, "Save Settings as..", "Params" ) )
1683
      return;
1684
      
1685
  mycreate    (&path,'GKON','TEXT');
1686
  
1687
  if( myopen( &path, write_bin, fspec ) )
1688
      return;
1689
  
1690
  count = sizeof( cPrefs );
1691
  mywrite( fspec, count, thePrefs );
1692
  myclose( fspec );
1693
}
1694
1695
1696
1697
// Temporarily save a 32bit image (including Alpha-channel) using name fname
1698
1699
int   SaveBufImage( Image *image, char *fname )
1700
{
1701
  
1702
  fullPath        fspec;
1703
1704
  MakeTempName( &fspec, fname );
1705
1706
1707
  mydelete( &fspec );
1708
  mycreate( &fspec, '8BIM', '8BPS');
1709
  
1710
  return writePSD(image,  &fspec);
1711
}
1712
1713
// Load a saved 32bit image (including Alpha-channel) using name fname
1714
// image must be allocated (not data)
1715
// mode = 0: only load image struct
1716
// mode = 1: also allocate and load data
1717
  
1718
  
1719
int   LoadBufImage( Image *image, char *fname, int mode)
1720
{
1721
  fullPath    fspec;
1722
1723
  MakeTempName( &fspec, fname );
1724
  return readPSD(image, &fspec,  mode);
1725
}
1726
1727
1728
// Read Photoshop Multilayer-image
1729
int readPSDMultiLayerImage( MultiLayerImage *mim, fullPath* sfile){
1730
  file_spec       src;
1731
1732
  char            header[128], *h;
1733
  long            count,chlength;
1734
  unsigned long       var;
1735
  char            data[12], *d;
1736
  short           svar;
1737
  int             i, k, result = 0,nchannel, *nodd = NULL;
1738
  unsigned char       **buf = NULL, ch;
1739
  Image           im;
1740
  int         BitsPerSample = 8;
1741
  
1742
  SetImageDefaults( &im );
1743
1744
  if( myopen( sfile,read_bin, src ) ){    
1745
      PrintError("Error Opening Image File");
1746
      return -1;
1747
  }
1748
      
1749
  // Read psd header
1750
1751
  h   = header;
1752
  count   = PSDHLENGTH;
1753
  myread( src,count,h); 
1754
  if( count != PSDHLENGTH ){
1755
      PrintError("Error Reading Image Header");
1756
      myclose( src );
1757
      return -1;
1758
  }
1759
  
1760
  if( ParsePSDHeader( header, &im ) != 0 ){
1761
      PrintError("Wrong File Format");
1762
      myclose( src );
1763
      return -1;
1764
  }
1765
  
1766
  // Read (and ignore) Color mode data
1767
  READLONG( var ); 
1768
  count = 1;
1769
  for( i=0; i<var; i++ )
1770
  {
1771
      myread(src,count,h);
1772
  }
1773
1774
  // Read (and ingnore) Image resources
1775
  READLONG( var ); 
1776
  count = 1;
1777
  for( i=0; i<var; i++ )
1778
  {
1779
      myread(src,count,h);
1780
  }
1781
1782
  // Read the layers
1783
1784
1785
  // Read layerinfo up to channeldata
1786
  READLONG( var );            // Length of info section(ignored)
1787
  READLONG( var );            // Length of layer info (ignored)
1788
  READSHORT( mim->numLayers );        // Number of layers
1789
  
1790
  mim->Layer  = (Image*)  malloc( mim->numLayers * sizeof( Image ) );
1791
  nodd        = (int*) malloc( mim->numLayers * sizeof( int ));
1792
  
1793
  if( mim->Layer == NULL || nodd == NULL) 
1794
  {
1795
      PrintError("Not enough memory");
1796
      result = -1;
1797
      goto readPSDMultiLayerImage_exit;
1798
  }
1799
  for(i=0; i<mim->numLayers; i++) 
1800
  {
1801
      SetImageDefaults( &mim->Layer[i] );
1802
      mim->Layer[i].width  = im.width;
1803
      mim->Layer[i].height = im.height;
1804
      READLONG( mim->Layer[i].selection.top ) ;  // Layer top 
1805
      READLONG( mim->Layer[i].selection.left  ); // Layer left
1806
      READLONG( mim->Layer[i].selection.bottom); // Layer bottom 
1807
      READLONG( mim->Layer[i].selection.right ); // Layer right 
1808
      
1809
      READSHORT( nchannel );                              // The number of channels in the layer.
1810
      mim->Layer[i].bitsPerPixel = nchannel * BitsPerSample;
1811
1812
      mim->Layer[i].bytesPerLine = (mim->Layer[i].selection.right - mim->Layer[i].selection.left) *
1813
                      mim->Layer[i].bitsPerPixel/8;
1814
      mim->Layer[i].dataSize = mim->Layer[i].bytesPerLine * 
1815
                   (mim->Layer[i].selection.bottom - mim->Layer[i].selection.top);
1816
      mim->Layer[i].data = (unsigned char**) mymalloc(mim->Layer[i].dataSize);
1817
      if( mim->Layer[i].data == NULL )
1818
      {
1819
          PrintError("Not enough memory");
1820
          result = -1;
1821
          goto readPSDMultiLayerImage_exit;
1822
      }
1823
      
1824
      
1825
      // ********** Channel information ***************************** //
1826
      
1827
      READSHORT( svar ); // red
1828
      READLONG(chlength);// Length of following channel data.
1829
      READSHORT( svar ); // green
1830
      READLONG(var);     // Length of following channel data.
1831
      READSHORT( svar ); // blue
1832
      READLONG(var);     // Length of following channel data.
1833
      if( mim->Layer[i].bitsPerPixel == 32 || mim->Layer[i].bitsPerPixel == 64) // alpha channel
1834
      {
1835
          READSHORT( svar );      // transparency mask
1836
          READLONG( var);         // Length of following channel data.
1837
      }
1838
      // ********** End Channel information ***************************** //
1839
  
1840
      READLONG( var );                     // Blend mode signature Always 8BIM.
1841
      READLONG( var );                     // Blend mode key
1842
1843
      READLONG( var );                    // Four flag bytes
1844
1845
      READLONG( var );                    // Extra data size Length of the extra data field. This is the
1846
      READLONG( var );                    // Layer Mask data
1847
      READLONG( var );                    // Layer blending ranges
1848
1849
      READLONG( var );                // Layer name
1850
      
1851
      var = 4*4 + 2 + nchannel * 6 + 4 + 4 + 4 * 1 + 4 + 12 + nchannel * chlength; // length
1852
      if( var/2 != (var+1)/2 ) // odd
1853
      {
1854
          nodd[i] = 1; 
1855
          //READUCHAR( ch );
1856
      }
1857
      else
1858
      {
1859
          nodd[i] = 0;
1860
      }
1861
  }
1862
  
1863
  
1864
  // ************* End Layer Structure ******************************* //
1865
1866
  // ************* Read Channel Image data ************************** //
1867
1868
  for( i=0; i< mim->numLayers; i++)
1869
  {
1870
      nchannel    = mim->Layer[i].bitsPerPixel/BitsPerSample;
1871
      chlength    = mim->Layer[i].dataSize/ nchannel;
1872
      buf = (unsigned char**) mymalloc( chlength );
1873
      if( buf == NULL )
1874
      {
1875
          PrintError("Not enough memory");
1876
          result = -1;
1877
          goto readPSDMultiLayerImage_exit;
1878
      }
1879
      for( k=0; k< nchannel; k++ )
1880
      {
1881
          READSHORT( svar );
1882
          if( svar != 0 )
1883
          {
1884
              PrintError("File format error");
1885
              result = -1;
1886
              goto readPSDMultiLayerImage_exit; 
1887
          }
1888
          count = chlength;
1889
          myread(  src, count, *buf );
1890
          {
1891
              register int x,y,cy,by;
1892
              register unsigned char* theData = *(mim->Layer[i].data);
1893
              int offset,bpp;
1894
              
1895
              offset = (mim->Layer[i].bitsPerPixel == 32?1:0) + k;
1896
              if( k==3 ) offset = 0;
1897
              
1898
              bpp = mim->Layer[i].bitsPerPixel/8;
1899
          
1900
              for(y=0; y<mim->Layer[i].height; y++)
1901
              {
1902
                  cy = y*mim->Layer[i].bytesPerLine + offset;
1903
                  by = y*mim->Layer[i].width;
1904
                  for(x=0; x<mim->Layer[i].width; x++)
1905
                  {
1906
                      theData[cy + bpp*x] = (*buf)[by + x];
1907
                  }
1908
              }
1909
          }
1910
      }
1911
      myfree( (void**)buf );
1912
      if( nodd[i] )   // pad byte
1913
      {
1914
          READUCHAR( ch );
1915
      }
1916
  }
1917
  
1918
1919
readPSDMultiLayerImage_exit:
1920
1921
  if( nodd != NULL )              free( nodd );
1922
1923
  myclose( src );
1924
  return result;
1925
}
1926
1927
1928
1929
  
1930
1931
1932
1933