mirror of
https://github.com/google/pebble.git
synced 2025-03-24 12:39:07 +00:00
170 lines
5.1 KiB
C
170 lines
5.1 KiB
C
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "clar.h"
|
|
|
|
#include "applib/graphics/gtypes.h"
|
|
#include "applib/graphics/gbitmap_pbi.h"
|
|
|
|
#include "stubs_app_state.h"
|
|
#include "stubs_graphics_context.h"
|
|
#include "stubs_logging.h"
|
|
#include "stubs_process_manager.h"
|
|
#include "stubs_passert.h"
|
|
|
|
// Stubs
|
|
///////////////////////
|
|
bool gbitmap_init_with_png_data(GBitmap *bitmap, const uint8_t *data, size_t data_size) {
|
|
return false;
|
|
}
|
|
|
|
bool gbitmap_png_data_is_png(const uint8_t *data, size_t data_size) {
|
|
return false;
|
|
}
|
|
|
|
ResAppNum sys_get_current_resource_num(void) {
|
|
return 0;
|
|
}
|
|
|
|
const uint8_t *sys_resource_read_only_bytes(ResAppNum app_num, uint32_t resource_id,
|
|
size_t *num_bytes_out) {
|
|
return NULL;
|
|
}
|
|
|
|
// Fakes
|
|
///////////////////////
|
|
size_t s_resource_size;
|
|
size_t sys_resource_size(ResAppNum app_num, uint32_t resource_id) {
|
|
return s_resource_size;
|
|
}
|
|
|
|
typedef struct {
|
|
uint16_t row_size_bytes;
|
|
union {
|
|
uint16_t info_flags;
|
|
BitmapInfo info;
|
|
};
|
|
uint16_t width;
|
|
uint16_t height;
|
|
} FakeBitmapData;
|
|
|
|
FakeBitmapData s_fake_bitmap_data;
|
|
|
|
size_t sys_resource_load_range(
|
|
ResAppNum app_num, uint32_t id, uint32_t start_offset, uint8_t *data, size_t num_bytes) {
|
|
|
|
BitmapData *bitmap = (BitmapData*) data;
|
|
*bitmap = (BitmapData) {
|
|
.row_size_bytes = s_fake_bitmap_data.row_size_bytes,
|
|
.info_flags = s_fake_bitmap_data.info_flags,
|
|
.width = s_fake_bitmap_data.width,
|
|
.height = s_fake_bitmap_data.height
|
|
};
|
|
|
|
return num_bytes;
|
|
}
|
|
|
|
|
|
// Tests
|
|
///////////////////////
|
|
|
|
void test_gbitmap_resource_validation__initialize(void) {
|
|
s_resource_size = 0;
|
|
s_fake_bitmap_data = (FakeBitmapData) { 0 };
|
|
}
|
|
|
|
static uint32_t prv_calculate_size(FakeBitmapData *bitmap) {
|
|
const uint32_t required_size_bytes =
|
|
offsetof(BitmapData, data) + // header size
|
|
(bitmap->row_size_bytes * bitmap->height) + // pixel data
|
|
gbitmap_get_palette_size(bitmap->info.format); // palette data
|
|
return required_size_bytes;
|
|
}
|
|
|
|
void test_gbitmap_resource_validation__total_size(void) {
|
|
s_fake_bitmap_data = (FakeBitmapData) {
|
|
.row_size_bytes = 8,
|
|
.info.format = GBitmapFormat8Bit,
|
|
.info.version = GBITMAP_VERSION_1,
|
|
.width = 8,
|
|
.height = 1
|
|
};
|
|
|
|
// Set the resource size to be valid.
|
|
s_resource_size = prv_calculate_size(&s_fake_bitmap_data);
|
|
|
|
// We should load it successfully
|
|
GBitmap bitmap;
|
|
cl_assert(gbitmap_init_with_resource_system(&bitmap, 0, 0));
|
|
|
|
// However, if we corrupt the row_size_bytes field we should fail.
|
|
s_fake_bitmap_data.row_size_bytes = 12;
|
|
cl_assert(!gbitmap_init_with_resource_system(&bitmap, 0, 0));
|
|
|
|
// Corrupt it the other way, so that there's not enough data
|
|
s_fake_bitmap_data.row_size_bytes = 4;
|
|
cl_assert(!gbitmap_init_with_resource_system(&bitmap, 0, 0));
|
|
|
|
// Fix it up again
|
|
s_fake_bitmap_data.row_size_bytes = 8;
|
|
cl_assert(gbitmap_init_with_resource_system(&bitmap, 0, 0));
|
|
|
|
// But now change the palette format to something that requires more space and watch it fail
|
|
s_fake_bitmap_data.info.format = GBitmapFormat4BitPalette;
|
|
cl_assert(!gbitmap_init_with_resource_system(&bitmap, 0, 0));
|
|
|
|
// But if we have space for the palette, it should pass
|
|
s_resource_size = prv_calculate_size(&s_fake_bitmap_data);
|
|
cl_assert(gbitmap_init_with_resource_system(&bitmap, 0, 0));
|
|
}
|
|
|
|
void test_gbitmap_resource_validation__row_size(void) {
|
|
s_fake_bitmap_data = (FakeBitmapData) {
|
|
.row_size_bytes = 8,
|
|
.info.format = GBitmapFormat8Bit,
|
|
.info.version = GBITMAP_VERSION_1,
|
|
.width = 8,
|
|
.height = 1
|
|
};
|
|
|
|
// Set the resource size to be valid.
|
|
s_resource_size = prv_calculate_size(&s_fake_bitmap_data);
|
|
|
|
// We should load it successfully
|
|
GBitmap bitmap;
|
|
cl_assert(gbitmap_init_with_resource_system(&bitmap, 0, 0));
|
|
|
|
// Vary the width without changing the height to be too large
|
|
s_fake_bitmap_data.width = 10,
|
|
cl_assert(!gbitmap_init_with_resource_system(&bitmap, 0, 0));
|
|
|
|
// Too small is fine though
|
|
s_fake_bitmap_data.width = 6,
|
|
cl_assert(gbitmap_init_with_resource_system(&bitmap, 0, 0));
|
|
|
|
// Test with an uneven number of bits and make sure we're rounding correctly
|
|
s_fake_bitmap_data.info.format = GBitmapFormat1Bit;
|
|
s_fake_bitmap_data.width = 64;
|
|
cl_assert(gbitmap_init_with_resource_system(&bitmap, 0, 0));
|
|
|
|
s_fake_bitmap_data.info.format = GBitmapFormat1Bit;
|
|
s_fake_bitmap_data.width = 65;
|
|
cl_assert(!gbitmap_init_with_resource_system(&bitmap, 0, 0));
|
|
|
|
s_fake_bitmap_data.info.format = GBitmapFormat1Bit;
|
|
s_fake_bitmap_data.width = 63;
|
|
cl_assert(gbitmap_init_with_resource_system(&bitmap, 0, 0));
|
|
}
|