~ubuntu-branches/debian/jessie/eso-midas/jessie

« back to all changes in this revision

Viewing changes to libsrc/idi/cidi/x11/idilocal4.c

  • Committer: Package Import Robot
  • Author(s): Ole Streicher
  • Date: 2014-04-22 14:44:58 UTC
  • Revision ID: package-import@ubuntu.com-20140422144458-okiwi1assxkkiz39
Tags: upstream-13.09pl1.2+dfsg
ImportĀ upstreamĀ versionĀ 13.09pl1.2+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*===========================================================================
 
2
  Copyright (C) 2000 Craig B. Markwardt
 
3
 
 
4
  This program is free software; you can redistribute it and/or 
 
5
  modify it under the terms of the GNU General Public License as 
 
6
  published by the Free Software Foundation; either version 2 of 
 
7
  the License, or (at your option) 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 
 
15
  License along with this program; if not, write to the Free 
 
16
  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, 
 
17
  MA 02139, USA.
 
18
 
 
19
  Correspondence concerning ESO-MIDAS should be addressed as follows:
 
20
        Internet e-mail: midas@eso.org
 
21
        Postal address: European Southern Observatory
 
22
                        Data Management Division 
 
23
                        Karl-Schwarzschild-Strasse 2
 
24
                        D 85748 Garching bei Muenchen 
 
25
                        GERMANY
 
26
===========================================================================*/
 
27
 
 
28
/***********************************************************************
 
29
*                                                               
 
30
*   file idilocal4.c
 
31
*                                                                 
 
32
*   IDI  Device Dependent Routines                                 
 
33
*   (version for XWindows release 11)                               
 
34
*                                                                    
 
35
*
 
36
* V 1.00 001129: C. Markwardt - conversions for 24- and 16-bit visuals
 
37
*
 
38
*   get_plane_offset     : convert bitmask to a shift offset
 
39
*   idi_conv32_24        : convert 32-bit RGB to 24-bit RGB
 
40
*   idi_conv24_32        : convert 24-bit RGB to 32-bit RGB
 
41
*   idi_conv32_16        : convert 32-bit RGB to 16-bit RGB
 
42
*   idi_conv16_32        : convert 16-bit RGB to 32-bit RGB
 
43
*   idi_order32          : reorder 32-bit RGB
 
44
*   idi_putimage         : wrapper for XPutImage
 
45
*   idi_getsubimage      : wrapper for XGetSubImage
 
46
*   test_swap            : check, if byte swap is needed
 
47
    
 
48
 090120         last modif
 
49
 
 
50
************************************************************************/
 
51
 
 
52
/*
 
53
 
 
54
*/
 
55
 
 
56
#include    <stdlib.h>
 
57
 
 
58
#include    <idi.h>
 
59
#include    <idistruct.h>
 
60
#include    <x11defs.h>
 
61
#include    <proto_idi.h>
 
62
 
 
63
 
 
64
/* Determine the shift to apply to 8-bit data to align with "mask" */
 
65
int
 
66
get_plane_offset(mask, wordsize)
 
67
     unsigned int mask, wordsize;
 
68
{
 
69
  int i;
 
70
  for (i=31; i>=0; i--)
 
71
    if ( (mask>>i) & 1 ) return (i+1-wordsize);
 
72
  return 0;
 
73
}
 
74
/*
 
75
 
 
76
*/
 
77
 
 
78
/* Convert 32-bit input to 24-bit output.  The image data sizes are
 
79
   the same, hence each line output line will be padded by 25%.  Note
 
80
   that this function allocates memory which must be freed by the
 
81
   caller. */
 
82
 
 
83
unsigned char *idi_conv32_24(image, src)
 
84
XImage *image;
 
85
unsigned char *src;
 
