about summary refs log tree commit diff
path: root/urt/rle_row_alc.c
blob: d763174444a3f62ca4544bf5b0e002bf18f3815e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * This software is copyrighted as noted below.  It may be freely copied,
 * modified, and redistributed, provided that the copyright notice is
 * preserved on all copies.
 *
 * There is no warranty or other guarantee of fitness for this software,
 * it is provided solely "as is".  Bug reports or fixes may be sent
 * to the author, who may or may not act on them as he desires.
 *
 * You may not include this software in a program or other software product
 * without supplying the source, or without informing the end-user that the
 * source is available for no extra charge.
 *
 * If you modify this software, you should include a notice giving the
 * name of the person performing the modification, the date of modification,
 * and the reason for such modification.
 *
 *  Modified at BRL 16-May-88 by Mike Muuss to avoid Alliant STDC desire
 *  to have all "void" functions so declared.
 */
/*
 * rle_row_alc.c - Allocate buffers for rle_getrow/rle_putrow.
 *
 * Author:      Spencer W. Thomas
 *              Computer Science Dept.
 *              University of Utah
 * Date:        Fri Nov 14 1986
 * Copyright (c) 1986, Spencer W. Thomas
 */

#include <stdlib.h>
#include <stdio.h>

#include "rle.h"

/*****************************************************************
 * TAG( rle_row_alloc )
 *
 * Allocate buffer space for use by rle_getrow and rle_putrow.
 * Inputs:
 *      the_hdr:        Header structure for RLE file to be read or
 *                      written.
 * Outputs:
 *      scanp:          Pointer to pointer to created scanline buffer.
 *                      This pointer is adjusted for the alpha channel,
 *                      if present.
 *      Returns 0 for success, -1 if malloc failed.
 * Assumptions:
 *      No input scanline will extend beyond the declared xmax endpoint.
 * Algorithm:
 *      Count number of channels actually used (check bitmap).
 *      Allocate nchan*rowlength pixels, allocate a buffer
 *      to hold ncolors+alpha pointers, and give each channel
 *      rowlength pixels.  Rowlength is xmax + 1, to allow for rle_getrow
 *      usage.
 */
int
rle_row_alloc( the_hdr, scanp )
rle_hdr *the_hdr;
rle_pixel ***scanp;
{
    rle_pixel ** scanbuf, * pixbuf;
    int rowlen, nchan = 0, i, ncol;

    rowlen = the_hdr->xmax + 1;
    if ( the_hdr->alpha && RLE_BIT( *the_hdr, RLE_ALPHA ) )
        nchan++;
    for ( i = 0; i < the_hdr->ncolors; i++ )
        if ( RLE_BIT( *the_hdr, i ) )
             nchan++;

    ncol = the_hdr->ncolors + the_hdr->alpha;

    if ( (scanbuf = (rle_pixel **)malloc( ncol * sizeof(rle_pixel *) )) == 0 )
        return -1;
    if ( (pixbuf = (rle_pixel *)malloc( nchan * rowlen *
                                       sizeof(rle_pixel) )) == 0 )
    {
        free( scanbuf );
        return -1;
    }

    if ( the_hdr->alpha )
        scanbuf++;

    for ( i = -the_hdr->alpha; i < the_hdr->ncolors; i++ )
        if ( RLE_BIT( *the_hdr, i ) )
        {
            scanbuf[i] = pixbuf;
            pixbuf += rowlen;
        }
        else
            scanbuf[i] = 0;
    *scanp = scanbuf;

    return 0;
}


/*****************************************************************
 * TAG( rle_row_free )
 *
 * Free storage allocated by rle_row_alloc().
 * Inputs:
 *      the_hdr:        Header structure as above.
 *      scanp:          Pointer to scanbuf above.
 * Outputs:
 *      Frees storage referenced by scanp and nrawp.
 * Assumptions:
 *      Storage was allocated by rle_row_alloc, or by use of same
 *      algorithm, at least.
 * Algorithm:
 *      free scanp[0] and scanp.
 */
void
rle_row_free( the_hdr, scanp )
rle_hdr *the_hdr;
rle_pixel **scanp;
{
    int i;

    if ( the_hdr->alpha )
        scanp--;
    for ( i = 0; i < the_hdr->ncolors + the_hdr->alpha; i++ )
        if ( scanp[i] != 0 )
        {
            free( (char *)scanp[i] );
            break;
        }
    free( (char *)scanp );
}