~ubuntu-branches/ubuntu/dapper/tiff/dapper-updates

« back to all changes in this revision

Viewing changes to contrib/win_dib/tiff2dib.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2005-11-09 18:21:15 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20051109182115-v0fd3zcbrq2sq6u4
Tags: 3.7.4-1ubuntu1
* Synchronize to Debian.
* Only change left: xlibmesa-gl-dev -> libgl1-mesa-dev build dependency
  change.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*************************************************************************
2
 
 *
3
 
 * Source file for Windows 95/Win32. 
4
 
 *
5
 
 * The function LoadTIFFinDIB in this source file let you load 
6
 
 * a TIFF file and build a memory DIB with it and return the 
7
 
 * HANDLE (HDIB) of the memory bloc containing the DIB.
8
 
 *
9
 
 *  Example : 
10
 
 * 
11
 
 *   HDIB   hDIB;
12
 
 *   hDIB = LoadTIFFinDIB("sample.tif");
13
 
 *
14
 
 *
15
 
 * To build this source file you must include the TIFF library   
16
 
 * in your project.
17
 
 *
18
 
 * 4/12/95   Philippe Tenenhaus   100423.3705@compuserve.com
19
 
 *
20
 
 ************************************************************************/
21
 
 
22
 
 
23
 
#include "tiffio.h" 
24
 
 
25
 
#define HDIB HANDLE
26
 
#define IS_WIN30_DIB(lpbi)  ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))
27
 
#define CVT(x)      (((x) * 255L) / ((1L<<16)-1))
28
 
 
29
 
static HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount);
30
 
static LPSTR FindDIBBits(LPSTR lpDIB);
31
 
static WORD PaletteSize(LPSTR lpDIB);
32
 
static WORD DIBNumColors(LPSTR lpDIB);
33
 
static int checkcmap(int n, uint16* r, uint16* g, uint16* b);
34
 
 
35
 
 
36
 
 
37
 
/*************************************************************************
38
 
 *
39
 
 * HDIB LoadTIFFinDIB(LPSTR lpFileName) 
40
 
 *
41
 
 * Parameter:
42
 
 *
43
 
 * LPSTR lpDIB      - File name of a tiff imag
44
 
 *
45
 
 * Return Value:
46
 
 *
47
 
 * LPSTR            - HANDLE of a DIB
48
 
 *
49
 
 * Description:
50
 
 *
51
 
 * This function load a TIFF file and build a memory DIB with it
52
 
 * and return the HANDLE (HDIB) of the memory bloc containing
53
 
 * the DIB.
54
 
 *
55
 
 * 4/12/95   Philippe Tenenhaus   100423.3705@compuserve.com
56
 
 *
57
 
 ************************************************************************/
58
 
 
59
 
HDIB LoadTIFFinDIB(LPSTR lpFileName)    
60
 
{
61
 
    TIFF          *tif;
62
 
    unsigned long imageLength; 
63
 
    unsigned long imageWidth; 
64
 
    unsigned int  BitsPerSample;
65
 
    unsigned long LineSize;
66
 
    unsigned int  SamplePerPixel;
67
 
    unsigned long RowsPerStrip;  
68
 
    int           PhotometricInterpretation;
69
 
    long          nrow;
70
 
        unsigned long row;
71
 
    char          *buf;          
72
 
    LPBITMAPINFOHEADER lpDIB; 
73
 
    HDIB          hDIB;
74
 
    char          *lpBits;
75
 
    HGLOBAL       hStrip;
76
 
    int           i,l;
77
 
    int           Align; 
78
 
    
79
 
    tif = TIFFOpen(lpFileName, "r");
80
 
    
81
 
    if (!tif)
82
 
        goto TiffOpenError;
83
 
    
84
 
    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
85
 
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength);  
86
 
    TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
87
 
    TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);  
88
 
    TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);   
89
 
    TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation);
90
 
           
91
 
    LineSize = TIFFScanlineSize(tif); //Number of byte in ine line
