[FFmpeg-devel] [PATCH] OpenEXR decoder rev-8

Jimmy Christensen jimmy
Mon Jul 6 16:07:53 CEST 2009


On 2009-07-06 15:54, Reimar D?ffinger wrote:
> On Sun, Jul 05, 2009 at 10:30:16PM +0200, Jimmy Christensen wrote:
>> +    //int buf_end        = (buf + buf_size);
>
> ?

Hmmm.. missed a comment there. Will ofcourse remove it.


>
>> +    int red_channel        .= -1;
>
> I don't think that'll work with that . in there.
>

How did that get in there?

>> +        if (buf_end - buf>= 20&&  !strncmp(buf, "channels", 9)) {
>> +            buf += 9;
>> +            if (!strncmp(buf, "chlist", 7)) {
>> +                buf += 7;
>
> A function would probably make sense, e.g.
> static int compare_str(const uint8_t **buf, const uint8_t *buf_end, const char *str) {
>      int len = strlen(str) + 1;
>      if (buf_end - *buf<  len || strncmp(buf, str, len))
>          return 0;
>      *buf += len;
>      return 1;
> }
>

Yes, would make it a function when I was sure that the method was correct.

>> +                variable_buffer_data_size = bytestream_get_le32(&buf);
>> +                channel_iter = -1;
>> +                if((buf + variable_buffer_data_size)<  buf_end) {
>
> buf + variable_buffer_data_size can overflow.
> The unsafe data (e.g. the thing you read from the file and haven't
> verified) should always stand alone.
> Also the () is useless.
>

Will try to make it better.

>> +                    const uint8_t *ptr_tmp = buf;
>> +                    if((buf_end - buf)>  variable_buffer_data_size) {
>
> What's supposed to be the difference between this check and the one
> above??
> Also you should decide on which part to put right and which left, not
> change it around IMO.

You're right. Will change it.

>
>> +                    while(ptr_tmp + 1<  (buf)) {
>> +                        channel_iter++;
>> +                        if((buf - ptr_tmp)>= 19&&  !strncmp(ptr_tmp, "R", 2)) {
>> +                            ptr_tmp += 2;
>> +                            red_channel = channel_iter;
>> +                            bits_per_color_id = AV_RL32(ptr_tmp);
>> +                            ptr_tmp += 16;
>> +                            continue;
>> +                        }
>> +
>> +                        if((buf - ptr_tmp)>= 19&&  !strncmp(ptr_tmp, "G", 2)) {
>> +                            ptr_tmp += 2;
>> +                            green_channel = channel_iter;
>> +                            ptr_tmp += 16;
>> +                            continue;
>> +                        }
>> +
>> +                        if((buf - ptr_tmp)>= 19&&  !strncmp(ptr_tmp, "B", 2)) {
>> +                            ptr_tmp += 2;
>> +                            blue_channel = channel_iter;
>> +                            ptr_tmp += 16;
>> +                            continue;
>> +                        }
>> +
>> +                        // Process other channels
>> +                        if(ptr_tmp<  buf) {
>> +                            while(ptr_tmp[0] != 0x0) {
>> +                                ptr_tmp++;
>> +                            }
>> +                            ptr_tmp += 17;
>> +                        }
>
> Both inside this loop as well as in the outer loop you can't handle the
> "else" case this way. If someone stores the data in the order "B", "G",
> "R", your "process other channels" part will throw away the "G".
>
No, and I know this since the files I use are actually stored as "B", 
"G", "R". Remember there is a continue inside each if. I know it's ugly.

>> +        // Process unknown variables
>> +        if((buf_end - buf)>  9) {
>> +            // Skip variable name
>> +            while(buf[0] != 0x0&&  buf<  buf_end) {
>
> If buf[0] is 0, then that indicates the end of the header, it's not an
> unknown variable.
> Also first accessing the data and the checking if it is in bounds makes
> little sense, even though due to padding it probably won't cause issues.
>

Will make it inside another if.

>> +            // Skip variable type
>> +            while(buf[0] != 0x0&&  buf<  buf_end) {
>> +                buf++;
>> +            }
>> +            buf++;
>
> Also it can be shortened to
> while (buf<  buf_end&&  *buf++) /**/;
>

Thanks. Will change that.

>
>> +                variable_buffer_data_size = bytestream_get_le32(&buf);
>> +                if((buf_end - buf)>  variable_buffer_data_size) {
>> +                    buf += variable_buffer_data_size;
>> +                } else {
>> +                    av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
>> +                    return -1;
>> +                }
>
> That's at least the second place where I see this code. A function might
> be a good idea.
>

See above comment.

>> +                uint16_t* ptr_x = (uint16_t*)ptr;
>
> The * is placed inconsistently.

Will change it.

>
>> +                const uint32_t line_offset = AV_RL64(buf);
>
> bytestream_get_le64

Will use that instead.

>
>> +                const uint8_t *red_channel_buffer   = avpkt->data + line_offset + 8 + (xdelta)*4*red_channel;
>> +                const uint8_t *green_channel_buffer = avpkt->data + line_offset + 8 + (xdelta)*4*green_channel;
>> +                const uint8_t *blue_channel_buffer  = avpkt->data + line_offset + 8 + (xdelta)*4*blue_channel;
>
> You aren't checking that these actually point anywhere valid.
> Try adding setting "line_offset = 0x4fffffff;" and you should see what I
> mean.

In this revision I focused more on the header parser. Will ofcourse make 
more checks here.

>
>> +                    *ptr_x++ = exr_flt2uint(AV_RL32(red_channel_buffer));
>> +                    red_channel_buffer += 4;
>> +                    *ptr_x++ = exr_flt2uint(AV_RL32(green_channel_buffer));
>> +                    green_channel_buffer += 4;
>> +                    *ptr_x++ = exr_flt2uint(AV_RL32(blue_channel_buffer));
>> +                    blue_channel_buffer += 4;
>
> bytestream_get_le32 for all of these.

Will use that instead.

>
>> +                // Zero out the end if xmax+1 is not w
>> +                memset(ptr_x, 0, (avctx->width - (xmax+1))*6);
>> +                ptr_x += (avctx->width - (xmax+1))*3;
>

True, was a copy from earlier in the code so didn't think about that.

> Incrementing ptr_x is pointless.
>
>> +        // 16-bit
>> +        case 1:
>
> basically the same comments.
>

-- 
Best Regards
Jimmy Christensen
Developer
Ghost A/S



More information about the ffmpeg-devel mailing list