86
 
 
87
{
 
88
  unsigned char *dst, *p, *q;
 
89
  unsigned int nbytes;
 
90
  unsigned int test = 0x000000ff;
 
91
  unsigned char *ptest = (unsigned char *)&test;
 
92
  int lend;
 
93
  int j, i;
 
94
 
 
95
  if ( *ptest == 0xff ) lend = 1; else lend = 0;
 
96
 
 
97
  /* Allocate a destination image */
 
98
  nbytes = image->bytes_per_line*image->height;
 
99
  dst = malloc((size_t)nbytes);
 
100
  if (dst == 0) 
 
101
    return 0;
 
102
 
 
103
  /* Zero the new image data */
 
104
  q = dst;
 
105
  for (i=0; i<nbytes; i++) 
 
106
    *q++ = 0;
 
107
  
 
108
  for (j=0; j<image->height; j++) {
 
109
    p = src + image->bytes_per_line*j;
 
110
    q = dst + image->bytes_per_line*j;
 
111
    /* Note that for 24-bit data, all we have to do is copy the 3
 
112
       lsb's and discard the msb, while otherwise preserving the byte
 
113
       order. */
 
114
    if (lend) {
 
115
      /* Little-endian - discard msb at end of each source word */
 
116
      for (i=0; i<image->width; i++) {
 
117
        *q++ = *p++;   *q++ = *p++;   *q++ = *p++;
 
118
        p++;
 
119
      } 
 
120
    } else {
 
121
      /* Big-endian - discard msb at beginning of each source word */
 
122
      for (i=0; i<image->width; i++) {
 
123
        p++;
 
124
        *q++ = *p++;   *q++ = *p++;   *q++ = *p++;
 
125
      } 
 
126
    }
 
127
  }
 
128
 
 
129
  return dst;
 
130
}
 
131
/*
 
132
 
 
133
*/
 
134
 
 
135
/* Convert 24-bit input to 32-bit output.  The image data sizes are
 
136
   the same, hence each input line must be padded by 25%.  Note that
 
137
   this function allocates memory which must be freed by the
 
138
   caller. */
 
139
 
 
140
unsigned char *idi_conv24_32(image, src)
 
141
XImage *image;
 
142
unsigned char *src;
 
143
 
 
144
{
 
145
  unsigned char *dst, *p, *q;
 
146
  unsigned int nbytes;
 
147
  unsigned int test = 0x000000ff;
 
148
  unsigned char *ptest = (unsigned char *)&test;
 
149
  int lend;
 
150
  int j, i;
 
151
 
 
152
  /* Test for endian-ness */
 
153
  if ( *ptest == 0xff ) lend = 1; else lend = 0;
 
154
#if 0
 
155
  fprintf(stderr, "%s-endian\n", lend?"little":"big");
 
156
  fprintf(stderr, "red_mask   = 0x%08x\n", image->red_mask);
 
157
  fprintf(stderr, "green_mask = 0x%08x\n", image->green_mask);
 
158
  fprintf(stderr, "blue_mask  = 0x%08x\n", image->blue_mask);
 
159
#endif
 
160
 
 
161
  /* Allocate a destination image */
 
162
  nbytes = image->bytes_per_line*image->height;
 
163
  dst = malloc((size_t)nbytes);
 
164
  if (dst == 0) 
 
165
    return 0;
 
166
  
 
167
  /* Zero the new image data */
 
168
  q = dst;
 
169
  for (i=0; i<nbytes; i++) 
 
170
    *q++ = 0;
 
171
  
 
172
  for (j=0; j<image->height; j++) {
 
173
    p = src + image->bytes_per_line*j;
 
174
    q = dst + image->bytes_per_line*j;
 
175
    /* Note that for 24-bit data, all we have to do is copy the 3
 
176
       lsb's and discard the msb, while otherwise preserving the byte
 
177
       order. */
 
178
    if (lend > 0) {
 
179
      /* Little-endian - insert msb at end of each dest word */
 
180
      for (i=0; i<image->width; i++) {
 
181
        *q++ = *p++;   *q++ = *p++;   *q++ = *p++;
 
182
        q++;
 
183
      } 
 
184
    } else {
 
185
      /* Big-endian - insert msb at beginning of each dest word */
 
186
      for (i=0; i<image->width; i++) {
 
187
        q++;
 
188
        *q++ = *p++;   *q++ = *p++;   *q++ = *p++;
 
189
      } 
 
190
    }
 
191
  }
 
192
 
 
193
  return dst;
 
194
}
 
195
/*
 
196
 
 
197
*/
 