92
 
 
93
 
    SamplePerPixel = (int) (LineSize/imageWidth);
94
 
 
95
 
    //Align = Number of byte to add at the end of each line of the DIB
96
 
    Align = 4 - (LineSize % 4);
97
 
    if (Align == 4)     Align = 0;
98
 
 
99
 
    
100
 
    //Create a new DIB
101
 
    hDIB = CreateDIB((DWORD) imageWidth, (DWORD) imageLength, (WORD)
102
 
(BitsPerSample*SamplePerPixel));
103
 
    lpDIB  = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
104
 
    if (!lpDIB)
105
 
          goto OutOfDIBMemory;
106
 
          
107
 
    if (lpDIB)
108
 
       lpBits = FindDIBBits((LPSTR) lpDIB);
109
 
 
110
 
    //In the tiff file the lines are save from up to down 
111
 
        //In a DIB the lines must be save from down to up
112
 
    if (lpBits)
113
 
      {
114
 
        lpBits = FindDIBBits((LPSTR) lpDIB);
115
 
        lpBits+=((imageWidth*SamplePerPixel)+Align)*(imageLength-1);
116
 
                //now lpBits pointe on the bottom line
117
 
        
118
 
        hStrip = GlobalAlloc(GHND,TIFFStripSize(tif));
119
 
        buf = GlobalLock(hStrip);           
120
 
        
121
 
        if (!buf)
122
 
           goto OutOfBufMemory;
123
 
        
124
 
        //PhotometricInterpretation = 2 image is RGB
125
 
        //PhotometricInterpretation = 3 image have a color palette              
126
 
        if (PhotometricInterpretation == 3)
127
 
        {
128
 
          uint16* red;
129
 
          uint16* green;
130
 
          uint16* blue;
131
 
          int16 i;
132
 
          LPBITMAPINFO lpbmi;   
133
 
          int   Palette16Bits;          
134
 
           
135
 
          TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue); 
136
 
 
137
 
                  //Is the palette 16 or 8 bits ?
138
 
          if (checkcmap(1<<BitsPerSample, red, green, blue) == 16) 
139
 
             Palette16Bits = TRUE;
140
 
          else
141
 
             Palette16Bits = FALSE;
142
 
             
143
 
          lpbmi = (LPBITMAPINFO)lpDIB;                      
144
 
                
145
 
          //load the palette in the DIB
146
 
          for (i = (1<<BitsPerSample)-1; i >= 0; i--) 
147
 
            {             
148
 
             if (Palette16Bits)
149
 
                {
150
 
                  lpbmi->bmiColors[i].rgbRed =(BYTE) CVT(red[i]);
151
 
                  lpbmi->bmiColors[i].rgbGreen = (BYTE) CVT(green[i]);
152
 
                  lpbmi->bmiColors[i].rgbBlue = (BYTE) CVT(blue[i]);           
153
 
                }
154
 
             else
155
 
                {
156
 
                  lpbmi->bmiColors[i].rgbRed = (BYTE) red[i];
157
 
                  lpbmi->bmiColors[i].rgbGreen = (BYTE) green[i];
158
 
                  lpbmi->bmiColors[i].rgbBlue = (BYTE) blue[i];        
159
 
                }
160
 
            }  
161
 
                 
162
 
        }
163
 
        
164
 
        //read the tiff lines and save them in the DIB
165
 
                //with RGB mode, we have to change the order of the 3 samples RGB
166
 
<=> BGR
167
 
        for (row = 0; row < imageLength; row += RowsPerStrip) 
168
 
          {     
169
 
            nrow = (row + RowsPerStrip > imageLength ? imageLength - row :
170
 
RowsPerStrip);
171
 
            if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
172
 
                buf, nrow*LineSize)==-1)
173
 
                  {
174
 
                     goto TiffReadError;
175
 
                  } 
176
 
            else
