Compare commits
15 Commits
fix-scroll
...
rewrite
| Author | SHA1 | Date | |
|---|---|---|---|
| fbca873f52 | |||
| d1a821edf5 | |||
| a4532b0f3d | |||
|
|
f819f9d452 | ||
| 2c2c7f4b33 | |||
| b75d1acb21 | |||
| e8d0a2eb27 | |||
| f4217888ce | |||
|
|
d358dd134e | ||
|
|
ca9da9d297 | ||
|
|
71a4cde22e | ||
|
|
f7404cf162 | ||
|
|
ef774ce0b4 | ||
|
|
193feedf25 | ||
|
|
ddfc39db56 |
@@ -4,7 +4,7 @@
|
||||
* Dawid Eckert ([@daedreth](https://github.com/daedreth))
|
||||
* Dylan G. ([@helloman892](https://github.com/helloman892))
|
||||
* Nils P. ([@ZetaDesigns](https://github.com/ZetaDesigns))
|
||||
* Matt Kenny ([@mattkenster](https://github.com/mattkenster))
|
||||
* Matt Kenny ([@8kenn](https://github.com/8kenn))
|
||||
|
||||
# Minor Contributors
|
||||
* Nic ([@Wizzrobes](https://github.com/Wizzrobes))
|
||||
@@ -15,4 +15,5 @@
|
||||
* [@uyuiyu](https://github.com/uyuiyu)
|
||||
* Guillaume Gérard ([@GreatWizard](https://github.com/GreatWizard))
|
||||
* Joel ([@joel16](https://github.com/joel16))
|
||||
* [@thedax](https://github.com/thedax)
|
||||
* [@thedax](https://github.com/thedax)
|
||||
* [@Wryyyong](https://github.com/Wryyyong)
|
||||
|
||||
@@ -6,8 +6,7 @@ To-do list here: https://trello.com/b/F1YSa1VK
|
||||
# Dependencies
|
||||
* devkitARM, which can be installed following the instructions [here](https://devkitpro.org/wiki/Getting_Started).
|
||||
* jansson, libvorbisidec, libpng, and libarchive, which can be retrieved from [devkitPro pacman](https://devkitpro.org/viewtopic.php?f=13&t=8702).
|
||||
* A recent build of [makerom](https://github.com/profi200/Project_CTR) and the latest release of [bannertool](https://github.com/Steveice10/bannertool). These must be added to your PATH.
|
||||
A 64-bit Windows binary of makerom is available [here](https://hm892.s-ul.eu/U0Irkqih).
|
||||
* A recent build of [makerom](https://github.com/profi200/Project_CTR) and the latest release of [bannertool](https://github.com/Steveice10/bannertool). These must be added to your PATH.
|
||||
|
||||
# Building
|
||||
First of all, make sure devkitARM is properly installed - `$DEVKITPRO` and `$DEVKITARM` should be set to `/opt/devkitpro` and `$DEVKITPRO/devkitARM`, respectively.
|
||||
|
||||
@@ -35,6 +35,7 @@ typedef struct {
|
||||
C3D_Tex *tex;
|
||||
Handle mutex;
|
||||
volatile bool finished;
|
||||
volatile bool closed;
|
||||
volatile bool success;
|
||||
Handle cancel;
|
||||
Handle started;
|
||||
@@ -47,4 +48,4 @@ bool init_qr(void);
|
||||
void exit_qr(qr_data *data);
|
||||
void take_picture(void);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
typedef u32 Color;
|
||||
|
||||
enum {
|
||||
typedef enum {
|
||||
COLOR_BACKGROUND, //silver-y black
|
||||
COLOR_ACCENT,
|
||||
COLOR_WHITE,
|
||||
|
||||
@@ -125,7 +125,7 @@ typedef enum {
|
||||
#define BUTTONS_INFO_LINES 4
|
||||
#define BUTTONS_INFO_COLUNMNS 2
|
||||
|
||||
enum {
|
||||
typedef enum {
|
||||
BUTTONS_Y_INFO = BUTTONS_START_Y+5,
|
||||
|
||||
BUTTONS_Y_LINE_1 = BUTTONS_START_Y + BUTTONS_STEP*1,
|
||||
@@ -173,4 +173,4 @@ void draw_base_interface(void);
|
||||
void draw_grid_interface(Entry_List_s* list, Instructions_s instructions);
|
||||
void draw_interface(Entry_List_s* list, Instructions_s instructions);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
FS_Archive ArchiveSD;
|
||||
FS_Archive ArchiveHomeExt;
|
||||
FS_Archive ArchiveThemeExt;
|
||||
extern FS_Archive ArchiveSD;
|
||||
extern FS_Archive ArchiveHomeExt;
|
||||
extern FS_Archive ArchiveThemeExt;
|
||||
|
||||
Result open_archives(void);
|
||||
Result close_archives(void);
|
||||
@@ -43,4 +43,4 @@ u32 zip_file_to_buf(char *file_name, u16 *zip_path, char **buf);
|
||||
Result buf_to_file(u32 size, FS_Path path, FS_Archive archive, char *buf);
|
||||
void remake_file(FS_Path path, FS_Archive archive, u32 size);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "draw.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#define THEMEPLAZA_BASE_URL "https://themeplaza.eu"
|
||||
#define THEMEPLAZA_API_URL "/api/anemone/v1"
|
||||
|
||||
@@ -150,7 +150,8 @@ void update_ui(void *arg)
|
||||
if (data->finished)
|
||||
{
|
||||
end_frame();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
C2D_DrawImageAt(data->image, 0.0f, 0.0f, 0.4f, NULL, 1.0f, 1.0f);
|
||||
|
||||
@@ -158,6 +159,7 @@ void update_ui(void *arg)
|
||||
draw_text_center(GFX_BOTTOM, 4, 0.5, 0.5, 0.5, colors[COLOR_WHITE], "Press \uE005 To Quit");
|
||||
end_frame();
|
||||
}
|
||||
data->closed = true;
|
||||
}
|
||||
|
||||
bool start_capture_cam(qr_data *data)
|
||||
@@ -219,6 +221,8 @@ void update_qr(qr_data *data)
|
||||
{
|
||||
exit_qr(data);
|
||||
|
||||
while (!data->finished) svcSleepThread(1000000);
|
||||
|
||||
draw_install(INSTALL_DOWNLOAD);
|
||||
char * zip_buf = NULL;
|
||||
char * filename = NULL;
|
||||
@@ -288,6 +292,7 @@ void update_qr(qr_data *data)
|
||||
{
|
||||
throw_error("File downloaded isn't a zip.", ERROR_LEVEL_WARNING);
|
||||
}
|
||||
free(zip_buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -295,7 +300,6 @@ void update_qr(qr_data *data)
|
||||
}
|
||||
|
||||
free(filename);
|
||||
free(zip_buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,6 +310,7 @@ bool init_qr(void)
|
||||
qr_data *data = calloc(1, sizeof(qr_data));
|
||||
data->capturing = false;
|
||||
data->finished = false;
|
||||
data->closed = false;
|
||||
svcCreateEvent(&data->started, RESET_STICKY);
|
||||
|
||||
data->context = quirc_new();
|
||||
@@ -321,7 +326,8 @@ bool init_qr(void)
|
||||
|
||||
while (!data->finished) update_qr(data);
|
||||
bool success = data->success;
|
||||
while (!data->closed) svcSleepThread(1000000);
|
||||
free(data);
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,7 +434,7 @@ void draw_text_wrap(float x, float y, float z, float scaleX, float scaleY, Color
|
||||
if((consumed = decode_utf8(&codepoint, (unsigned char*)text)) == -1)
|
||||
break;
|
||||
|
||||
float character_width = scaleX * (fontGetCharWidthInfo(fontGlyphIndexFromCodePoint(codepoint))->charWidth);
|
||||
float character_width = scaleX * (fontGetCharWidthInfo(NULL, fontGlyphIndexFromCodePoint(NULL, codepoint))->charWidth);
|
||||
if((current_width += character_width) > max_width)
|
||||
{
|
||||
char* last_space = NULL;
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
|
||||
FS_Archive ArchiveSD;
|
||||
FS_Archive ArchiveHomeExt;
|
||||
FS_Archive ArchiveThemeExt;
|
||||
|
||||
Result open_archives(void)
|
||||
{
|
||||
@@ -172,6 +176,7 @@ u32 zip_file_to_buf(char *file_name, u16 *zip_path, char **buf)
|
||||
archive_read_support_format_zip(a);
|
||||
|
||||
int r = archive_read_open_filename(a, path, 0x4000);
|
||||
free(path);
|
||||
if(r != ARCHIVE_OK)
|
||||
{
|
||||
DEBUG("Invalid zip being opened\n");
|
||||
@@ -203,4 +208,4 @@ void remake_file(FS_Path path, FS_Archive archive, u32 size)
|
||||
char *buf = calloc(size, 1);
|
||||
buf_to_file(size, path, archive, buf);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,9 +187,27 @@ Result load_entries(const char * loading_path, Entry_List_s * list)
|
||||
if(R_FAILED(res) || entries_read == 0)
|
||||
break;
|
||||
|
||||
if(!(dir_entry.attributes & FS_ATTRIBUTE_DIRECTORY) && strcmp(dir_entry.shortExt, "ZIP"))
|
||||
if(!(dir_entry.attributes & FS_ATTRIBUTE_DIRECTORY) && strcmp(dir_entry.shortExt, "ZIP"))
|
||||
continue;
|
||||
|
||||
u16 path[0x106] = {0};
|
||||
struacat(path, loading_path);
|
||||
strucat(path, dir_entry.name);
|
||||
char * buf = NULL;
|
||||
|
||||
if (!strcmp(dir_entry.shortExt, "ZIP"))
|
||||
{
|
||||
u32 size = zip_file_to_buf("info.smdh", path, &buf);
|
||||
if (size == 0) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
struacat(path, "/info.smdh");
|
||||
u32 size = file_to_buf(fsMakePath(PATH_UTF16, path), ArchiveSD, &buf);
|
||||
if (size == 0) continue;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
list->entries_count++;
|
||||
Entry_s * new_list = realloc(list->entries, list->entries_count * sizeof(Entry_s));
|
||||
if(new_list == NULL)
|
||||
@@ -345,19 +363,18 @@ static bool load_icons(Entry_List_s * current_list, Handle mutex)
|
||||
if(abs(delta) >= current_list->entries_count - current_list->entries_loaded*(ICONS_OFFSET_AMOUNT-1))
|
||||
delta = -SIGN(delta) * (current_list->entries_count - abs(delta));
|
||||
|
||||
int absdelta = abs(delta);
|
||||
int starti = current_list->scroll;
|
||||
int endi = starti + absdelta;
|
||||
int endi = starti + abs(delta);
|
||||
|
||||
if(delta < 0)
|
||||
{
|
||||
endi -= absdelta + 1;
|
||||
starti += absdelta - 1;
|
||||
endi -= abs(delta) + 1;
|
||||
starti += abs(delta) - 1;
|
||||
}
|
||||
|
||||
int ctr = 0;
|
||||
Entry_s ** entries = calloc(absdelta, sizeof(Entry_s *));
|
||||
int * indexes = calloc(absdelta, sizeof(int));
|
||||
Entry_s ** entries = calloc(abs(delta), sizeof(Entry_s *));
|
||||
int * indexes = calloc(abs(delta), sizeof(int));
|
||||
bool released = false;
|
||||
|
||||
C2D_Image ** icons = current_list->icons;
|
||||
@@ -390,38 +407,18 @@ static bool load_icons(Entry_List_s * current_list, Handle mutex)
|
||||
indexes[ctr] = index;
|
||||
}
|
||||
|
||||
static int cutoff[] = {
|
||||
0, // absdelta = 1
|
||||
0, // absdelta = 2
|
||||
0, // absdelta = 3
|
||||
0, // absdelta = 4
|
||||
1, // absdelta = 5, 1 visible to be replaced before allowing drawing
|
||||
2, // absdelta = 6, 2 visible to be replaced before allowing drawing
|
||||
3, // absdelta = 7, 3 visible to be replaced before allowing drawing
|
||||
};
|
||||
int actual_cutoff = cutoff[absdelta-1];
|
||||
if(actual_cutoff == 0)
|
||||
#undef SIGN
|
||||
|
||||
if(abs(delta) < 4)
|
||||
{
|
||||
svcReleaseMutex(mutex);
|
||||
released = true;
|
||||
svcSleepThread(1e7);
|
||||
}
|
||||
|
||||
if(delta > 0)
|
||||
{
|
||||
starti = 0;
|
||||
endi = absdelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
starti = absdelta-1;
|
||||
endi = -1;
|
||||
}
|
||||
|
||||
int change = SIGN(delta);
|
||||
#undef SIGN
|
||||
|
||||
for(int i = starti; i != endi; i += change)
|
||||
svcSleepThread(1e7);
|
||||
starti = 0;
|
||||
endi = abs(delta);
|
||||
for(int i = starti; i < endi; i++)
|
||||
{
|
||||
Entry_s * current_entry = entries[i];
|
||||
int index = indexes[i];
|
||||
@@ -433,11 +430,10 @@ static bool load_icons(Entry_List_s * current_list, Handle mutex)
|
||||
|
||||
icons[index] = load_entry_icon(*current_entry);
|
||||
|
||||
if(!released && i == actual_cutoff)
|
||||
if(!released && i > endi/2)
|
||||
{
|
||||
svcReleaseMutex(mutex);
|
||||
released = true;
|
||||
svcSleepThread(1e7);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,8 +558,12 @@ bool load_preview_from_buffer(void * buf, u32 size, C2D_Image * preview_image, i
|
||||
|
||||
memcpy(preview_image->tex->data + dst, px, sizeof(u32));
|
||||
}
|
||||
|
||||
free(row_pointers[j]);
|
||||
}
|
||||
|
||||
free(row_pointers);
|
||||
|
||||
*preview_offset = (width-400)/2;
|
||||
|
||||
return true;
|
||||
@@ -663,4 +663,4 @@ Result load_audio(Entry_s entry, audio_s *audio)
|
||||
DEBUG("<load_audio> fmemopen failed!\n");
|
||||
return MAKERESULT(RL_FATAL, RS_NOTFOUND, RM_APPLICATION, RD_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -576,10 +576,11 @@ static quirc_decode_error_t codestream_ecc(struct quirc_data *data,
|
||||
&quirc_version_db[data->version];
|
||||
const struct quirc_rs_params *sb_ecc = &ver->ecc[data->ecc_level];
|
||||
struct quirc_rs_params lb_ecc;
|
||||
int bc = ver->data_bytes / sb_ecc->bs;
|
||||
const int lb_count =
|
||||
(ver->data_bytes - sb_ecc->bs * sb_ecc->ns) / (sb_ecc->bs + 1);
|
||||
const int bc = lb_count + sb_ecc->ns;
|
||||
const int ecc_offset = sb_ecc->dw * bc + lb_count;
|
||||
int dst_offset = 0;
|
||||
int lb_count = ver->data_bytes - bc * sb_ecc->bs;
|
||||
int small_dw_total = bc * sb_ecc->dw;
|
||||
int i;
|
||||
|
||||
memcpy(&lb_ecc, sb_ecc, sizeof(lb_ecc));
|
||||
@@ -588,22 +589,16 @@ static quirc_decode_error_t codestream_ecc(struct quirc_data *data,
|
||||
|
||||
for (i = 0; i < bc; i++) {
|
||||
uint8_t *dst = ds->data + dst_offset;
|
||||
const struct quirc_rs_params *ecc = sb_ecc;
|
||||
const struct quirc_rs_params *ecc =
|
||||
(i < sb_ecc->ns) ? sb_ecc : &lb_ecc;
|
||||
const int num_ec = ecc->bs - ecc->dw;
|
||||
quirc_decode_error_t err;
|
||||
int j = 0;
|
||||
int k;
|
||||
int j;
|
||||
|
||||
for (k = 0; k < sb_ecc->dw; k++)
|
||||
dst[j++] = ds->raw[k * bc + i];
|
||||
|
||||
if (i + lb_count >= bc) {
|
||||
dst[j++] = ds->raw[small_dw_total + i - lb_count];
|
||||
ecc = &lb_ecc;
|
||||
}
|
||||
|
||||
for (k = 0; k < sb_ecc->bs - sb_ecc->dw; k++)
|
||||
dst[j++] = ds->raw[small_dw_total + lb_count + i +
|
||||
k * bc];
|
||||
for (j = 0; j < ecc->dw; j++)
|
||||
dst[j] = ds->raw[j * bc + i];
|
||||
for (j = 0; j < num_ec; j++)
|
||||
dst[ecc->dw + j] = ds->raw[ecc_offset + j * bc + i];
|
||||
|
||||
err = correct_block(dst, ecc);
|
||||
if (err)
|
||||
@@ -729,10 +724,10 @@ static quirc_decode_error_t decode_alpha(struct quirc_data *data,
|
||||
int bits = 13;
|
||||
int count;
|
||||
|
||||
if (data->version < 7)
|
||||
if (data->version < 10)
|
||||
bits = 9;
|
||||
else if (data->version < 11)
|
||||
bits = 10;
|
||||
else if (data->version < 27)
|
||||
bits = 11;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
@@ -795,12 +790,18 @@ static quirc_decode_error_t decode_kanji(struct quirc_data *data,
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
int d = take_bits(ds, 13);
|
||||
int msB = d / 0xc0;
|
||||
int lsB = d % 0xc0;
|
||||
int intermediate = (msB << 8) | lsB;
|
||||
uint16_t sjw;
|
||||
|
||||
if (d + 0x8140 >= 0x9ffc)
|
||||
sjw = d + 0x8140;
|
||||
else
|
||||
sjw = d + 0xc140;
|
||||
if (intermediate + 0x8140 <= 0x9ffc) {
|
||||
/* bytes are in the range 0x8140 to 0x9FFC */
|
||||
sjw = intermediate + 0x8140;
|
||||
} else {
|
||||
/* bytes are in the range 0xE040 to 0xEBBF */
|
||||
sjw = intermediate + 0xc140;
|
||||
}
|
||||
|
||||
data->payload[data->payload_len++] = sjw >> 8;
|
||||
data->payload[data->payload_len++] = sjw & 0xff;
|
||||
@@ -873,7 +874,7 @@ static quirc_decode_error_t decode_payload(struct quirc_data *data,
|
||||
done:
|
||||
|
||||
/* Add nul terminator to all payloads */
|
||||
if ((unsigned int)data->payload_len >= sizeof(data->payload))
|
||||
if (data->payload_len >= (int) sizeof(data->payload))
|
||||
data->payload_len--;
|
||||
data->payload[data->payload_len] = 0;
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
@@ -98,8 +99,8 @@ static void perspective_map(const double *c,
|
||||
double x = (c[0]*u + c[1]*v + c[2]) / den;
|
||||
double y = (c[3]*u + c[4]*v + c[5]) / den;
|
||||
|
||||
ret->x = rint(x);
|
||||
ret->y = rint(y);
|
||||
ret->x = (int) rint(x);
|
||||
ret->y = (int) rint(y);
|
||||
}
|
||||
|
||||
static void perspective_unmap(const double *c,
|
||||
@@ -121,234 +122,113 @@ static void perspective_unmap(const double *c,
|
||||
* Span-based floodfill routine
|
||||
*/
|
||||
|
||||
#define FLOOD_FILL_MAX_DEPTH 128
|
||||
|
||||
typedef void (*span_func_t)(void *user_data, int y, int left, int right);
|
||||
|
||||
#if 0 // recursive flood fill
|
||||
|
||||
#define FLOOD_FILL_MAX_DEPTH 4096
|
||||
|
||||
struct flood_fill_params{
|
||||
struct quirc *q;
|
||||
int from;
|
||||
int to;
|
||||
span_func_t func;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
static struct flood_fill_params ffp;
|
||||
|
||||
static void flood_fill_rec(int x, int y, int depth)
|
||||
static void flood_fill_seed(struct quirc *q, int x, int y, int from, int to,
|
||||
span_func_t func, void *user_data,
|
||||
int depth)
|
||||
{
|
||||
int left = x;
|
||||
int right = x;
|
||||
int i;
|
||||
quirc_pixel_t *row = ffp.q->pixels + y * ffp.q->w;
|
||||
quirc_pixel_t *row = q->pixels + y * q->w;
|
||||
|
||||
if (!depth)
|
||||
if (depth >= FLOOD_FILL_MAX_DEPTH)
|
||||
return;
|
||||
|
||||
while (left > 0 && row[left - 1] == ffp.from)
|
||||
while (left > 0 && row[left - 1] == from)
|
||||
left--;
|
||||
|
||||
while (right < ffp.q->w - 1 && row[right + 1] == ffp.from)
|
||||
while (right < q->w - 1 && row[right + 1] == from)
|
||||
right++;
|
||||
|
||||
/* Fill the extent */
|
||||
for (i = left; i <= right; i++)
|
||||
row[i] = ffp.to;
|
||||
row[i] = to;
|
||||
|
||||
if (ffp.func)
|
||||
ffp.func(ffp.user_data, y, left, right);
|
||||
if (func)
|
||||
func(user_data, y, left, right);
|
||||
|
||||
/* Seed new flood-fills */
|
||||
if (y > 0) {
|
||||
row = ffp.q->pixels + (y - 1) * ffp.q->w;
|
||||
row = q->pixels + (y - 1) * q->w;
|
||||
|
||||
for (i = left; i <= right; i++)
|
||||
if (row[i] == ffp.from)
|
||||
flood_fill_rec(i, y - 1, depth - 1);
|
||||
if (row[i] == from)
|
||||
flood_fill_seed(q, i, y - 1, from, to,
|
||||
func, user_data, depth + 1);
|
||||
}
|
||||
|
||||
if (y < ffp.q->h - 1) {
|
||||
row = ffp.q->pixels + (y + 1) * ffp.q->w;
|
||||
if (y < q->h - 1) {
|
||||
row = q->pixels + (y + 1) * q->w;
|
||||
|
||||
for (i = left; i <= right; i++)
|
||||
if (row[i] == ffp.from)
|
||||
flood_fill_rec(i, y + 1, depth - 1);
|
||||
if (row[i] == from)
|
||||
flood_fill_seed(q, i, y + 1, from, to,
|
||||
func, user_data, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void flood_fill_seed(struct quirc *q, int x, int y, int from, int to,
|
||||
span_func_t func, void *user_data)
|
||||
{
|
||||
ffp.q = q;
|
||||
ffp.from = from;
|
||||
ffp.to = to;
|
||||
ffp.func = func;
|
||||
ffp.user_data = user_data;
|
||||
|
||||
flood_fill_rec(x, y, FLOOD_FILL_MAX_DEPTH);
|
||||
}
|
||||
|
||||
#else // stacked flood fill
|
||||
|
||||
#define FILL_STACK_CHUNK_SIZE 0x400
|
||||
|
||||
struct fill_stack_chunk{
|
||||
int x[FILL_STACK_CHUNK_SIZE];
|
||||
int y[FILL_STACK_CHUNK_SIZE];
|
||||
struct fill_stack_chunk *prev;
|
||||
};
|
||||
|
||||
struct fill_stack{
|
||||
struct fill_stack_chunk *last_chunk;
|
||||
int index;
|
||||
};
|
||||
|
||||
static void fill_stack_init(struct fill_stack *s){
|
||||
s->last_chunk = NULL;
|
||||
}
|
||||
|
||||
static int fill_stack_is_empty(struct fill_stack *s){
|
||||
return s->last_chunk == NULL;
|
||||
}
|
||||
|
||||
static void fill_stack_push(struct fill_stack *s, int x, int y){
|
||||
struct fill_stack_chunk *c;
|
||||
if(s->last_chunk != NULL && s->index < FILL_STACK_CHUNK_SIZE - 1){
|
||||
c = s->last_chunk;
|
||||
s->index++;
|
||||
}else{
|
||||
c = (struct fill_stack_chunk*)malloc(sizeof(struct fill_stack_chunk));
|
||||
if(c == NULL){
|
||||
return;
|
||||
}
|
||||
c->prev = s->last_chunk;
|
||||
s->last_chunk = c;
|
||||
s->index = 0;
|
||||
}
|
||||
c->x[s->index] = x;
|
||||
c->y[s->index] = y;
|
||||
}
|
||||
|
||||
static void fill_stack_pop(struct fill_stack *s, int *px, int *py){
|
||||
struct fill_stack_chunk *c = s->last_chunk;
|
||||
if(c == NULL){
|
||||
return;
|
||||
}
|
||||
*px = c->x[s->index];
|
||||
*py = c->y[s->index];
|
||||
if(s->index > 0){
|
||||
s->index--;
|
||||
}else{
|
||||
s->last_chunk = c->prev;
|
||||
s->index = FILL_STACK_CHUNK_SIZE - 1;
|
||||
free(c);
|
||||
}
|
||||
}
|
||||
|
||||
static void flood_fill_seed(struct quirc *q, int start_x, int start_y, int from, int to,
|
||||
span_func_t func, void *user_data)
|
||||
{
|
||||
struct fill_stack s;
|
||||
fill_stack_init(&s);
|
||||
fill_stack_push(&s, start_x, start_y);
|
||||
|
||||
do{
|
||||
int x = 0, y = 0;
|
||||
fill_stack_pop(&s, &x, &y);
|
||||
|
||||
int left = x, right = x, i;
|
||||
quirc_pixel_t *row = q->pixels + y * q->w;
|
||||
|
||||
while (left > 0 && row[left - 1] == from)
|
||||
left--;
|
||||
|
||||
while (right < q->w - 1 && row[right + 1] == from)
|
||||
right++;
|
||||
|
||||
/* Fill the extent */
|
||||
for (i = left; i <= right; i++)
|
||||
row[i] = to;
|
||||
|
||||
if (func)
|
||||
func(user_data, y, left, right);
|
||||
|
||||
/* Seed new flood-fills */
|
||||
if (y > 0) {
|
||||
row = q->pixels + (y - 1) * q->w;
|
||||
|
||||
for (i = left; i <= right; i++)
|
||||
if (row[i] == from)
|
||||
fill_stack_push(&s, i, y - 1);
|
||||
}
|
||||
|
||||
if (y < q->h - 1) {
|
||||
row = q->pixels + (y + 1) * q->w;
|
||||
|
||||
for (i = left; i <= right; i++)
|
||||
if (row[i] == from)
|
||||
fill_stack_push(&s, i, y + 1);
|
||||
}
|
||||
}while(!fill_stack_is_empty(&s));
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************
|
||||
* Adaptive thresholding
|
||||
*/
|
||||
|
||||
#define THRESHOLD_S_DEN 8
|
||||
#define THRESHOLD_T 5
|
||||
|
||||
static void threshold(struct quirc *q)
|
||||
static uint8_t otsu(const struct quirc *q)
|
||||
{
|
||||
int x, y;
|
||||
int avg_w = 0;
|
||||
int avg_u = 0;
|
||||
int threshold_s = q->w / THRESHOLD_S_DEN;
|
||||
quirc_pixel_t *row = q->pixels;
|
||||
int numPixels = q->w * q->h;
|
||||
|
||||
for (y = 0; y < q->h; y++) {
|
||||
int row_average[q->w];
|
||||
|
||||
memset(row_average, 0, sizeof(row_average));
|
||||
|
||||
for (x = 0; x < q->w; x++) {
|
||||
int w, u;
|
||||
|
||||
if (y & 1) {
|
||||
w = x;
|
||||
u = q->w - 1 - x;
|
||||
} else {
|
||||
w = q->w - 1 - x;
|
||||
u = x;
|
||||
}
|
||||
|
||||
avg_w = (avg_w * (threshold_s - 1)) /
|
||||
threshold_s + row[w];
|
||||
avg_u = (avg_u * (threshold_s - 1)) /
|
||||
threshold_s + row[u];
|
||||
|
||||
row_average[w] += avg_w;
|
||||
row_average[u] += avg_u;
|
||||
}
|
||||
|
||||
for (x = 0; x < q->w; x++) {
|
||||
if (row[x] < row_average[x] *
|
||||
(100 - THRESHOLD_T) / (200 * threshold_s))
|
||||
row[x] = QUIRC_PIXEL_BLACK;
|
||||
else
|
||||
row[x] = QUIRC_PIXEL_WHITE;
|
||||
}
|
||||
|
||||
row += q->w;
|
||||
// Calculate histogram
|
||||
const int HISTOGRAM_SIZE = 256;
|
||||
unsigned int histogram[HISTOGRAM_SIZE];
|
||||
memset(histogram, 0, (HISTOGRAM_SIZE) * sizeof(unsigned int));
|
||||
uint8_t* ptr = q->image;
|
||||
int length = numPixels;
|
||||
while (length--) {
|
||||
uint8_t value = *ptr++;
|
||||
histogram[value]++;
|
||||
}
|
||||
|
||||
// Calculate weighted sum of histogram values
|
||||
int sum = 0;
|
||||
for (int i = 0; i < HISTOGRAM_SIZE; ++i) {
|
||||
sum += i * histogram[i];
|
||||
}
|
||||
|
||||
// Compute threshold
|
||||
int sumB = 0;
|
||||
int q1 = 0;
|
||||
double max = 0;
|
||||
uint8_t threshold = 0;
|
||||
for (int i = 0; i < HISTOGRAM_SIZE; ++i) {
|
||||
// Weighted background
|
||||
q1 += histogram[i];
|
||||
if (q1 == 0)
|
||||
continue;
|
||||
|
||||
// Weighted foreground
|
||||
const int q2 = numPixels - q1;
|
||||
if (q2 == 0)
|
||||
break;
|
||||
|
||||
sumB += i * histogram[i];
|
||||
const double m1 = (double)sumB / q1;
|
||||
const double m2 = ((double)sum - sumB) / q2;
|
||||
const double m1m2 = m1 - m2;
|
||||
const double variance = m1m2 * m1m2 * q1 * q2;
|
||||
if (variance >= max) {
|
||||
threshold = i;
|
||||
max = variance;
|
||||
}
|
||||
}
|
||||
|
||||
return threshold;
|
||||
}
|
||||
|
||||
static void area_count(void *user_data, int y, int left, int right)
|
||||
{
|
||||
(void)y;
|
||||
(void)y;
|
||||
((struct quirc_region *)user_data)->count += right - left + 1;
|
||||
}
|
||||
|
||||
@@ -381,7 +261,7 @@ static int region_code(struct quirc *q, int x, int y)
|
||||
box->seed.y = y;
|
||||
box->capstone = -1;
|
||||
|
||||
flood_fill_seed(q, x, y, pixel, region, area_count, box);
|
||||
flood_fill_seed(q, x, y, pixel, region, area_count, box, 0);
|
||||
|
||||
return region;
|
||||
}
|
||||
@@ -451,7 +331,7 @@ static void find_region_corners(struct quirc *q,
|
||||
psd.scores[0] = -1;
|
||||
flood_fill_seed(q, region->seed.x, region->seed.y,
|
||||
rcode, QUIRC_PIXEL_BLACK,
|
||||
find_one_corner, &psd);
|
||||
find_one_corner, &psd, 0);
|
||||
|
||||
psd.ref.x = psd.corners[0].x - psd.ref.x;
|
||||
psd.ref.y = psd.corners[0].y - psd.ref.y;
|
||||
@@ -469,7 +349,7 @@ static void find_region_corners(struct quirc *q,
|
||||
|
||||
flood_fill_seed(q, region->seed.x, region->seed.y,
|
||||
QUIRC_PIXEL_BLACK, rcode,
|
||||
find_other_corners, &psd);
|
||||
find_other_corners, &psd, 0);
|
||||
}
|
||||
|
||||
static void record_capstone(struct quirc *q, int ring, int stone)
|
||||
@@ -542,7 +422,7 @@ static void finder_scan(struct quirc *q, int y)
|
||||
{
|
||||
quirc_pixel_t *row = q->pixels + y * q->w;
|
||||
int x;
|
||||
int last_color;
|
||||
int last_color = 0;
|
||||
int run_length = 0;
|
||||
int run_count = 0;
|
||||
int pb[5];
|
||||
@@ -888,7 +768,7 @@ static int fitness_all(const struct quirc *q, int index)
|
||||
|
||||
/* Check alignment patterns */
|
||||
ap_count = 0;
|
||||
while (info->apat[ap_count])
|
||||
while ((ap_count < QUIRC_MAX_ALIGNMENT) && info->apat[ap_count])
|
||||
ap_count++;
|
||||
|
||||
for (i = 1; i + 1 < ap_count; i++) {
|
||||
@@ -974,7 +854,7 @@ static void rotate_capstone(struct quirc_capstone *cap,
|
||||
struct quirc_point copy[4];
|
||||
int j;
|
||||
int best = 0;
|
||||
int best_score = 0;
|
||||
int best_score = INT_MAX;
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
struct quirc_point *p = &cap->corners[j];
|
||||
@@ -1082,10 +962,10 @@ static void record_qr_grid(struct quirc *q, int a, int b, int c)
|
||||
|
||||
flood_fill_seed(q, reg->seed.x, reg->seed.y,
|
||||
qr->align_region, QUIRC_PIXEL_BLACK,
|
||||
NULL, NULL);
|
||||
NULL, NULL, 0);
|
||||
flood_fill_seed(q, reg->seed.x, reg->seed.y,
|
||||
QUIRC_PIXEL_BLACK, qr->align_region,
|
||||
find_leftmost_to_line, &psd);
|
||||
find_leftmost_to_line, &psd, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1191,17 +1071,18 @@ static void test_grouping(struct quirc *q, int i)
|
||||
test_neighbours(q, i, &hlist, &vlist);
|
||||
}
|
||||
|
||||
static void pixels_setup(struct quirc *q)
|
||||
static void pixels_setup(struct quirc *q, uint8_t threshold)
|
||||
{
|
||||
if (sizeof(*q->image) == sizeof(*q->pixels)) {
|
||||
if (QUIRC_PIXEL_ALIAS_IMAGE) {
|
||||
q->pixels = (quirc_pixel_t *)q->image;
|
||||
} else {
|
||||
int x, y;
|
||||
for (y = 0; y < q->h; y++) {
|
||||
for (x = 0; x < q->w; x++) {
|
||||
q->pixels[y * q->w + x] = q->image[y * q->w + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* source = q->image;
|
||||
quirc_pixel_t* dest = q->pixels;
|
||||
int length = q->w * q->h;
|
||||
while (length--) {
|
||||
uint8_t value = *source++;
|
||||
*dest++ = (value < threshold) ? QUIRC_PIXEL_BLACK : QUIRC_PIXEL_WHITE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1223,8 +1104,8 @@ void quirc_end(struct quirc *q)
|
||||
{
|
||||
int i;
|
||||
|
||||
pixels_setup(q);
|
||||
threshold(q);
|
||||
uint8_t threshold = otsu(q);
|
||||
pixels_setup(q, threshold);
|
||||
|
||||
for (i = 0; i < q->h; i++)
|
||||
finder_scan(q, i);
|
||||
|
||||
@@ -36,34 +36,73 @@ struct quirc *quirc_new(void)
|
||||
|
||||
void quirc_destroy(struct quirc *q)
|
||||
{
|
||||
if (q->image)
|
||||
free(q->image);
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels))
|
||||
free(q->image);
|
||||
/* q->pixels may alias q->image when their type representation is of the
|
||||
same size, so we need to be careful here to avoid a double free */
|
||||
if (!QUIRC_PIXEL_ALIAS_IMAGE)
|
||||
free(q->pixels);
|
||||
|
||||
free(q);
|
||||
}
|
||||
|
||||
int quirc_resize(struct quirc *q, int w, int h)
|
||||
{
|
||||
uint8_t *new_image = realloc(q->image, w * h);
|
||||
uint8_t *image = NULL;
|
||||
quirc_pixel_t *pixels = NULL;
|
||||
|
||||
if (!new_image)
|
||||
return -1;
|
||||
/*
|
||||
* XXX: w and h should be size_t (or at least unsigned) as negatives
|
||||
* values would not make much sense. The downside is that it would break
|
||||
* both the API and ABI. Thus, at the moment, let's just do a sanity
|
||||
* check.
|
||||
*/
|
||||
if (w < 0 || h < 0)
|
||||
goto fail;
|
||||
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels)) {
|
||||
size_t new_size = w * h * sizeof(quirc_pixel_t);
|
||||
quirc_pixel_t *new_pixels = realloc(q->pixels, new_size);
|
||||
if (!new_pixels)
|
||||
return -1;
|
||||
q->pixels = new_pixels;
|
||||
/*
|
||||
* alloc a new buffer for q->image. We avoid realloc(3) because we want
|
||||
* on failure to be leave `q` in a consistant, unmodified state.
|
||||
*/
|
||||
image = calloc(w, h);
|
||||
if (!image)
|
||||
goto fail;
|
||||
|
||||
/* compute the "old" (i.e. currently allocated) and the "new"
|
||||
(i.e. requested) image dimensions */
|
||||
size_t olddim = q->w * q->h;
|
||||
size_t newdim = w * h;
|
||||
size_t min = (olddim < newdim ? olddim : newdim);
|
||||
|
||||
/*
|
||||
* copy the data into the new buffer, avoiding (a) to read beyond the
|
||||
* old buffer when the new size is greater and (b) to write beyond the
|
||||
* new buffer when the new size is smaller, hence the min computation.
|
||||
*/
|
||||
(void)memcpy(image, q->image, min);
|
||||
|
||||
/* alloc a new buffer for q->pixels if needed */
|
||||
if (!QUIRC_PIXEL_ALIAS_IMAGE) {
|
||||
pixels = calloc(newdim, sizeof(quirc_pixel_t));
|
||||
if (!pixels)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
q->image = new_image;
|
||||
/* alloc succeeded, update `q` with the new size and buffers */
|
||||
q->w = w;
|
||||
q->h = h;
|
||||
free(q->image);
|
||||
q->image = image;
|
||||
if (!QUIRC_PIXEL_ALIAS_IMAGE) {
|
||||
free(q->pixels);
|
||||
q->pixels = pixels;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* NOTREACHED */
|
||||
fail:
|
||||
free(image);
|
||||
free(pixels);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int quirc_count(const struct quirc *q)
|
||||
@@ -84,7 +123,6 @@ static const char *const error_table[] = {
|
||||
|
||||
const char *quirc_strerror(quirc_decode_error_t err)
|
||||
{
|
||||
// note from Anemone3DS dev - L88 used to compare err >= 0, but err is always positive
|
||||
if (err < sizeof(error_table) / sizeof(error_table[0]))
|
||||
return error_table[err];
|
||||
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct quirc;
|
||||
|
||||
/* Obtain the library version string. */
|
||||
@@ -117,7 +121,7 @@ struct quirc_code {
|
||||
* is a bitmask giving the actual values of cells. If the cell
|
||||
* at (x, y) is black, then the following bit is set:
|
||||
*
|
||||
* cell_bitmap[i << 3] & (1 << (i & 7))
|
||||
* cell_bitmap[i >> 3] & (1 << (i & 7))
|
||||
*
|
||||
* where i = (y * size) + x.
|
||||
*/
|
||||
@@ -162,4 +166,8 @@ void quirc_extract(const struct quirc *q, int index,
|
||||
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
|
||||
struct quirc_data *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,8 +32,10 @@
|
||||
#define QUIRC_PERSPECTIVE_PARAMS 8
|
||||
|
||||
#if QUIRC_MAX_REGIONS < UINT8_MAX
|
||||
#define QUIRC_PIXEL_ALIAS_IMAGE 1
|
||||
typedef uint8_t quirc_pixel_t;
|
||||
#elif QUIRC_MAX_REGIONS < UINT16_MAX
|
||||
#define QUIRC_PIXEL_ALIAS_IMAGE 0
|
||||
typedef uint16_t quirc_pixel_t;
|
||||
#else
|
||||
#error "QUIRC_MAX_REGIONS > 65534 is not supported"
|
||||
@@ -98,9 +100,9 @@ struct quirc {
|
||||
#define QUIRC_MAX_ALIGNMENT 7
|
||||
|
||||
struct quirc_rs_params {
|
||||
int bs; /* Block size */
|
||||
int dw; /* Data words */
|
||||
int ce; /* Correctable errors */
|
||||
int bs; /* Small block size */
|
||||
int dw; /* Small data words */
|
||||
int ns; /* Number of small blocks */
|
||||
};
|
||||
|
||||
struct quirc_version_info {
|
||||
|
||||
@@ -22,400 +22,400 @@ const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1] = {
|
||||
.data_bytes = 26,
|
||||
.apat = {0},
|
||||
.ecc = {
|
||||
{.bs = 26, .dw = 16, .ce = 4},
|
||||
{.bs = 26, .dw = 19, .ce = 2},
|
||||
{.bs = 26, .dw = 9, .ce = 8},
|
||||
{.bs = 26, .dw = 13, .ce = 6}
|
||||
{.bs = 26, .dw = 16, .ns = 1},
|
||||
{.bs = 26, .dw = 19, .ns = 1},
|
||||
{.bs = 26, .dw = 9, .ns = 1},
|
||||
{.bs = 26, .dw = 13, .ns = 1}
|
||||
}
|
||||
},
|
||||
{ /* Version 2 */
|
||||
.data_bytes = 44,
|
||||
.apat = {6, 18, 0},
|
||||
.ecc = {
|
||||
{.bs = 44, .dw = 28, .ce = 8},
|
||||
{.bs = 44, .dw = 34, .ce = 4},
|
||||
{.bs = 44, .dw = 16, .ce = 14},
|
||||
{.bs = 44, .dw = 22, .ce = 11}
|
||||
{.bs = 44, .dw = 28, .ns = 1},
|
||||
{.bs = 44, .dw = 34, .ns = 1},
|
||||
{.bs = 44, .dw = 16, .ns = 1},
|
||||
{.bs = 44, .dw = 22, .ns = 1}
|
||||
}
|
||||
},
|
||||
{ /* Version 3 */
|
||||
.data_bytes = 70,
|
||||
.apat = {6, 22, 0},
|
||||
.ecc = {
|
||||
{.bs = 70, .dw = 44, .ce = 13},
|
||||
{.bs = 70, .dw = 55, .ce = 7},
|
||||
{.bs = 35, .dw = 13, .ce = 11},
|
||||
{.bs = 35, .dw = 17, .ce = 9}
|
||||
{.bs = 70, .dw = 44, .ns = 1},
|
||||
{.bs = 70, .dw = 55, .ns = 1},
|
||||
{.bs = 35, .dw = 13, .ns = 2},
|
||||
{.bs = 35, .dw = 17, .ns = 2}
|
||||
}
|
||||
},
|
||||
{ /* Version 4 */
|
||||
.data_bytes = 100,
|
||||
.apat = {6, 26, 0},
|
||||
.ecc = {
|
||||
{.bs = 50, .dw = 32, .ce = 9},
|
||||
{.bs = 100, .dw = 80, .ce = 10},
|
||||
{.bs = 25, .dw = 9, .ce = 8},
|
||||
{.bs = 50, .dw = 24, .ce = 13}
|
||||
{.bs = 50, .dw = 32, .ns = 2},
|
||||
{.bs = 100, .dw = 80, .ns = 1},
|
||||
{.bs = 25, .dw = 9, .ns = 4},
|
||||
{.bs = 50, .dw = 24, .ns = 2}
|
||||
}
|
||||
},
|
||||
{ /* Version 5 */
|
||||
.data_bytes = 134,
|
||||
.apat = {6, 30, 0},
|
||||
.ecc = {
|
||||
{.bs = 67, .dw = 43, .ce = 12},
|
||||
{.bs = 134, .dw = 108, .ce = 13},
|
||||
{.bs = 33, .dw = 11, .ce = 11},
|
||||
{.bs = 33, .dw = 15, .ce = 9}
|
||||
{.bs = 67, .dw = 43, .ns = 2},
|
||||
{.bs = 134, .dw = 108, .ns = 1},
|
||||
{.bs = 33, .dw = 11, .ns = 2},
|
||||
{.bs = 33, .dw = 15, .ns = 2}
|
||||
}
|
||||
},
|
||||
{ /* Version 6 */
|
||||
.data_bytes = 172,
|
||||
.apat = {6, 34, 0},
|
||||
.ecc = {
|
||||
{.bs = 43, .dw = 27, .ce = 8},
|
||||
{.bs = 86, .dw = 68, .ce = 9},
|
||||
{.bs = 43, .dw = 15, .ce = 14},
|
||||
{.bs = 43, .dw = 19, .ce = 12}
|
||||
{.bs = 43, .dw = 27, .ns = 4},
|
||||
{.bs = 86, .dw = 68, .ns = 2},
|
||||
{.bs = 43, .dw = 15, .ns = 4},
|
||||
{.bs = 43, .dw = 19, .ns = 4}
|
||||
}
|
||||
},
|
||||
{ /* Version 7 */
|
||||
.data_bytes = 196,
|
||||
.apat = {6, 22, 38, 0},
|
||||
.ecc = {
|
||||
{.bs = 49, .dw = 31, .ce = 9},
|
||||
{.bs = 98, .dw = 78, .ce = 10},
|
||||
{.bs = 39, .dw = 13, .ce = 13},
|
||||
{.bs = 32, .dw = 14, .ce = 9}
|
||||
{.bs = 49, .dw = 31, .ns = 4},
|
||||
{.bs = 98, .dw = 78, .ns = 2},
|
||||
{.bs = 39, .dw = 13, .ns = 4},
|
||||
{.bs = 32, .dw = 14, .ns = 2}
|
||||
}
|
||||
},
|
||||
{ /* Version 8 */
|
||||
.data_bytes = 242,
|
||||
.apat = {6, 24, 42, 0},
|
||||
.ecc = {
|
||||
{.bs = 60, .dw = 38, .ce = 11},
|
||||
{.bs = 121, .dw = 97, .ce = 12},
|
||||
{.bs = 40, .dw = 14, .ce = 13},
|
||||
{.bs = 40, .dw = 18, .ce = 11}
|
||||
{.bs = 60, .dw = 38, .ns = 2},
|
||||
{.bs = 121, .dw = 97, .ns = 2},
|
||||
{.bs = 40, .dw = 14, .ns = 4},
|
||||
{.bs = 40, .dw = 18, .ns = 4}
|
||||
}
|
||||
},
|
||||
{ /* Version 9 */
|
||||
.data_bytes = 292,
|
||||
.apat = {6, 26, 46, 0},
|
||||
.ecc = {
|
||||
{.bs = 58, .dw = 36, .ce = 11},
|
||||
{.bs = 146, .dw = 116, .ce = 15},
|
||||
{.bs = 36, .dw = 12, .ce = 12},
|
||||
{.bs = 36, .dw = 16, .ce = 10}
|
||||
{.bs = 58, .dw = 36, .ns = 3},
|
||||
{.bs = 146, .dw = 116, .ns = 2},
|
||||
{.bs = 36, .dw = 12, .ns = 4},
|
||||
{.bs = 36, .dw = 16, .ns = 4}
|
||||
}
|
||||
},
|
||||
{ /* Version 10 */
|
||||
.data_bytes = 346,
|
||||
.apat = {6, 28, 50, 0},
|
||||
.ecc = {
|
||||
{.bs = 69, .dw = 43, .ce = 13},
|
||||
{.bs = 86, .dw = 68, .ce = 9},
|
||||
{.bs = 43, .dw = 15, .ce = 14},
|
||||
{.bs = 43, .dw = 19, .ce = 12}
|
||||
{.bs = 69, .dw = 43, .ns = 4},
|
||||
{.bs = 86, .dw = 68, .ns = 2},
|
||||
{.bs = 43, .dw = 15, .ns = 6},
|
||||
{.bs = 43, .dw = 19, .ns = 6}
|
||||
}
|
||||
},
|
||||
{ /* Version 11 */
|
||||
.data_bytes = 404,
|
||||
.apat = {6, 30, 54, 0},
|
||||
.ecc = {
|
||||
{.bs = 80, .dw = 50, .ce = 15},
|
||||
{.bs = 101, .dw = 81, .ce = 10},
|
||||
{.bs = 36, .dw = 12, .ce = 12},
|
||||
{.bs = 50, .dw = 22, .ce = 14}
|
||||
{.bs = 80, .dw = 50, .ns = 1},
|
||||
{.bs = 101, .dw = 81, .ns = 4},
|
||||
{.bs = 36, .dw = 12, .ns = 3},
|
||||
{.bs = 50, .dw = 22, .ns = 4}
|
||||
}
|
||||
},
|
||||
{ /* Version 12 */
|
||||
.data_bytes = 466,
|
||||
.apat = {6, 32, 58, 0},
|
||||
.ecc = {
|
||||
{.bs = 58, .dw = 36, .ce = 11},
|
||||
{.bs = 116, .dw = 92, .ce = 12},
|
||||
{.bs = 42, .dw = 14, .ce = 14},
|
||||
{.bs = 46, .dw = 20, .ce = 14}
|
||||
{.bs = 58, .dw = 36, .ns = 6},
|
||||
{.bs = 116, .dw = 92, .ns = 2},
|
||||
{.bs = 42, .dw = 14, .ns = 7},
|
||||
{.bs = 46, .dw = 20, .ns = 4}
|
||||
}
|
||||
},
|
||||
{ /* Version 13 */
|
||||
.data_bytes = 532,
|
||||
.apat = {6, 34, 62, 0},
|
||||
.ecc = {
|
||||
{.bs = 59, .dw = 37, .ce = 11},
|
||||
{.bs = 133, .dw = 107, .ce = 13},
|
||||
{.bs = 33, .dw = 11, .ce = 11},
|
||||
{.bs = 44, .dw = 20, .ce = 12}
|
||||
{.bs = 59, .dw = 37, .ns = 8},
|
||||
{.bs = 133, .dw = 107, .ns = 4},
|
||||
{.bs = 33, .dw = 11, .ns = 12},
|
||||
{.bs = 44, .dw = 20, .ns = 8}
|
||||
}
|
||||
},
|
||||
{ /* Version 14 */
|
||||
.data_bytes = 581,
|
||||
.apat = {6, 26, 46, 66, 0},
|
||||
.ecc = {
|
||||
{.bs = 65, .dw = 41, .ce = 12},
|
||||
{.bs = 109, .dw = 87, .ce = 11},
|
||||
{.bs = 36, .dw = 12, .ce = 12},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 64, .dw = 40, .ns = 4},
|
||||
{.bs = 145, .dw = 115, .ns = 3},
|
||||
{.bs = 36, .dw = 12, .ns = 11},
|
||||
{.bs = 36, .dw = 16, .ns = 11}
|
||||
}
|
||||
},
|
||||
{ /* Version 15 */
|
||||
.data_bytes = 655,
|
||||
.apat = {6, 26, 48, 70, 0},
|
||||
.ecc = {
|
||||
{.bs = 65, .dw = 41, .ce = 12},
|
||||
{.bs = 109, .dw = 87, .ce = 11},
|
||||
{.bs = 36, .dw = 12, .ce = 12},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 65, .dw = 41, .ns = 5},
|
||||
{.bs = 109, .dw = 87, .ns = 5},
|
||||
{.bs = 36, .dw = 12, .ns = 11},
|
||||
{.bs = 54, .dw = 24, .ns = 5}
|
||||
}
|
||||
},
|
||||
{ /* Version 16 */
|
||||
.data_bytes = 733,
|
||||
.apat = {6, 26, 50, 74, 0},
|
||||
.ecc = {
|
||||
{.bs = 73, .dw = 45, .ce = 14},
|
||||
{.bs = 122, .dw = 98, .ce = 12},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 43, .dw = 19, .ce = 12}
|
||||
{.bs = 73, .dw = 45, .ns = 7},
|
||||
{.bs = 122, .dw = 98, .ns = 5},
|
||||
{.bs = 45, .dw = 15, .ns = 3},
|
||||
{.bs = 43, .dw = 19, .ns = 15}
|
||||
}
|
||||
},
|
||||
{ /* Version 17 */
|
||||
.data_bytes = 815,
|
||||
.apat = {6, 30, 54, 78, 0},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ce = 14},
|
||||
{.bs = 135, .dw = 107, .ce = 14},
|
||||
{.bs = 42, .dw = 14, .ce = 14},
|
||||
{.bs = 50, .dw = 22, .ce = 14}
|
||||
{.bs = 74, .dw = 46, .ns = 10},
|
||||
{.bs = 135, .dw = 107, .ns = 1},
|
||||
{.bs = 42, .dw = 14, .ns = 2},
|
||||
{.bs = 50, .dw = 22, .ns = 1}
|
||||
}
|
||||
},
|
||||
{ /* Version 18 */
|
||||
.data_bytes = 901,
|
||||
.apat = {6, 30, 56, 82, 0},
|
||||
.ecc = {
|
||||
{.bs = 69, .dw = 43, .ce = 13},
|
||||
{.bs = 150, .dw = 120, .ce = 15},
|
||||
{.bs = 42, .dw = 14, .ce = 14},
|
||||
{.bs = 50, .dw = 22, .ce = 14}
|
||||
{.bs = 69, .dw = 43, .ns = 9},
|
||||
{.bs = 150, .dw = 120, .ns = 5},
|
||||
{.bs = 42, .dw = 14, .ns = 2},
|
||||
{.bs = 50, .dw = 22, .ns = 17}
|
||||
}
|
||||
},
|
||||
{ /* Version 19 */
|
||||
.data_bytes = 991,
|
||||
.apat = {6, 30, 58, 86, 0},
|
||||
.ecc = {
|
||||
{.bs = 70, .dw = 44, .ce = 13},
|
||||
{.bs = 141, .dw = 113, .ce = 14},
|
||||
{.bs = 39, .dw = 13, .ce = 13},
|
||||
{.bs = 47, .dw = 21, .ce = 13}
|
||||
{.bs = 70, .dw = 44, .ns = 3},
|
||||
{.bs = 141, .dw = 113, .ns = 3},
|
||||
{.bs = 39, .dw = 13, .ns = 9},
|
||||
{.bs = 47, .dw = 21, .ns = 17}
|
||||
}
|
||||
},
|
||||
{ /* Version 20 */
|
||||
.data_bytes = 1085,
|
||||
.apat = {6, 34, 62, 90, 0},
|
||||
.ecc = {
|
||||
{.bs = 67, .dw = 41, .ce = 13},
|
||||
{.bs = 135, .dw = 107, .ce = 14},
|
||||
{.bs = 43, .dw = 15, .ce = 14},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 67, .dw = 41, .ns = 3},
|
||||
{.bs = 135, .dw = 107, .ns = 3},
|
||||
{.bs = 43, .dw = 15, .ns = 15},
|
||||
{.bs = 54, .dw = 24, .ns = 15}
|
||||
}
|
||||
},
|
||||
{ /* Version 21 */
|
||||
.data_bytes = 1156,
|
||||
.apat = {6, 28, 50, 72, 92, 0},
|
||||
.ecc = {
|
||||
{.bs = 68, .dw = 42, .ce = 13},
|
||||
{.bs = 144, .dw = 116, .ce = 14},
|
||||
{.bs = 46, .dw = 16, .ce = 15},
|
||||
{.bs = 50, .dw = 22, .ce = 14}
|
||||
{.bs = 68, .dw = 42, .ns = 17},
|
||||
{.bs = 144, .dw = 116, .ns = 4},
|
||||
{.bs = 46, .dw = 16, .ns = 19},
|
||||
{.bs = 50, .dw = 22, .ns = 17}
|
||||
}
|
||||
},
|
||||
{ /* Version 22 */
|
||||
.data_bytes = 1258,
|
||||
.apat = {6, 26, 50, 74, 98, 0},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ce = 14},
|
||||
{.bs = 139, .dw = 111, .ce = 14},
|
||||
{.bs = 37, .dw = 13, .ce = 12},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 74, .dw = 46, .ns = 17},
|
||||
{.bs = 139, .dw = 111, .ns = 2},
|
||||
{.bs = 37, .dw = 13, .ns = 34},
|
||||
{.bs = 54, .dw = 24, .ns = 7}
|
||||
}
|
||||
},
|
||||
{ /* Version 23 */
|
||||
.data_bytes = 1364,
|
||||
.apat = {6, 30, 54, 78, 102, 0},
|
||||
.ecc = {
|
||||
{.bs = 75, .dw = 47, .ce = 14},
|
||||
{.bs = 151, .dw = 121, .ce = 15},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 75, .dw = 47, .ns = 4},
|
||||
{.bs = 151, .dw = 121, .ns = 4},
|
||||
{.bs = 45, .dw = 15, .ns = 16},
|
||||
{.bs = 54, .dw = 24, .ns = 11}
|
||||
}
|
||||
},
|
||||
{ /* Version 24 */
|
||||
.data_bytes = 1474,
|
||||
.apat = {6, 28, 54, 80, 106, 0},
|
||||
.ecc = {
|
||||
{.bs = 73, .dw = 45, .ce = 14},
|
||||
{.bs = 147, .dw = 117, .ce = 15},
|
||||
{.bs = 46, .dw = 16, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 73, .dw = 45, .ns = 6},
|
||||
{.bs = 147, .dw = 117, .ns = 6},
|
||||
{.bs = 46, .dw = 16, .ns = 30},
|
||||
{.bs = 54, .dw = 24, .ns = 11}
|
||||
}
|
||||
},
|
||||
{ /* Version 25 */
|
||||
.data_bytes = 1588,
|
||||
.apat = {6, 32, 58, 84, 110, 0},
|
||||
.ecc = {
|
||||
{.bs = 75, .dw = 47, .ce = 14},
|
||||
{.bs = 132, .dw = 106, .ce = 13},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 75, .dw = 47, .ns = 8},
|
||||
{.bs = 132, .dw = 106, .ns = 8},
|
||||
{.bs = 45, .dw = 15, .ns = 22},
|
||||
{.bs = 54, .dw = 24, .ns = 7}
|
||||
}
|
||||
},
|
||||
{ /* Version 26 */
|
||||
.data_bytes = 1706,
|
||||
.apat = {6, 30, 58, 86, 114, 0},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ce = 14},
|
||||
{.bs = 142, .dw = 114, .ce = 14},
|
||||
{.bs = 46, .dw = 16, .ce = 15},
|
||||
{.bs = 50, .dw = 22, .ce = 14}
|
||||
{.bs = 74, .dw = 46, .ns = 19},
|
||||
{.bs = 142, .dw = 114, .ns = 10},
|
||||
{.bs = 46, .dw = 16, .ns = 33},
|
||||
{.bs = 50, .dw = 22, .ns = 28}
|
||||
}
|
||||
},
|
||||
{ /* Version 27 */
|
||||
.data_bytes = 1828,
|
||||
.apat = {6, 34, 62, 90, 118, 0},
|
||||
.ecc = {
|
||||
{.bs = 73, .dw = 45, .ce = 14},
|
||||
{.bs = 152, .dw = 122, .ce = 15},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 53, .dw = 23, .ce = 15}
|
||||
{.bs = 73, .dw = 45, .ns = 22},
|
||||
{.bs = 152, .dw = 122, .ns = 8},
|
||||
{.bs = 45, .dw = 15, .ns = 12},
|
||||
{.bs = 53, .dw = 23, .ns = 8}
|
||||
}
|
||||
},
|
||||
{ /* Version 28 */
|
||||
.data_bytes = 1921,
|
||||
.apat = {6, 26, 50, 74, 98, 122, 0},
|
||||
.ecc = {
|
||||
{.bs = 73, .dw = 45, .ce = 14},
|
||||
{.bs = 147, .dw = 117, .ce = 15},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 73, .dw = 45, .ns = 3},
|
||||
{.bs = 147, .dw = 117, .ns = 3},
|
||||
{.bs = 45, .dw = 15, .ns = 11},
|
||||
{.bs = 54, .dw = 24, .ns = 4}
|
||||
}
|
||||
},
|
||||
{ /* Version 29 */
|
||||
.data_bytes = 2051,
|
||||
.apat = {6, 30, 54, 78, 102, 126, 0},
|
||||
.ecc = {
|
||||
{.bs = 73, .dw = 45, .ce = 14},
|
||||
{.bs = 146, .dw = 116, .ce = 15},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 73, .dw = 45, .ce = 14}
|
||||
{.bs = 73, .dw = 45, .ns = 21},
|
||||
{.bs = 146, .dw = 116, .ns = 7},
|
||||
{.bs = 45, .dw = 15, .ns = 19},
|
||||
{.bs = 53, .dw = 23, .ns = 1}
|
||||
}
|
||||
},
|
||||
{ /* Version 30 */
|
||||
.data_bytes = 2185,
|
||||
.apat = {6, 26, 52, 78, 104, 130, 0},
|
||||
.ecc = {
|
||||
{.bs = 75, .dw = 47, .ce = 14},
|
||||
{.bs = 145, .dw = 115, .ce = 15},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 75, .dw = 47, .ns = 19},
|
||||
{.bs = 145, .dw = 115, .ns = 5},
|
||||
{.bs = 45, .dw = 15, .ns = 23},
|
||||
{.bs = 54, .dw = 24, .ns = 15}
|
||||
}
|
||||
},
|
||||
{ /* Version 31 */
|
||||
.data_bytes = 2323,
|
||||
.apat = {6, 30, 56, 82, 108, 134, 0},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ce = 14},
|
||||
{.bs = 145, .dw = 115, .ce = 15},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 74, .dw = 46, .ns = 2},
|
||||
{.bs = 145, .dw = 115, .ns = 13},
|
||||
{.bs = 45, .dw = 15, .ns = 23},
|
||||
{.bs = 54, .dw = 24, .ns = 42}
|
||||
}
|
||||
},
|
||||
{ /* Version 32 */
|
||||
.data_bytes = 2465,
|
||||
.apat = {6, 34, 60, 86, 112, 138, 0},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ce = 14},
|
||||
{.bs = 145, .dw = 115, .ce = 15},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 74, .dw = 46, .ns = 10},
|
||||
{.bs = 145, .dw = 115, .ns = 17},
|
||||
{.bs = 45, .dw = 15, .ns = 19},
|
||||
{.bs = 54, .dw = 24, .ns = 10}
|
||||
}
|
||||
},
|
||||
{ /* Version 33 */
|
||||
.data_bytes = 2611,
|
||||
.apat = {6, 30, 58, 96, 114, 142, 0},
|
||||
.apat = {6, 30, 58, 86, 114, 142, 0},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ce = 14},
|
||||
{.bs = 145, .dw = 115, .ce = 15},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 74, .dw = 46, .ns = 14},
|
||||
{.bs = 145, .dw = 115, .ns = 17},
|
||||
{.bs = 45, .dw = 15, .ns = 11},
|
||||
{.bs = 54, .dw = 24, .ns = 29}
|
||||
}
|
||||
},
|
||||
{ /* Version 34 */
|
||||
.data_bytes = 2761,
|
||||
.apat = {6, 34, 62, 90, 118, 146, 0},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ce = 14},
|
||||
{.bs = 145, .dw = 115, .ce = 15},
|
||||
{.bs = 46, .dw = 16, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 74, .dw = 46, .ns = 14},
|
||||
{.bs = 145, .dw = 115, .ns = 13},
|
||||
{.bs = 46, .dw = 16, .ns = 59},
|
||||
{.bs = 54, .dw = 24, .ns = 44}
|
||||
}
|
||||
},
|
||||
{ /* Version 35 */
|
||||
.data_bytes = 2876,
|
||||
.apat = {6, 30, 54, 78, 102, 126, 150},
|
||||
.ecc = {
|
||||
{.bs = 75, .dw = 47, .ce = 14},
|
||||
{.bs = 151, .dw = 121, .ce = 15},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 75, .dw = 47, .ns = 12},
|
||||
{.bs = 151, .dw = 121, .ns = 12},
|
||||
{.bs = 45, .dw = 15, .ns = 22},
|
||||
{.bs = 54, .dw = 24, .ns = 39}
|
||||
}
|
||||
},
|
||||
{ /* Version 36 */
|
||||
.data_bytes = 3034,
|
||||
.apat = {6, 24, 50, 76, 102, 128, 154},
|
||||
.ecc = {
|
||||
{.bs = 75, .dw = 47, .ce = 14},
|
||||
{.bs = 151, .dw = 121, .ce = 15},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 75, .dw = 47, .ns = 6},
|
||||
{.bs = 151, .dw = 121, .ns = 6},
|
||||
{.bs = 45, .dw = 15, .ns = 2},
|
||||
{.bs = 54, .dw = 24, .ns = 46}
|
||||
}
|
||||
},
|
||||
{ /* Version 37 */
|
||||
.data_bytes = 3196,
|
||||
.apat = {6, 28, 54, 80, 106, 132, 158},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ce = 14},
|
||||
{.bs = 152, .dw = 122, .ce = 15},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 74, .dw = 46, .ns = 29},
|
||||
{.bs = 152, .dw = 122, .ns = 17},
|
||||
{.bs = 45, .dw = 15, .ns = 24},
|
||||
{.bs = 54, .dw = 24, .ns = 49}
|
||||
}
|
||||
},
|
||||
{ /* Version 38 */
|
||||
.data_bytes = 3362,
|
||||
.apat = {6, 32, 58, 84, 110, 136, 162},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ce = 14},
|
||||
{.bs = 152, .dw = 122, .ce = 15},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 74, .dw = 46, .ns = 13},
|
||||
{.bs = 152, .dw = 122, .ns = 4},
|
||||
{.bs = 45, .dw = 15, .ns = 42},
|
||||
{.bs = 54, .dw = 24, .ns = 48}
|
||||
}
|
||||
},
|
||||
{ /* Version 39 */
|
||||
.data_bytes = 3532,
|
||||
.apat = {6, 26, 54, 82, 110, 138, 166},
|
||||
.ecc = {
|
||||
{.bs = 75, .dw = 47, .ce = 14},
|
||||
{.bs = 147, .dw = 117, .ce = 15},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 75, .dw = 47, .ns = 40},
|
||||
{.bs = 147, .dw = 117, .ns = 20},
|
||||
{.bs = 45, .dw = 15, .ns = 10},
|
||||
{.bs = 54, .dw = 24, .ns = 43}
|
||||
}
|
||||
},
|
||||
{ /* Version 40 */
|
||||
.data_bytes = 3706,
|
||||
.apat = {6, 30, 58, 86, 114, 142, 170},
|
||||
.ecc = {
|
||||
{.bs = 75, .dw = 47, .ce = 14},
|
||||
{.bs = 148, .dw = 118, .ce = 15},
|
||||
{.bs = 45, .dw = 15, .ce = 15},
|
||||
{.bs = 54, .dw = 24, .ce = 15}
|
||||
{.bs = 75, .dw = 47, .ns = 18},
|
||||
{.bs = 148, .dw = 118, .ns = 19},
|
||||
{.bs = 45, .dw = 15, .ns = 20},
|
||||
{.bs = 54, .dw = 24, .ns = 34}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -193,6 +193,8 @@ static void load_remote_list(Entry_List_s * list, json_int_t page, EntryMode mod
|
||||
if(page <= 0)
|
||||
page = list->tp_page_count;
|
||||
|
||||
list->selected_entry = 0;
|
||||
|
||||
InstallType loading_screen = INSTALL_NONE;
|
||||
if(mode == MODE_THEMES)
|
||||
loading_screen = INSTALL_LOADING_REMOTE_THEMES;
|
||||
@@ -807,8 +809,7 @@ u32 http_get(const char *url, char ** filename, char ** buf, InstallType install
|
||||
return 0;
|
||||
}
|
||||
|
||||
char * tok = strtok(content_disposition, "\"");
|
||||
tok = strtok(NULL, "\"");
|
||||
char * tok = strstr(content_disposition, "filename=");
|
||||
|
||||
if(!(tok))
|
||||
{
|
||||
@@ -820,6 +821,17 @@ u32 http_get(const char *url, char ** filename, char ** buf, InstallType install
|
||||
return 0;
|
||||
}
|
||||
|
||||
tok += sizeof("filename=") - 1;
|
||||
if(ispunct((int)*tok))
|
||||
{
|
||||
tok++;
|
||||
}
|
||||
char* last_char = tok + strlen(tok) - 1;
|
||||
if(ispunct((int)*last_char))
|
||||
{
|
||||
*last_char = '\0';
|
||||
}
|
||||
|
||||
char *illegal_characters = "\"?;:/\\+";
|
||||
for (size_t i = 0; i < strlen(tok); i++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user