198
 
 
199
/* Convert 32-bit input to 16-bit output.
 
200
   The main work is now done in function `wr_lut', here we just
 
201
   convert from unsignded int (4 bytes) to unsigned short int (2 bytes). */
 
202
 
 
203
unsigned char *idi_conv32_16(image, src, wordsize)
 
204
XImage *image;
 
205
unsigned char *src;
 
206
unsigned int wordsize;
 
207
 
 
208
{
 
209
unsigned char *dst, *p, *q;
 
210
unsigned short int *qi;
 
211
unsigned int *pi;
 
212
unsigned int word, nbytes;
 
213
int j, i;
 
214
 
 
215
 
 
216
/* allocate a destination image */
 
217
 
 
218
nbytes = image->bytes_per_line*image->height;
 
219
dst = malloc((size_t)nbytes);
 
220
if (dst == (unsigned char *) 0) return 0;
 
221
 
 
222
 
 
223
/* copy/convert from source to dest. image */
 
224
 
 
225
p = src;
 
226
q = dst;
 
227
 
 
228
for (j=0; j<image->height; j++)
 
229
   {
 
230
   pi = (unsigned int *) p;
 
231
   qi = (unsigned short int *) q;
 
232
 
 
233
   for (i=0; i<image->width; i++)
 
234
      {
 
235
      word = *pi++;
 
236
      *qi++ = (unsigned short int) word;
 
237
      }
 
238
   p += image->bytes_per_line;
 
239
   q += image->bytes_per_line;
 
240
   }
 
241
 
 
242
return dst;
 
243
}
 
244
/*
 
245
 
 
246
*/
 
247
 
 
248
/* Convert 16-bit input to 32-bit output.  The image data sizes are
 
249
   the same, hence each input line must be padded by 50%.  Note that
 
250
   this function allocates memory which must be freed by the
 
251
   caller. Also, the conversion from 16-bit to 24-bit assumes that the
 
252
   low-order bits are zero. */
 
253
 
 
254
unsigned char *idi_conv16_32(image, src, wordsize)
 
255
XImage *image;
 
256
unsigned char *src;
 
257
unsigned int wordsize;
 
258
 
 
259
{
 
260
  unsigned char *dst, *p, *q;
 
261
  unsigned short int *pi;
 
262
  unsigned int *qi;
 
263
  unsigned int nbytes;
 
264
  unsigned char r, g, b;
 
265
  unsigned int rm, gm, bm;   /* Red green and blue masks */
 
266
  unsigned int ro, go, bo;   /* Red green and blue mask offsets */
 
267
  unsigned short int word;
 
268
  int j, i;
 
269
 
 
270
  rm = image->red_mask;
 
271
  gm = image->green_mask;
 
272
  bm = image->blue_mask;
 
273
  ro = get_plane_offset(rm, wordsize);
 
274
  go = get_plane_offset(gm, wordsize);
 
275
  bo = get_plane_offset(bm, wordsize);
 
276
  if (ro < 0 || go < 0 || bo < 0) 
 
277
    return 0;
 
278
 
 
279
  /* Allocate a destination image */
 
280
  nbytes = image->bytes_per_line*image->height;
 
281
  dst = malloc((size_t)nbytes);
 
282
  if (dst == 0) 
 
283
    return 0;
 
284
  
 
285
  for (i=0, q=dst; i<nbytes; i++) 
 
286
    *q++ = 0;
 
287
  
 
288
  for (j=0; j<image->height; j++) {
 
289
    p = src + image->bytes_per_line*j;
 
290
    q = dst + image->bytes_per_line*j;
 
291
    pi = (unsigned short int *) p;
 
292
    qi = (unsigned int *) q;
 
293
    /* Note that for 16-bit input data the red element in the 24-bit
 
294
       output data will always be in the LSB, given the way that
 
295
       RGBord is constructed */
 
296
    if (ro > 0) {
 
297
      /* bo must be negative */
 
298
      for (i=0; i<image->width; i++) {
 
299
        word = *pi++;
 
300
        r = (word & rm) >>  ro;
 
301
        g = (word & gm) >>  go;
 
302
        b = (word & bm) << -bo;
 
303
        *qi++ = r | (g << 8) | (b << 16);
 
304
      } 
 
305
    } else {
 
306
      /* ro must be negative */
 
307
      for (i=0; i<image->width; i++) {
 
308
        word = *pi++;
 
309
        r = (word & rm) <<  -ro;
 
310
        g = (word & gm) >>  go;
 
311
        b = (word & bm) >>  bo;
 
312
        *qi++ = r | (g << 8) | (b << 16);
 
313
      }
 
314
    }
 
315
  }
 
316
 
 
317
  return dst;
 
318
}
 