177
 
                  {  
178
 
                    for (l = 0; l < nrow; l++) 
179
 
                      {
180
 
                         if (SamplePerPixel  == 3)
181
 
                           for (i=0;i< (int) (imageWidth);i++)
182
 
                              {
183
 
                               lpBits[i*SamplePerPixel+0]=buf[l*LineSize+i*Sample
184
 
PerPixel+2]; 
185
 
                               lpBits[i*SamplePerPixel+1]=buf[l*LineSize+i*Sample
186
 
PerPixel+1];
187
 
                               lpBits[i*SamplePerPixel+2]=buf[l*LineSize+i*Sample
188
 
PerPixel+0];
189
 
                              }
190
 
                         else
191
 
                           memcpy(lpBits, &buf[(int) (l*LineSize)], (int)
192
 
imageWidth*SamplePerPixel); 
193
 
                          
194
 
                         lpBits-=imageWidth*SamplePerPixel+Align;
195
 
 
196
 
                      }
197
 
                 }
198
 
          }
199
 
        GlobalUnlock(hStrip);
200
 
        GlobalFree(hStrip);
201
 
        GlobalUnlock(hDIB); 
202
 
        TIFFClose(tif);
203
 
      }
204
 
      
205
 
    return hDIB;
206
 
    
207
 
    OutOfBufMemory:
208
 
       
209
 
    TiffReadError:
210
 
       GlobalUnlock(hDIB); 
211
 
       GlobalFree(hStrip);
212
 
    OutOfDIBMemory:
213
 
       TIFFClose(tif);
214
 
    TiffOpenError:
215
 
       return (HANDLE) 0;
216
 
       
217
 
         
218
 
}
219
 
 
220
 
 
221
 
static int checkcmap(int n, uint16* r, uint16* g, uint16* b)
222
 
{
223
 
    while (n-- > 0)
224
 
        if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
225
 
        return (16);
226
 
    
227
 
    return (8);
228
 
}
229
 
 
230
 
 
231
 
 
232
 
/*************************************************************************
233
 
 * All the following functions were created by microsoft, they are
234
 
 * parts of the sample project "wincap" given with the SDK Win32.
235
 
 *
236
 
 * Microsoft says that :
237
 
 *
238
 
 *  You have a royalty-free right to use, modify, reproduce and
239
 
 *  distribute the Sample Files (and/or any modified version) in
240
 
 *  any way you find useful, provided that you agree that
241
 
 *  Microsoft has no warranty obligations or liability for any
242
 
 *  Sample Application Files which are modified.
243
 
 *
244
 
 ************************************************************************/
245
 
 
246
 
HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount)
247
 
