Browse code

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>

Reimar Döffinger authored on 2012/01/08 20:19:48
Showing 1 changed files
... ...
@@ -20,6 +20,7 @@
20 20
  */
21 21
 
22 22
 #include "libavutil/imgutils.h"
23
+#include "libavutil/avassert.h"
23 24
 #include "avcodec.h"
24 25
 #include "bytestream.h"
25 26
 #include "sgi.h"
... ...
@@ -113,6 +114,25 @@ static int read_rle_sgi(unsigned char* out_buf, const uint8_t *in_buf,
113 113
     return 0;
114 114
 }
115 115
 
116
+static av_always_inline void copy_loop(uint8_t *out_buf, const uint8_t *in_buf,
117
+                                       unsigned offset, unsigned bytes_per_channel,
118
+                                       SgiState *s)
119
+{
120
+    int x, y, z;
121
+    for (y = s->height - 1; y >= 0; y--) {
122
+        uint8_t *line = out_buf + (y * s->linesize);
123
+        for (x = s->width; x > 0; x--) {
124
+            const uint8_t *ptr = in_buf;
125
+            in_buf += bytes_per_channel;
126
+            for(z = 0; z < s->depth; z ++) {
127
+                memcpy(line, ptr, bytes_per_channel);
128
+                line += bytes_per_channel;
129
+                ptr += offset;
130
+            }
131
+        }
132
+    }
133
+}
134
+
116 135
 /**
117 136
  * Read an uncompressed SGI image.
118 137
  * @param out_buf output buffer
... ...
@@ -125,8 +145,6 @@ static int read_rle_sgi(unsigned char* out_buf, const uint8_t *in_buf,
125 125
 static int read_uncompressed_sgi(unsigned char* out_buf, uint8_t* out_end,
126 126
                 const uint8_t *in_buf, const uint8_t *in_end, SgiState* s)
127 127
 {
128
-    int x, y, z;
129
-    const uint8_t *ptr;
130 128
     unsigned int offset = s->height * s->width * s->bytes_per_channel;
131 129
 
132 130
     /* Test buffer size. */
... ...
@@ -134,17 +152,11 @@ static int read_uncompressed_sgi(unsigned char* out_buf, uint8_t* out_end,
134 134
        return -1;
135 135
     }
136 136
 
137
-    for (y = s->height - 1; y >= 0; y--) {
138
-        out_end = out_buf + (y * s->linesize);
139
-        for (x = s->width; x > 0; x--) {
140
-            ptr = in_buf;
141
-            in_buf += s->bytes_per_channel;
142
-            for(z = 0; z < s->depth; z ++) {
143
-                memcpy(out_end, ptr, s->bytes_per_channel);
144
-                out_end += s->bytes_per_channel;
145
-                ptr += offset;
146
-            }
147
-        }
137
+    if (s->bytes_per_channel == 2) {
138
+        copy_loop(out_buf, in_buf, offset, 2, s);
139
+    } else {
140
+        av_assert1(s->bytes_per_channel == 1);
141
+        copy_loop(out_buf, in_buf, offset, 1, s);
148 142
     }
149 143
     return 0;
150 144
 }