Revision 44f110f5 libavformat/sgi.c

View differences:

libavformat/sgi.c
86 86
        AVPicture *pict, ByteIOContext *f)
87 87
{
88 88
    int x, y, z, chan_offset, ret = 0;
89
    uint8_t *dest_row, *tmp_row = NULL;
90

  
91
    tmp_row = av_malloc(si->xsize);
89
    uint8_t *dest_row;
92 90

  
93 91
    /* skip header */ 
94 92
    url_fseek(f, SGI_HEADER_SIZE, SEEK_SET);
......
108 106
        for (y = si->ysize - 1; y >= 0; y--) {
109 107
            dest_row = pict->data[0] + (y * si->xsize * si->zsize);
110 108

  
111
            if (!get_buffer(f, tmp_row, si->xsize)) {
112
                ret = -1;
113
                goto cleanup;
114
            }
115 109
            for (x = 0; x < si->xsize; x++) {
116
                dest_row[chan_offset] = tmp_row[x]; 
110
                dest_row[chan_offset] = get_byte(f); 
117 111
                dest_row += si->zsize;
118 112
            }
119 113
        }
120 114
    }
121 115

  
122
cleanup:
123
    av_free(tmp_row);
124 116
    return ret;
125 117
}
126 118

  
127 119

  
128 120
/* expand an rle row into a channel */
129
static void expand_rle_row(unsigned char *optr, unsigned char *iptr, 
121
static int expand_rle_row(ByteIOContext *f, unsigned char *optr,
130 122
        int chan_offset, int pixelstride)
131 123
{
132 124
    unsigned char pixel, count;
125
    int length = 0;
133 126
 
134 127
#ifndef WORDS_BIGENDIAN
135 128
    /* rgba -> bgra for rgba32 on little endian cpus */
......
141 134
    optr += chan_offset;
142 135

  
143 136
    while (1) {
144
        pixel = *iptr++;
137
        pixel = get_byte(f);
145 138

  
146 139
        if (!(count = (pixel & 0x7f))) {
147
            return;
140
            return length;
148 141
        }
149 142
        if (pixel & 0x80) {
150 143
            while (count--) {
151
                *optr = *iptr;
144
                *optr = get_byte(f);
145
                length++;
152 146
                optr += pixelstride;
153
                iptr++;
154 147
            }
155 148
        } else {
156
            pixel = *iptr++;
149
            pixel = get_byte(f);
157 150

  
158 151
            while (count--) {
159 152
                *optr = pixel;
153
                length++;
160 154
                optr += pixelstride;
161 155
            }
162 156
        }
......
168 162
static int read_rle_sgi(const SGIInfo *sgi_info, 
169 163
        AVPicture *pict, ByteIOContext *f)
170 164
{
171
    uint8_t *dest_row, *rle_data = NULL;
172
    unsigned long *start_table, *length_table;
165
    uint8_t *dest_row;
166
    unsigned long *start_table;
173 167
    int y, z, xsize, ysize, zsize, tablen; 
174
    long start_offset, run_length;
168
    long start_offset;
175 169
    int ret = 0;
176 170

  
177 171
    xsize = sgi_info->xsize;
178 172
    ysize = sgi_info->ysize;
179 173
    zsize = sgi_info->zsize;
180 174

  
181
    rle_data = av_malloc(xsize);
182

  
183 175
    /* skip header */ 
184 176
    url_fseek(f, SGI_HEADER_SIZE, SEEK_SET);
185 177

  
......
187 179
    tablen = ysize * zsize * sizeof(long);
188 180

  
189 181
    start_table = (unsigned long *)av_malloc(tablen);
190
    length_table = (unsigned long *)av_malloc(tablen);
191 182

  
192 183
    if (!get_buffer(f, (uint8_t *)start_table, tablen)) {
193
        ret = -1;
184
        ret = AVERROR_IO;
194 185
        goto fail;
195 186
    }
196 187

  
197
    if (!get_buffer(f, (uint8_t *)length_table, tablen)) {
198
        ret = -1;
199
        goto fail;
200
    }
188
    /* skip run length table */ 
189
    url_fseek(f, tablen, SEEK_CUR);
201 190

  
202 191
    for (z = 0; z < zsize; z++) {
203 192
        for (y = 0; y < ysize; y++) {
204 193
            dest_row = pict->data[0] + (ysize - 1 - y) * (xsize * zsize);
205 194

  
206 195
            start_offset = BE_32(&start_table[y + z * ysize]);
207
            run_length = BE_32(&length_table[y + z * ysize]);
208 196

  
209
            /* don't seek if already in the correct spot */
197
            /* don't seek if already at the next rle start offset */
210 198
            if (url_ftell(f) != start_offset) {
211 199
                url_fseek(f, start_offset, SEEK_SET);
212 200
            }
213 201

  
214
            get_buffer(f, rle_data, run_length);
215
            
216
            expand_rle_row(dest_row, rle_data, z, zsize);
202
            if (expand_rle_row(f, dest_row, z, zsize) != xsize) {
203
              ret =  AVERROR_INVALIDDATA;
204
              goto fail;
205
            }
217 206
        }
218 207
    }
219 208

  
220 209
fail:
221 210
    av_free(start_table);
222
    av_free(length_table);
223
    av_free(rle_data);
224 211

  
225 212
    return ret;
226 213
}

Also available in: Unified diff