319
/*
 
320
 
 
321
*/
 
322
 
 
323
/* Wrapper for XPutImage.  The arguments are identical.  This function
 
324
   takes an XImage either in 32-bit truecolor or 8-bit pseudocolor and
 
325
   converts to the appropriate bitsize and depth of the output
 
326
   drawable. No error checking is done on the arguments. */
 
327
 
 
328
void idi_putimage(display, draw, gc, image, sx, sy, dx, dy, width, height)
 
329
Display *display;
 
330
Drawable draw;
 
331
GC gc;
 
332
XImage *image;
 
333
int sx, sy, dx, dy;
 
334
unsigned int width, height;
 
335
 
 
336
{
 
337
  unsigned char *dst = 0;
 
338
  unsigned char *src = (unsigned char *)image->data;
 
339
  int wordsize = 8;
 
340
 
 
341
  /* Convert from a standard size, either 8-bit or 32-bit, to the
 
342
     native pixel size */
 
343
  switch (image->bits_per_pixel) {
 
344
    /* 32-bit true-color, and 8-bit pseudo color are output immediately */
 
345
  case 8:
 
346
  case 32:
 
347
    break;
 
348
  case 16:
 
349
    dst = idi_conv32_16(image, src, wordsize);  /* 32 bits to 16 bits */
 
350
    break;
 
351
  case 24:
 
352
    dst = idi_conv32_24(image, src);            /* 32 bits to 24 bits */
 
353
    break;
 
354
  }
 
355
 
 
356
  /* Temporarily insert the transformed data into the XImage, Put the
 
357
     image, and then restore the original data */
 
358
  if (dst) image->data = (char *) dst;
 
359
  XPutImage(display, draw, gc, image, sx, sy, dx, dy, width, height);
 
360
  image->data = (char *) src;
 
361
  
 
362
  if (dst) free(dst);
 
363
  return;
 
364
}
 
365
 
 
366
/*
 
367
 
 
368
*/
 
369
 
 
370
void idi_order32(no,image, src)
 
371
int  no;
 
372
XImage *image;
 
373
unsigned char *src;
 
374
 
 
375
{
 
376
int  i, ii, j, ioff;
 
377
 
 
378
register unsigned char  *p, *q, rr, gg, bb;
 
379
 
 
380
 
 
381
 
 
382
ii = image->bytes_per_line;
 
383
ioff = 0;
 
384
 
 
385
 
 
386
/* work on RGBord = 1 */
 
387
 
 
388
if (Xworkst[no].flag24[2] == 1)         /* special swap flag */
 
389
   {
 
390
   for (j=0; j<image->height; j++)
 
391
      {
 
392
      p = q = src + ioff;
 
393
 
 
394
      for (i=0; i<image->width; i++)
 
395
         {
 
396
         rr = *p++;
 
397
         gg = *p++;
 
398
         bb = *p++;
 
399
         p++;
 
400
 
 
401
         *q++ = bb;
 
402
         *q++ = gg;
 
403
         *q++ = rr;
 
404
         q++;
 
405
         }
 
406
 
 
407
      ioff += ii;
 
408
      }
 
409
   }
 
410
 
 
411
else
 
412
   {
 
413
   for (j=0; j<image->height; j++)
 
414
      {
 
415
      p = q = src + ioff;
 
416
 
 
417
      for (i=0; i<image->width; i++)
 
418
         {
 
419
         p++;
 
420
         rr = *p++;
 
421
         gg = *p++;
 
422
         bb = *p++;
 
423
 
 
424
         q++;
 
425
         *q++ = bb;
 
426
         *q++ = gg;
 
427
         *q++ = rr;
 
428
         }
 
429
 
 
430
      ioff += ii;
 
431
      }
 
432
   }
 
433
}
 
434
/*
 
435
 
 
436
*/
 
