diff options
author | Reimar Döffinger <Reimar.Doeffinger@gmx.de> | 2012-01-08 15:19:48 +0400 |
---|---|---|
committer | Reimar Döffinger <Reimar.Doeffinger@gmx.de> | 2012-01-09 14:02:21 +0400 |
commit | 4231bbbf4c54c22fbda6832002675b43f24d3802 (patch) | |
tree | 162424aafe0803ba2aa04216b5323787dfc0e8ad /libavcodec/sgidec.c | |
parent | efd6b80b402a54923f007378a7dc5397676a8f3a (diff) |
sgidec: make compiler optimize away memcpy call in inner loop.
Using an always_inline function makes the memcpy length a constant,
any reasonable compiler will replace it by a single mov instruction
without us having to duplicate the actual code.
Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
Diffstat (limited to 'libavcodec/sgidec.c')
-rw-r--r-- | libavcodec/sgidec.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c index ae05d83592..98327a86a9 100644 --- a/libavcodec/sgidec.c +++ b/libavcodec/sgidec.c @@ -20,6 +20,7 @@ */ #include "libavutil/imgutils.h" +#include "libavutil/avassert.h" #include "avcodec.h" #include "bytestream.h" #include "sgi.h" @@ -113,6 +114,25 @@ static int read_rle_sgi(unsigned char* out_buf, const uint8_t *in_buf, return 0; } +static av_always_inline void copy_loop(uint8_t *out_buf, const uint8_t *in_buf, + unsigned offset, unsigned bytes_per_channel, + SgiState *s) +{ + int x, y, z; + for (y = s->height - 1; y >= 0; y--) { + uint8_t *line = out_buf + (y * s->linesize); + for (x = s->width; x > 0; x--) { + const uint8_t *ptr = in_buf; + in_buf += bytes_per_channel; + for(z = 0; z < s->depth; z ++) { + memcpy(line, ptr, bytes_per_channel); + line += bytes_per_channel; + ptr += offset; + } + } + } +} + /** * Read an uncompressed SGI image. * @param out_buf output buffer @@ -125,8 +145,6 @@ static int read_rle_sgi(unsigned char* out_buf, const uint8_t *in_buf, static int read_uncompressed_sgi(unsigned char* out_buf, uint8_t* out_end, const uint8_t *in_buf, const uint8_t *in_end, SgiState* s) { - int x, y, z; - const uint8_t *ptr; unsigned int offset = s->height * s->width * s->bytes_per_channel; /* Test buffer size. */ @@ -134,17 +152,11 @@ static int read_uncompressed_sgi(unsigned char* out_buf, uint8_t* out_end, return -1; } - for (y = s->height - 1; y >= 0; y--) { - out_end = out_buf + (y * s->linesize); - for (x = s->width; x > 0; x--) { - ptr = in_buf; - in_buf += s->bytes_per_channel; - for(z = 0; z < s->depth; z ++) { - memcpy(out_end, ptr, s->bytes_per_channel); - out_end += s->bytes_per_channel; - ptr += offset; - } - } + if (s->bytes_per_channel == 2) { + copy_loop(out_buf, in_buf, offset, 2, s); + } else { + av_assert1(s->bytes_per_channel == 1); + copy_loop(out_buf, in_buf, offset, 1, s); } return 0; } |