source: trunk/poppler/freetype-2.1.10/src/base/ftbitmap.c @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 15 years ago

First import

File size: 13.7 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  ftbitmap.c                                                             */
4/*                                                                         */
5/*    FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */
6/*    bitmaps into 8bpp format (body).                                     */
7/*                                                                         */
8/*  Copyright 2004, 2005 by                                                */
9/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
10/*                                                                         */
11/*  This file is part of the FreeType project, and may only be used,       */
12/*  modified, and distributed under the terms of the FreeType project      */
13/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
14/*  this file you indicate that you have read the license and              */
15/*  understand and accept it fully.                                        */
16/*                                                                         */
17/***************************************************************************/
18
19
20#include <ft2build.h>
21#include FT_BITMAP_H
22#include FT_INTERNAL_OBJECTS_H
23
24
25  static
26  const FT_Bitmap  null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 };
27
28
29  /* documentation is in ftbitmap.h */
30
31  FT_EXPORT_DEF( void )
32  FT_Bitmap_New( FT_Bitmap  *abitmap )
33  {
34    *abitmap = null_bitmap;
35  }
36
37
38  /* documentation is in ftbitmap.h */
39
40  FT_EXPORT_DEF( FT_Error )
41  FT_Bitmap_Copy( FT_Library        library,
42                  const FT_Bitmap  *source,
43                  FT_Bitmap        *target)
44  {
45    FT_Memory  memory = library->memory;
46    FT_Error   error  = FT_Err_Ok;
47    FT_Int     pitch  = source->pitch;
48    FT_ULong   size;
49
50
51    if ( source == target )
52      return FT_Err_Ok;
53
54    if ( source->buffer == NULL )
55    {
56      *target = *source;
57
58      return FT_Err_Ok;
59    }
60
61    if ( pitch < 0 )
62      pitch = -pitch;
63    size = (FT_ULong)( pitch * source->rows );
64
65    if ( target->buffer )
66    {
67      FT_Int    target_pitch = target->pitch;
68      FT_ULong  target_size;
69
70
71      if ( target_pitch < 0  )
72        target_pitch = -target_pitch;
73      target_size = (FT_ULong)( target_pitch * target->rows );
74
75      if ( target_size != size )
76        FT_QREALLOC( target->buffer, target_size, size );
77    }
78    else
79      FT_QALLOC( target->buffer, size );
80
81    if ( !error )
82    {
83      unsigned char *p;
84
85
86      p = target->buffer;
87      *target = *source;
88      target->buffer = p;
89
90      FT_MEM_COPY( target->buffer, source->buffer, size );
91    }
92
93    return error;
94  }
95
96
97  static FT_Error
98  ft_bitmap_assure_buffer( FT_Memory   memory,
99                           FT_Bitmap*  bitmap,
100                           FT_UInt     xpixels,
101                           FT_UInt     ypixels )
102  {
103    FT_Error        error;
104    int             pitch;
105    int             new_pitch;
106    FT_UInt         ppb;
107    FT_Int          i;
108    unsigned char*  buffer;
109
110
111    pitch = bitmap->pitch;
112    if ( pitch < 0 )
113      pitch = -pitch;
114
115    switch ( bitmap->pixel_mode )
116    {
117    case FT_PIXEL_MODE_MONO:
118      ppb = 8;
119      break;
120    case FT_PIXEL_MODE_GRAY2:
121      ppb = 4;
122      break;
123    case FT_PIXEL_MODE_GRAY4:
124      ppb = 2;
125      break;
126    case FT_PIXEL_MODE_GRAY:
127    case FT_PIXEL_MODE_LCD:
128    case FT_PIXEL_MODE_LCD_V:
129      ppb = 1;
130      break;
131    default:
132      return FT_Err_Invalid_Glyph_Format;
133    }
134
135    /* if no need to allocate memory */
136    if ( ypixels == 0 && pitch * ppb >= bitmap->width + xpixels )
137    {
138      /* zero the padding */
139      for ( i = 0; i < bitmap->rows; i++ )
140      {
141        unsigned char*  last_byte;
142        int             bits = xpixels * ( 8 / ppb );
143        int             mask = 0;
144
145
146        last_byte = bitmap->buffer + i * pitch + ( bitmap->width - 1 ) / ppb;
147
148        if ( bits >= 8 )
149        {
150          FT_MEM_ZERO( last_byte + 1, bits / 8 );
151          bits %= 8;
152        }
153
154        if ( bits > 0 )
155        {
156          while ( bits-- > 0 )
157            mask |= 1 << bits;
158
159          *last_byte &= ~mask;
160        }
161      }
162
163      return FT_Err_Ok;
164    }
165
166    new_pitch = ( bitmap->width + xpixels + ppb - 1 ) / ppb;
167
168    if ( FT_ALLOC( buffer, new_pitch * ( bitmap->rows + ypixels ) ) )
169      return error;
170
171    if ( bitmap->pitch > 0 )
172    {
173      for ( i = 0; i < bitmap->rows; i++ )
174        FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ),
175                     bitmap->buffer + pitch * i, pitch );
176    }
177    else
178    {
179      for ( i = 0; i < bitmap->rows; i++ )
180        FT_MEM_COPY( buffer + new_pitch * i,
181                     bitmap->buffer + pitch * i, pitch );
182    }
183
184    FT_FREE( bitmap->buffer );
185    bitmap->buffer = buffer;
186
187    if ( bitmap->pitch < 0 )
188      new_pitch = -new_pitch;
189
190    /* set pitch only */
191    bitmap->pitch = new_pitch;
192
193    return FT_Err_Ok;
194  }
195
196
197  /* documentation is in ftbitmap.h */
198
199  FT_EXPORT_DEF( FT_Error )
200  FT_Bitmap_Embolden( FT_Library  library,
201                      FT_Bitmap*  bitmap,
202                      FT_Pos      xStrength,
203                      FT_Pos      yStrength )
204  {
205    FT_Error        error;
206    unsigned char*  p;
207    FT_Int          i, x, y, pitch;
208    FT_Int          xstr, ystr;
209
210
211    if ( !library )
212      return FT_Err_Invalid_Library_Handle;
213
214    if ( !bitmap || !bitmap->buffer )
215      return FT_Err_Invalid_Argument;
216
217    xstr = FT_PIX_ROUND( xStrength ) >> 6;
218    ystr = FT_PIX_ROUND( yStrength ) >> 6;
219
220    if ( xstr == 0 && ystr == 0 )
221      return FT_Err_Ok;
222    else if ( xstr < 0 || ystr < 0 )
223      return FT_Err_Invalid_Argument;
224
225    switch ( bitmap->pixel_mode )
226    {
227    case FT_PIXEL_MODE_GRAY2:
228    case FT_PIXEL_MODE_GRAY4:
229      {
230        FT_Bitmap  tmp;
231        FT_Int     align;
232
233
234        if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 )
235          align = ( bitmap->width + xstr + 3 ) / 4;
236        else
237          align = ( bitmap->width + xstr + 1 ) / 2;
238
239        FT_Bitmap_New( &tmp );
240        error = FT_Bitmap_Convert( library, bitmap, &tmp, align );
241
242        if ( error )
243          return error;
244
245        FT_Bitmap_Done( library, bitmap );
246        *bitmap = tmp;
247      }
248      break;
249
250    case FT_PIXEL_MODE_MONO:
251      if ( xstr > 8 )
252        xstr = 8;
253      break;
254
255    case FT_PIXEL_MODE_LCD:
256      xstr *= 3;
257      break;
258
259    case FT_PIXEL_MODE_LCD_V:
260      ystr *= 3;
261      break;
262    }
263
264    error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr );
265    if ( error )
266      return error;
267
268    pitch = bitmap->pitch;
269    if ( pitch > 0 )
270      p = bitmap->buffer + pitch * ystr;
271    else
272    {
273      pitch = -pitch;
274      p = bitmap->buffer + pitch * ( bitmap->rows - 1 );
275    }
276
277    /* for each row */
278    for ( y = 0; y < bitmap->rows ; y++ )
279    {
280      /*
281       * Horizontally:
282       *
283       * From the last pixel on, make each pixel or'ed with the
284       * `xstr' pixels before it.
285       */
286      for ( x = pitch - 1; x >= 0; x-- )
287      {
288        unsigned char tmp;
289
290
291        tmp = p[x];
292        for ( i = 1; i <= xstr; i++ )
293        {
294          if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO )
295          {
296            p[x] |= tmp >> i;
297
298            /* the maximum value of 8 for `xstr' comes from here */
299            if ( x > 0 )
300              p[x] |= p[x - 1] << ( 8 - i );
301
302#if 0
303            if ( p[x] == 0xff )
304              break;
305#endif
306          }
307          else
308          {
309            if ( x - i >= 0 )
310            {
311              if ( p[x] + p[x - i] > bitmap->num_grays - 1 )
312              {
313                p[x] = bitmap->num_grays - 1;
314                break;
315              }
316              else
317              {
318                p[x] += p[x - i];
319                if ( p[x] == bitmap->num_grays - 1 )
320                  break;
321              }
322            }
323            else
324              break;
325          }
326        }
327      }
328
329      /*
330       * Vertically:
331       *
332       * Make the above `ystr' rows or'ed with it.
333       */
334      for ( x = 1; x <= ystr; x++ )
335      {
336        unsigned char*  q;
337
338
339        q = p - bitmap->pitch * x;
340        for ( i = 0; i < pitch; i++ )
341          q[i] |= p[i];
342      }
343
344      p += bitmap->pitch;
345    }
346
347    bitmap->width += xstr;
348    bitmap->rows += ystr;
349
350    return FT_Err_Ok;
351  }
352
353
354  /* documentation is in ftbitmap.h */
355
356  FT_EXPORT_DEF( FT_Error )
357  FT_Bitmap_Convert( FT_Library        library,
358                     const FT_Bitmap  *source,
359                     FT_Bitmap        *target,
360                     FT_Int            alignment )
361  {
362    FT_Error   error = FT_Err_Ok;
363    FT_Memory  memory;
364
365
366    if ( !library )
367      return FT_Err_Invalid_Library_Handle;
368
369    memory = library->memory;
370
371    switch ( source->pixel_mode )
372    {
373    case FT_PIXEL_MODE_MONO:
374    case FT_PIXEL_MODE_GRAY:
375    case FT_PIXEL_MODE_GRAY2:
376    case FT_PIXEL_MODE_GRAY4:
377      {
378        FT_Int   pad;
379        FT_Long  old_size;
380
381
382        old_size = target->rows * target->pitch;
383        if ( old_size < 0 )
384          old_size = -old_size;
385
386        target->pixel_mode = FT_PIXEL_MODE_GRAY;
387        target->rows       = source->rows;
388        target->width      = source->width;
389
390        pad = 0;
391        if ( alignment > 0 )
392        {
393          pad = source->width % alignment;
394          if ( pad != 0 )
395            pad = alignment - pad;
396        }
397
398        target->pitch = source->width + pad;
399
400        if ( target->rows * target->pitch > old_size             &&
401             FT_QREALLOC( target->buffer,
402                          old_size, target->rows * target->pitch ) )
403          return error;
404      }
405      break;
406
407    default:
408      error = FT_Err_Invalid_Argument;
409    }
410
411    switch ( source->pixel_mode )
412    {
413    case FT_PIXEL_MODE_MONO:
414      {
415        FT_Byte*  s = source->buffer;
416        FT_Byte*  t = target->buffer;
417        FT_Int    i;
418
419
420        target->num_grays = 2;
421
422        for ( i = source->rows; i > 0; i-- )
423        {
424          FT_Byte*  ss = s;
425          FT_Byte*  tt = t;
426          FT_Int    j;
427
428
429          /* get the full bytes */
430          for ( j = source->width >> 3; j > 0; j-- )
431          {
432            FT_Int  val = ss[0]; /* avoid a byte->int cast on each line */
433
434
435            tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );
436            tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 );
437            tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 );
438            tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 );
439            tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 );
440            tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 );
441            tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 );
442            tt[7] = (FT_Byte)(   val & 0x01 );
443
444            tt += 8;
445            ss += 1;
446          }
447
448          /* get remaining pixels (if any) */
449          j = source->width & 7;
450          if ( j > 0 )
451          {
452            FT_Int  val = *ss;
453
454
455            for ( ; j > 0; j-- )
456            {
457              tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7);
458              val <<= 1;
459              tt   += 1;
460            }
461          }
462
463          s += source->pitch;
464          t += target->pitch;
465        }
466      }
467      break;
468
469
470    case FT_PIXEL_MODE_GRAY:
471      {
472        FT_Int    width   = source->width;
473        FT_Byte*  s       = source->buffer;
474        FT_Byte*  t       = target->buffer;
475        FT_Int    s_pitch = source->pitch;
476        FT_Int    t_pitch = target->pitch;
477        FT_Int    i;
478
479
480        target->num_grays = 256;
481
482        for ( i = source->rows; i > 0; i-- )
483        {
484          FT_ARRAY_COPY( t, s, width );
485
486          s += s_pitch;
487          t += t_pitch;
488        }
489      }
490      break;
491
492
493    case FT_PIXEL_MODE_GRAY2:
494      {
495        FT_Byte*  s = source->buffer;
496        FT_Byte*  t = target->buffer;
497        FT_Int    i;
498
499
500        target->num_grays = 4;
501
502        for ( i = source->rows; i > 0; i-- )
503        {
504          FT_Byte*  ss = s;
505          FT_Byte*  tt = t;
506          FT_Int    j;
507
508
509          /* get the full bytes */
510          for ( j = source->width >> 2; j > 0; j-- )
511          {
512            FT_Int  val = ss[0];
513
514
515            tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
516            tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 );
517            tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 );
518            tt[3] = (FT_Byte)( ( val & 0x03 ) );
519
520            ss += 1;
521            tt += 4;
522          }
523
524          j = source->width & 3;
525          if ( j > 0 )
526          {
527            FT_Int  val = ss[0];
528
529
530            for ( ; j > 0; j-- )
531            {
532              tt[0]  = (FT_Byte)( ( val & 0xC0 ) >> 6 );
533              val  <<= 2;
534              tt    += 1;
535            }
536          }
537
538          s += source->pitch;
539          t += target->pitch;
540        }
541      }
542      break;
543
544
545    case FT_PIXEL_MODE_GRAY4:
546      {
547        FT_Byte*  s = source->buffer;
548        FT_Byte*  t = target->buffer;
549        FT_Int    i;
550
551
552        target->num_grays = 16;
553
554        for ( i = source->rows; i > 0; i-- )
555        {
556          FT_Byte*  ss = s;
557          FT_Byte*  tt = t;
558          FT_Int    j;
559
560
561          /* get the full bytes */
562          for ( j = source->width >> 1; j > 0; j-- )
563          {
564            FT_Int  val = ss[0];
565
566
567            tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 );
568            tt[1] = (FT_Byte)( ( val & 0x0F ) );
569
570            ss += 1;
571            tt += 2;
572          }
573
574          if ( source->width & 1 )
575            tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );
576
577          s += source->pitch;
578          t += target->pitch;
579        }
580      }
581      break;
582
583
584    default:
585      ;
586    }
587
588    return error;
589  }
590
591
592  /* documentation is in ftbitmap.h */
593
594  FT_EXPORT_DEF( FT_Error )
595  FT_Bitmap_Done( FT_Library  library,
596                  FT_Bitmap  *bitmap )
597  {
598    FT_Memory  memory;
599
600
601    if ( !library )
602      return FT_Err_Invalid_Library_Handle;
603
604    if ( !bitmap )
605      return FT_Err_Invalid_Argument;
606
607    memory = library->memory;
608
609    FT_FREE( bitmap->buffer );
610    *bitmap = null_bitmap;
611
612    return FT_Err_Ok;
613  }
614
615
616/* END */
Note: See TracBrowser for help on using the repository browser.