{
248
 
   BITMAPINFOHEADER bi;         // bitmap header
249
 
   LPBITMAPINFOHEADER lpbi;     // pointer to BITMAPINFOHEADER
250
 
   DWORD dwLen;                 // size of memory block
251
 
   HDIB hDIB;
252
 
   DWORD dwBytesPerLine;        // Number of bytes per scanline
253
 
 
254
 
 
255
 
   // Make sure bits per pixel is valid
256
 
   if (wBitCount <= 1)
257
 
      wBitCount = 1;
258
 
   else if (wBitCount <= 4)
259
 
      wBitCount = 4;
260
 
   else if (wBitCount <= 8)
261
 
      wBitCount = 8;
262
 
   else if (wBitCount <= 24)
263
 
      wBitCount = 24;
264
 
   else
265
 
      wBitCount = 4;  // set default value to 4 if parameter is bogus
266
 
 
267
 
   // initialize BITMAPINFOHEADER
268
 
   bi.biSize = sizeof(BITMAPINFOHEADER);
269
 
   bi.biWidth = dwWidth;         // fill in width from parameter
270
 
   bi.biHeight = dwHeight;       // fill in height from parameter
271
 
   bi.biPlanes = 1;              // must be 1
272
 
   bi.biBitCount = wBitCount;    // from parameter
273
 
   bi.biCompression = BI_RGB;    
274
 
   bi.biSizeImage = (dwWidth*dwHeight*wBitCount)/8; //0;           // 0's here
275
 
mean "default"
276
 
   bi.biXPelsPerMeter = 2834; //0;
277
 
   bi.biYPelsPerMeter = 2834; //0;
278
 
   bi.biClrUsed = 0;
279
 
   bi.biClrImportant = 0;
280
 
 
281
 
   // calculate size of memory block required to store the DIB.  This
282
 
   // block should be big enough to hold the BITMAPINFOHEADER, the color
283
 
   // table, and the bits
284
 
 
285
 
   dwBytesPerLine =   (((wBitCount * dwWidth) + 31) / 32 * 4);
286
 
   dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + (dwBytesPerLine * dwHeight);
287
 
 
288
 
   // alloc memory block to store our bitmap
289
 
   hDIB = GlobalAlloc(GHND, dwLen);
290
 
 
291
 
   // major bummer if we couldn't get memory block
292
 
   if (!hDIB)
293
 
   {
294
 
      return NULL;
295
 
   }
296
 
 
297
 
   // lock memory and get pointer to it
298
 
   lpbi = (VOID FAR *)GlobalLock(hDIB);
299
 
 
300
 
   // use our bitmap info structure to fill in first part of
301
 
   // our DIB with the BITMAPINFOHEADER
302
 
   *lpbi = bi;
303
 
 
304
 
   // Since we don't know what the colortable and bits should contain,
305
 
   // just leave these blank.  Unlock the DIB and return the HDIB.
306
 
 
307
 
   GlobalUnlock(hDIB);
308
 
 
309
 
   /* return handle to the DIB */
310
 
   return hDIB;
311
 
}
312
 
 
313
 
 
314
 
LPSTR FAR FindDIBBits(LPSTR lpDIB)
315
 
{
316
 
   return (lpDIB + *(LPDWORD)lpDIB + PaletteSize(lpDIB));
317
 
}
318
 
 
319
 
 
320
 
WORD FAR PaletteSize(LPSTR lpDIB)
321
 
{
322
 
   /* calculate the size required by the palette */
323
 
   if (IS_WIN30_DIB (lpDIB))
324
 
      return (DIBNumColors(lpDIB) * sizeof(RGBQUAD));
325
 
   else
326
 
      return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE));
327
 
}
328
 
 
329
 
 
330
 
WORD DIBNumColors(LPSTR lpDIB)
331
 
{
332
 
   WORD wBitCount;  // DIB bit count
333
 
 
334
 
   /*  If this is a Windows-style DIB, the number of colors in the
335
 
    *  color table can be less than the number of bits per pixel
336
 
    *  allows for (i.e. lpbi->biClrUsed can be set to some value).
337
 
    *  If this is the case, return the appropriate value.
338
 
    */
339
 
 
340
 
   if (IS_WIN30_DIB(lpDIB))
341
 
   {
342
 
      DWORD dwClrUsed;
343
 
 
344
 
      dwClrUsed = ((LPBITMAPINFOHEADER)lpDIB)->biClrUsed;
345
 
      if (dwClrUsed)
346
 
     return (WORD)dwClrUsed;
347
 
   }
348
 
 
349
 
   /*  Calculate the number of colors in the color table based on
350
 
    *  the number of bits per pixel for the DIB.
351
 
    */
352
 
   if (IS_WIN30_DIB(lpDIB))
353
 
      wBitCount = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
354
 
   else
355
 
      wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount;
356
 
 
357
 
   /* return number of colors based on bits per pixel */
358
 
   switch (wBitCount)
359
 
      {
360
 
   case 1:
361
 
      return 2;
362
 
 
363
 
   case 4:
364
 
      return 16;
365
 
 
366
 
   case 8:
367
 
      return 256;
368
 
 
369
 
   default:
370
 
      return 0;
371
 
      }
372
 
}