summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--applypatch/imgdiff.cpp19
-rw-r--r--interlace-frames.py79
-rw-r--r--minui/minui.h4
-rw-r--r--minui/resources.cpp21
-rw-r--r--res-hdpi/images/icon_installing.pngbin118562 -> 129975 bytes
-rw-r--r--res-mdpi/images/icon_installing.pngbin118562 -> 129975 bytes
-rw-r--r--res-xhdpi/images/icon_installing.pngbin118562 -> 129975 bytes
-rw-r--r--res-xxhdpi/images/icon_installing.pngbin118562 -> 129975 bytes
-rw-r--r--res-xxxhdpi/images/icon_installing.pngbin118562 -> 129975 bytes
-rw-r--r--screen_ui.cpp9
-rw-r--r--screen_ui.h4
-rw-r--r--wear_ui.cpp2
-rw-r--r--wear_ui.h5
13 files changed, 95 insertions, 48 deletions
diff --git a/applypatch/imgdiff.cpp b/applypatch/imgdiff.cpp
index 50cabbe6b..f22502e38 100644
--- a/applypatch/imgdiff.cpp
+++ b/applypatch/imgdiff.cpp
@@ -407,6 +407,7 @@ unsigned char* ReadImage(const char* filename,
while (pos < sz) {
unsigned char* p = img+pos;
+ bool processed_deflate = false;
if (sz - pos >= 4 &&
p[0] == 0x1f && p[1] == 0x8b &&
p[2] == 0x08 && // deflate compression
@@ -460,18 +461,24 @@ unsigned char* ReadImage(const char* filename,
strm.next_out = curr->data + curr->len;
ret = inflate(&strm, Z_NO_FLUSH);
if (ret < 0) {
- printf("Error: inflate failed [%s] at file offset [%zu]\n"
- "imgdiff only supports gzip kernel compression,"
- " did you try CONFIG_KERNEL_LZO?\n",
- strm.msg, chunk_offset);
- free(img);
- return NULL;
+ if (!processed_deflate) {
+ // This is the first chunk, assume that it's just a spurious
+ // gzip header instead of a real one.
+ break;
+ }
+ printf("Error: inflate failed [%s] at file offset [%zu]\n"
+ "imgdiff only supports gzip kernel compression,"
+ " did you try CONFIG_KERNEL_LZO?\n",
+ strm.msg, chunk_offset);
+ free(img);
+ return NULL;
}
curr->len = allocated - strm.avail_out;
if (strm.avail_out == 0) {
allocated *= 2;
curr->data = reinterpret_cast<unsigned char*>(realloc(curr->data, allocated));
}
+ processed_deflate = true;
} while (ret != Z_STREAM_END);
curr->deflate_len = sz - strm.avail_in - pos;
diff --git a/interlace-frames.py b/interlace-frames.py
index 243e565e7..3e777b470 100644
--- a/interlace-frames.py
+++ b/interlace-frames.py
@@ -12,42 +12,69 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-"""Script to take a set of frames (PNG files) for a recovery animation
-and turn it into a single output image which contains the input frames
-interlaced by row. Run with the names of all the input frames on the
-command line, in order, followed by the name of the output file."""
+"""
+Script to take a set of frames (PNG files) for a recovery animation and turn
+it into a single output image which contains the input frames interlaced by
+row. Run with the names of all the input frames on the command line. Specify
+the name of the output file with -o (or --output), and optionally specify the
+number of frames per second (FPS) with --fps (default: 20).
+e.g.
+interlace-frames.py --fps 20 --output output.png frame0.png frame1.png frame3.png
+"""
+
+from __future__ import print_function
+
+import argparse
import sys
try:
import Image
import PngImagePlugin
except ImportError:
- print "This script requires the Python Imaging Library to be installed."
+ print("This script requires the Python Imaging Library to be installed.")
sys.exit(1)
-frames = [Image.open(fn).convert("RGB") for fn in sys.argv[1:-1]]
-assert len(frames) > 0, "Must have at least one input frame."
-sizes = set()
-for fr in frames:
- sizes.add(fr.size)
-assert len(sizes) == 1, "All input images must have the same size."
-w, h = sizes.pop()
-N = len(frames)
+def interlace(output, fps, inputs):
+ frames = [Image.open(fn).convert("RGB") for fn in inputs]
+ assert len(frames) > 0, "Must have at least one input frame."
+ sizes = set()
+ for fr in frames:
+ sizes.add(fr.size)
+
+ assert len(sizes) == 1, "All input images must have the same size."
+ w, h = sizes.pop()
+ N = len(frames)
+
+ out = Image.new("RGB", (w, h*N))
+ for j in range(h):
+ for i in range(w):
+ for fn, f in enumerate(frames):
+ out.putpixel((i, j*N+fn), f.getpixel((i, j)))
+
+ # When loading this image, the graphics library expects to find a text
+ # chunk that specifies how many frames this animation represents. If
+ # you post-process the output of this script with some kind of
+ # optimizer tool (eg pngcrush or zopflipng) make sure that your
+ # optimizer preserves this text chunk.
+
+ meta = PngImagePlugin.PngInfo()
+ meta.add_text("Frames", str(N))
+ meta.add_text("FPS", str(fps))
+
+ out.save(output, pnginfo=meta)
+
+
+def main(argv):
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--fps', default=20)
+ parser.add_argument('--output', '-o', required=True)
+ parser.add_argument('input', nargs='+')
+ args = parser.parse_args(argv)
-out = Image.new("RGB", (w, h*N))
-for j in range(h):
- for i in range(w):
- for fn, f in enumerate(frames):
- out.putpixel((i, j*N+fn), f.getpixel((i, j)))
+ interlace(args.output, args.fps, args.input)
-# When loading this image, the graphics library expects to find a text
-# chunk that specifies how many frames this animation represents. If
-# you post-process the output of this script with some kind of
-# optimizer tool (eg pngcrush or zopflipng) make sure that your
-# optimizer preserves this text chunk.
-meta = PngImagePlugin.PngInfo()
-meta.add_text("Frames", str(N))
+if __name__ == '__main__':
+ main(sys.argv[1:])
-out.save(sys.argv[-1], pnginfo=meta)
diff --git a/minui/minui.h b/minui/minui.h
index bdde083f3..e3bc00548 100644
--- a/minui/minui.h
+++ b/minui/minui.h
@@ -101,8 +101,8 @@ int res_create_display_surface(const char* name, GRSurface** pSurface);
// should have a 'Frames' text chunk whose value is the number of
// frames this image represents. The pixel data itself is interlaced
// by row.
-int res_create_multi_display_surface(const char* name,
- int* frames, GRSurface*** pSurface);
+int res_create_multi_display_surface(const char* name, int* frames,
+ int* fps, GRSurface*** pSurface);
// Load a single alpha surface from a grayscale PNG image.
int res_create_alpha_surface(const char* name, GRSurface** pSurface);
diff --git a/minui/resources.cpp b/minui/resources.cpp
index 5e4789277..63a0dff28 100644
--- a/minui/resources.cpp
+++ b/minui/resources.cpp
@@ -237,14 +237,14 @@ int res_create_display_surface(const char* name, GRSurface** pSurface) {
return result;
}
-int res_create_multi_display_surface(const char* name, int* frames, GRSurface*** pSurface) {
+int res_create_multi_display_surface(const char* name, int* frames, int* fps,
+ GRSurface*** pSurface) {
GRSurface** surface = NULL;
int result = 0;
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
png_uint_32 width, height;
png_byte channels;
- int i;
png_textp text;
int num_text;
unsigned char* p_row;
@@ -257,14 +257,23 @@ int res_create_multi_display_surface(const char* name, int* frames, GRSurface***
if (result < 0) return result;
*frames = 1;
+ *fps = 20;
if (png_get_text(png_ptr, info_ptr, &text, &num_text)) {
- for (i = 0; i < num_text; ++i) {
+ for (int i = 0; i < num_text; ++i) {
if (text[i].key && strcmp(text[i].key, "Frames") == 0 && text[i].text) {
*frames = atoi(text[i].text);
- break;
+ } else if (text[i].key && strcmp(text[i].key, "FPS") == 0 && text[i].text) {
+ *fps = atoi(text[i].text);
}
}
printf(" found frames = %d\n", *frames);
+ printf(" found fps = %d\n", *fps);
+ }
+
+ if (frames <= 0 || fps <= 0) {
+ printf("bad number of frames (%d) and/or FPS (%d)\n", *frames, *fps);
+ result = -10;
+ goto exit;
}
if (height % *frames != 0) {
@@ -278,7 +287,7 @@ int res_create_multi_display_surface(const char* name, int* frames, GRSurface***
result = -8;
goto exit;
}
- for (i = 0; i < *frames; ++i) {
+ for (int i = 0; i < *frames; ++i) {
surface[i] = init_display_surface(width, height / *frames);
if (surface[i] == NULL) {
result = -8;
@@ -307,7 +316,7 @@ exit:
if (result < 0) {
if (surface) {
- for (i = 0; i < *frames; ++i) {
+ for (int i = 0; i < *frames; ++i) {
if (surface[i]) free(surface[i]);
}
free(surface);
diff --git a/res-hdpi/images/icon_installing.png b/res-hdpi/images/icon_installing.png
index c2c020162..0fcfbc231 100644
--- a/res-hdpi/images/icon_installing.png
+++ b/res-hdpi/images/icon_installing.png
Binary files differ
diff --git a/res-mdpi/images/icon_installing.png b/res-mdpi/images/icon_installing.png
index c2c020162..0fcfbc231 100644
--- a/res-mdpi/images/icon_installing.png
+++ b/res-mdpi/images/icon_installing.png
Binary files differ
diff --git a/res-xhdpi/images/icon_installing.png b/res-xhdpi/images/icon_installing.png
index c2c020162..0fcfbc231 100644
--- a/res-xhdpi/images/icon_installing.png
+++ b/res-xhdpi/images/icon_installing.png
Binary files differ
diff --git a/res-xxhdpi/images/icon_installing.png b/res-xxhdpi/images/icon_installing.png
index c2c020162..0fcfbc231 100644
--- a/res-xxhdpi/images/icon_installing.png
+++ b/res-xxhdpi/images/icon_installing.png
Binary files differ
diff --git a/res-xxxhdpi/images/icon_installing.png b/res-xxxhdpi/images/icon_installing.png
index c2c020162..0fcfbc231 100644
--- a/res-xxxhdpi/images/icon_installing.png
+++ b/res-xxxhdpi/images/icon_installing.png
Binary files differ
diff --git a/screen_ui.cpp b/screen_ui.cpp
index 23fc90154..522aa6b23 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -73,7 +73,7 @@ ScreenRecoveryUI::ScreenRecoveryUI() :
menu_items(0),
menu_sel(0),
file_viewer_text_(nullptr),
- animation_fps(20),
+ animation_fps(-1),
installing_frames(-1),
stage(-1),
max_stage(-1) {
@@ -367,8 +367,9 @@ void ScreenRecoveryUI::LoadBitmap(const char* filename, GRSurface** surface) {
}
}
-void ScreenRecoveryUI::LoadBitmapArray(const char* filename, int* frames, GRSurface*** surface) {
- int result = res_create_multi_display_surface(filename, frames, surface);
+void ScreenRecoveryUI::LoadBitmapArray(const char* filename, int* frames, int* fps,
+ GRSurface*** surface) {
+ int result = res_create_multi_display_surface(filename, frames, fps, surface);
if (result < 0) {
LOGE("missing bitmap %s\n(Code %d)\n", filename, result);
}
@@ -405,7 +406,7 @@ void ScreenRecoveryUI::Init() {
text_top_ = 1;
backgroundIcon[NONE] = nullptr;
- LoadBitmapArray("icon_installing", &installing_frames, &installation);
+ LoadBitmapArray("icon_installing", &installing_frames, &animation_fps, &installation);
backgroundIcon[INSTALLING_UPDATE] = installing_frames ? installation[0] : nullptr;
backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE];
LoadBitmap("icon_error", &backgroundIcon[ERROR]);
diff --git a/screen_ui.h b/screen_ui.h
index 8e18864d7..08a5f44a9 100644
--- a/screen_ui.h
+++ b/screen_ui.h
@@ -109,6 +109,8 @@ class ScreenRecoveryUI : public RecoveryUI {
pthread_t progress_thread_;
+ // The following two are parsed from the image file
+ // (e.g. '/res/images/icon_installing.png').
int animation_fps;
int installing_frames;
@@ -135,7 +137,7 @@ class ScreenRecoveryUI : public RecoveryUI {
void DrawTextLines(int* y, const char* const* lines);
void LoadBitmap(const char* filename, GRSurface** surface);
- void LoadBitmapArray(const char* filename, int* frames, GRSurface*** surface);
+ void LoadBitmapArray(const char* filename, int* frames, int* fps, GRSurface*** surface);
void LoadLocalizedBitmap(const char* filename, GRSurface** surface);
};
diff --git a/wear_ui.cpp b/wear_ui.cpp
index 3ee38e8a4..50aeb3849 100644
--- a/wear_ui.cpp
+++ b/wear_ui.cpp
@@ -61,10 +61,10 @@ WearRecoveryUI::WearRecoveryUI() :
menu_unusable_rows(0),
intro_frames(22),
loop_frames(60),
+ animation_fps(30),
currentIcon(NONE),
intro_done(false),
current_frame(0),
- animation_fps(30),
rtl_locale(false),
progressBarType(EMPTY),
progressScopeStart(0),
diff --git a/wear_ui.h b/wear_ui.h
index 839a26438..63c1b6e6e 100644
--- a/wear_ui.h
+++ b/wear_ui.h
@@ -79,6 +79,9 @@ class WearRecoveryUI : public RecoveryUI {
int intro_frames;
int loop_frames;
+ // Number of frames per sec (default: 30) for both of intro and loop.
+ int animation_fps;
+
private:
Icon currentIcon;
@@ -86,8 +89,6 @@ class WearRecoveryUI : public RecoveryUI {
int current_frame;
- int animation_fps;
-
bool rtl_locale;
pthread_mutex_t updateMutex;