437
 
 
438
/* Wrapper for XGetSubImage.  The arguments are identical.  This
 
439
   function reads an XImage from the drawable, in the native bitsize
 
440
   and depth of the drawable, and then converts to either an 8-bit
 
441
   pseudocolor or 32-bit RGB image.  No error checking is done on the
 
442
   arguments. */
 
443
 
 
444
XImage 
 
445
*idi_getsubimage(display,draw,x,y,width,height,plane_mask,format,dimage,no)
 
446
Display *display;
 
447
Drawable draw;
 
448
int x, y;
 
449
unsigned int width, height;
 
450
unsigned long plane_mask;
 
451
int format;
 
452
XImage *dimage;
 
453
int no;
 
454
 
 
455
{
 
456
XImage *image;
 
457
 
 
458
unsigned char *dst;
 
459
 
 
460
 
 
461
 
 
462
/* Do the actual XGetSubImage, which will return in the native
 
463
   depth and bit_per_pixel of the drawable */
 
464
 
 
465
image =
 
466
   XGetSubImage(display,draw,x,y,width,height,plane_mask,format,dimage,0,0);
 
467
 
 
468
 
 
469
/* Convert to a standard size, either 8-bit or 32-bit */
 
470
switch (image->bits_per_pixel) 
 
471
   {
 
472
  case 16:                              /* 16 bits to 32 bits */
 
473
   dst = idi_conv16_32(image,(unsigned char *) image->data, 8);
 
474
   break;                               /* wordsize = 8 */
 
475
 
 
476
  case 24:                              /* 24 bits to 32 bits */
 
477
   dst = idi_conv24_32(image,(unsigned char *) image->data); 
 
478
   break;
 
479
 
 
480
  case 8:                               /* 8-bit pseudo color, nothing to do */
 
481
   return image;
 
482
 
 
483
  case 32:                              /* 32-bit true-color, reorder */
 
484
   if (Xworkst[no].RGBord == 1)
 
485
      idi_order32(no,image,(unsigned char *) image->data);
 
486
   return image;
 
487
 
 
488
  default:
 
489
   return image;
 
490
  }
 
491
 
 
492
/* Now copy the "destination" image back into the original "source" */
 
493
    
 
494
if (dst != (unsigned char *)0) 
 
495
   {
 
496
   unsigned int nbytes, i;
 
497
   register unsigned char *p, *q;
 
498
 
 
499
   nbytes = image->bytes_per_line * image->height;
 
500
   p = dst; 
 
501
   q = (unsigned char *) image->data;
 
502
   for (i=0; i<nbytes; i++) *q++ = *p++;
 
503
 
 
504
   free(dst);
 
505
   }
 
506
 
 
507
return image;
 
508
}
 
509
/*
 
510
 
 
511
*/
 
512
 
 
513
/* test_swap returns 1, if byte swapping needed, else 0 */
 
514
 
 
515
int test_swap(dspno)
 
516
int  dspno;
 
517
                                /* `test_swap()' is copied from Xtest.c */
 
518
{
 
519
int   nn, mm;
 
520
int  *endian;
 
521
unsigned char hilo[4];
 
522
 
 
523
 
 
524
 
 
525
/* find byte order at Xhost */
 
526
 
 
527
nn = XImageByteOrder(mydisp[ididev[dspno].screen]);
 
528
if (nn == LSBFirst)
 
529
   nn = 0;                              /* least signif. byte first */
 
530
else
 
531
   nn = 1;                              /* most signif. byte first */
 
532
 
 
533
 
 
534
/* get byte order locally */
 
535
 
 
536
endian = (int *) &hilo[0];
 
537
*endian = 0x1256abef;
 
538
if (hilo[0] == 0x12)
 
539
 
 
540
   /* the most significant byte (0x12) is stored first,
 
541
      we have a big-endian architecture */
 
542
   mm = 1;
 
543
 
 
544
else
 
545
 
 
546
   /* the most significant byte (0x12) is stored last,
 
547
      we have a little-endian architecture */
 
548
   mm = 0;
 
549
 
 
550
 
 
551
if (mm == nn)
 
552
   return 0;
 
553
else
 
554
   return 1;
 
555
}
 
556