clangformat everything
This commit is contained in:
@@ -1,15 +1,11 @@
|
||||
#include "about.h"
|
||||
#include "ui_about.h"
|
||||
|
||||
About::About(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::About)
|
||||
{
|
||||
About::About(QWidget* parent) : QDialog(parent), ui(new Ui::About) {
|
||||
ui->setupUi(this);
|
||||
ui->lblVersion->setText(ui->lblVersion->text() + " " + __DATE__ + " " + __TIME__);
|
||||
}
|
||||
|
||||
About::~About()
|
||||
{
|
||||
About::~About() {
|
||||
delete ui;
|
||||
}
|
||||
|
||||
@@ -7,16 +7,15 @@ namespace Ui {
|
||||
class About;
|
||||
}
|
||||
|
||||
class About : public QDialog
|
||||
{
|
||||
class About : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit About(QWidget *parent = nullptr);
|
||||
public:
|
||||
explicit About(QWidget* parent = nullptr);
|
||||
~About();
|
||||
|
||||
private:
|
||||
Ui::About *ui;
|
||||
private:
|
||||
Ui::About* ui;
|
||||
};
|
||||
|
||||
#endif // ABOUT_H
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int main(int argc, char* argv[]) {
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
@@ -1,107 +1,97 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "QUdpSocket"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::MainWindow)
|
||||
{
|
||||
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
|
||||
ui->setupUi(this);
|
||||
m_udpSocket = new QUdpSocket(this);
|
||||
m_udpSocket->bind(QHostAddress::Any, UDP_PORT, QUdpSocket::ShareAddress);
|
||||
|
||||
connect(m_udpSocket, &QUdpSocket::readyRead,
|
||||
this, &MainWindow::processPendingDatagrams);
|
||||
connect(m_udpSocket, &QUdpSocket::readyRead, this, &MainWindow::processPendingDatagrams);
|
||||
|
||||
//Timer just to ask twice (udp)
|
||||
// Timer just to ask twice (udp)
|
||||
m_timer = new QTimer(this);
|
||||
m_timer->setSingleShot(true);
|
||||
m_timer->setInterval(500);
|
||||
connect(m_timer,&QTimer::timeout, this, &MainWindow::SendRequest);
|
||||
connect(m_timer, &QTimer::timeout, this, &MainWindow::SendRequest);
|
||||
|
||||
//Send Request on startup
|
||||
// Send Request on startup
|
||||
on_pbRefresh_clicked();
|
||||
|
||||
ui->devices->setIconSize(QSize(48,48));
|
||||
ui->devices->setIconSize(QSize(48, 48));
|
||||
ui->devices->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
ui->comboBox->addItem("default");
|
||||
ui->comboBox->addItem("192.168.69.10"); //test
|
||||
if (ui->comboBox->currentText()=="default"){
|
||||
ui->comboBox->addItem("192.168.69.10"); // test
|
||||
if (ui->comboBox->currentText() == "default") {
|
||||
ui->ChangeOwner->setDisabled(true);
|
||||
}
|
||||
|
||||
// //Example items for screenshot:
|
||||
// QListWidgetItem * item = new QListWidgetItem(QIcon(":/res/stm32.png"), "00:80:E1:05:44:21 @ 192.168.0.11 (John Doe)");
|
||||
// ui->devices->addItem(item);
|
||||
// QListWidgetItem * item2 = new QListWidgetItem(QIcon(":/res/rpi.png"), "E4:5F:01:05:44:21 @ 192.168.0.11 (Jane Doe)");
|
||||
// ui->devices->addItem(item2);
|
||||
// QListWidgetItem * item3 = new QListWidgetItem(QIcon(":/res/unknown.png"), "44:44:44:05:44:21 @ 192.168.0.11 (Juul Doe)");
|
||||
// ui->devices->addItem(item3);
|
||||
// //Example items for screenshot:
|
||||
// QListWidgetItem * item = new QListWidgetItem(QIcon(":/res/stm32.png"), "00:80:E1:05:44:21 @ 192.168.0.11 (John
|
||||
// Doe)"); ui->devices->addItem(item); QListWidgetItem * item2 = new QListWidgetItem(QIcon(":/res/rpi.png"),
|
||||
// "E4:5F:01:05:44:21 @ 192.168.0.11 (Jane Doe)"); ui->devices->addItem(item2); QListWidgetItem * item3 = new
|
||||
// QListWidgetItem(QIcon(":/res/unknown.png"), "44:44:44:05:44:21 @ 192.168.0.11 (Juul Doe)");
|
||||
// ui->devices->addItem(item3);
|
||||
connect(ui->actionAbout_Qt, &QAction::triggered, QApplication::aboutQt);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
MainWindow::~MainWindow() {
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void MainWindow::on_pbRefresh_clicked()
|
||||
{
|
||||
void MainWindow::on_pbRefresh_clicked() {
|
||||
this->func = 0;
|
||||
SendRequest();
|
||||
m_timer->start();
|
||||
}
|
||||
|
||||
void MainWindow::SendRequest()
|
||||
{
|
||||
void MainWindow::SendRequest() {
|
||||
int broadcasts_send = 0;
|
||||
int data_send = 0;
|
||||
QUdpSocket udpSocket;
|
||||
QByteArray datagram;
|
||||
if(this->func == 0){
|
||||
datagram = UDP_REQUEST"v1.0";
|
||||
//Get all the Network Interface Cards of this Computer
|
||||
if (this->func == 0) {
|
||||
datagram = UDP_REQUEST "v1.0";
|
||||
// Get all the Network Interface Cards of this Computer
|
||||
QList<QNetworkInterface> NICs = QNetworkInterface::allInterfaces();
|
||||
foreach(QNetworkInterface NIC, NICs){
|
||||
//Get all the adresses on this NIC
|
||||
foreach (QNetworkInterface NIC, NICs) {
|
||||
// Get all the adresses on this NIC
|
||||
QList<QNetworkAddressEntry> adresses = NIC.addressEntries();
|
||||
foreach(QNetworkAddressEntry adress, adresses){
|
||||
foreach (QNetworkAddressEntry adress, adresses) {
|
||||
QD << NIC.name() << adress.ip();
|
||||
//If broadcast adress = null => IPv6 (no support for broadcasts)
|
||||
// If broadcast adress = null => IPv6 (no support for broadcasts)
|
||||
QHostAddress broadc_addr = adress.broadcast();
|
||||
if(!broadc_addr.isNull()){
|
||||
//Send UDP packet
|
||||
if (!broadc_addr.isNull()) {
|
||||
// Send UDP packet
|
||||
udpSocket.writeDatagram(datagram, adress.broadcast(), UDP_PORT);
|
||||
broadcasts_send++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(this->func == 1){
|
||||
} else if (this->func == 1) {
|
||||
QHostAddress addr(ui->comboBox->currentText());
|
||||
udpSocket.writeDatagram(this->data, addr, UDP_PORT);
|
||||
data_send++;
|
||||
}
|
||||
|
||||
|
||||
if(broadcasts_send == 0 && data_send == 0){
|
||||
ui->pteLog->appendPlainText("Warning: no Network Interface Cards or valid IP adresses found (no broadcasts send)");
|
||||
}else if(data_send != 0){
|
||||
if (broadcasts_send == 0 && data_send == 0) {
|
||||
ui->pteLog->appendPlainText(
|
||||
"Warning: no Network Interface Cards or valid IP adresses found (no broadcasts send)");
|
||||
} else if (data_send != 0) {
|
||||
ui->pteLog->appendPlainText(tr("Info: %1 message sent to %2").arg(data_send).arg(ui->comboBox->currentText()));
|
||||
}else{
|
||||
} else {
|
||||
ui->pteLog->appendPlainText(tr("Info: %1 broadcasts send").arg(broadcasts_send));
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::processPendingDatagrams()
|
||||
{
|
||||
void MainWindow::processPendingDatagrams() {
|
||||
QByteArray datagram;
|
||||
QHostAddress host;
|
||||
|
||||
// just get rid of every host in the combobox, not pretty code, i know
|
||||
if(this->func == 0){
|
||||
for(int i = 1; i < ui->comboBox->count(); i++){
|
||||
if (this->func == 0) {
|
||||
for (int i = 1; i < ui->comboBox->count(); i++) {
|
||||
ui->comboBox->removeItem(i);
|
||||
}
|
||||
}
|
||||
@@ -114,74 +104,69 @@ void MainWindow::processPendingDatagrams()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::processDatagram(QString msg,QString host)
|
||||
{
|
||||
|
||||
//Append received data to log
|
||||
QString logLine = tr("Van %1: \"%2\"")
|
||||
.arg(host)
|
||||
.arg(msg);
|
||||
void MainWindow::processDatagram(QString msg, QString host) {
|
||||
// Append received data to log
|
||||
QString logLine = tr("Van %1: \"%2\"").arg(host).arg(msg);
|
||||
ui->pteLog->appendPlainText(logLine);
|
||||
|
||||
//We receive our own request. So a check to see if it is the request:
|
||||
if(msg.indexOf(UDP_REQUEST) != -1){
|
||||
return; //we are done here...
|
||||
// We receive our own request. So a check to see if it is the request:
|
||||
if (msg.indexOf(UDP_REQUEST) != -1) {
|
||||
return; // we are done here...
|
||||
}
|
||||
|
||||
// add new host to select in combobox
|
||||
if(this->func == 0){
|
||||
if (this->func == 0) {
|
||||
ui->comboBox->addItem(host);
|
||||
}
|
||||
|
||||
|
||||
//RegEx for MAC adress
|
||||
QRegularExpression macRegExp("([0-9A-F]{2})[:-]([0-9A-F]{2})[:-]([0-9A-F]{2})[:-]([0-9A-F]{2})[:-]([0-9A-F]{2})[:-]([0-9A-F]{2})");
|
||||
// RegEx for MAC adress
|
||||
QRegularExpression macRegExp(
|
||||
"([0-9A-F]{2})[:-]([0-9A-F]{2})[:-]([0-9A-F]{2})[:-]([0-9A-F]{2})[:-]([0-9A-F]{2})[:-]([0-9A-F]{2})");
|
||||
QRegularExpressionMatch match = macRegExp.match(msg.toUpper());
|
||||
if(match.hasMatch()){
|
||||
if (match.hasMatch()) {
|
||||
QString foundOUI = match.captured(1) % match.captured(2) % match.captured(3);
|
||||
QString foundMAC = match.captured(0);
|
||||
QString imgName = ":/res/unknown.png";
|
||||
/*grep STMicro oui.txt | grep base
|
||||
0080E1 (base 16) STMicroelectronics SRL
|
||||
10E77A (base 16) STMicrolectronics International NV*/
|
||||
if(foundOUI == "0080E1" || foundOUI == "10E77A") {
|
||||
if (foundOUI == "0080E1" || foundOUI == "10E77A") {
|
||||
imgName = ":/res/stm32.png";
|
||||
}
|
||||
/*grep Raspberry oui.txt | grep base
|
||||
DCA632 (base 16) Raspberry Pi Trading Ltd
|
||||
E45F01 (base 16) Raspberry Pi Trading Ltd
|
||||
B827EB (base 16) Raspberry Pi Foundation*/
|
||||
if(foundOUI == "DCA632" || foundOUI == "E45F01" || foundOUI == "B827EB") {
|
||||
if (foundOUI == "DCA632" || foundOUI == "E45F01" || foundOUI == "B827EB") {
|
||||
imgName = ":/res/rpi.png";
|
||||
}
|
||||
QString needle = UDP_ANS_OWNER;
|
||||
QString owner = "???";
|
||||
int index = msg.indexOf(needle);
|
||||
if(index != -1){
|
||||
if (index != -1) {
|
||||
owner = msg.mid(index + needle.length());
|
||||
}else{
|
||||
} else {
|
||||
ui->pteLog->appendPlainText("Warning: no OWNER found in message");
|
||||
}
|
||||
|
||||
QListWidgetItem * item = searchItem(foundMAC);
|
||||
if(item == nullptr){
|
||||
QListWidgetItem* item = searchItem(foundMAC);
|
||||
if (item == nullptr) {
|
||||
item = new QListWidgetItem();
|
||||
ui->devices->addItem(item);
|
||||
}
|
||||
item->setIcon(QIcon(imgName));
|
||||
item->setText(tr("%1 @ %2 (%3)").arg(foundMAC).arg(host).arg(owner));
|
||||
item->setToolTip(tr("Last seen: %1").arg(QTime::currentTime().toString("H:mm:ss.zzz")));
|
||||
}else{
|
||||
} else {
|
||||
ui->pteLog->appendPlainText("Warning: no MAC found in message");
|
||||
}
|
||||
}
|
||||
|
||||
QListWidgetItem *MainWindow::searchItem(QString MAC)
|
||||
{
|
||||
QListWidgetItem * item = nullptr;
|
||||
for(int i = 0; i < ui->devices->count(); i++){
|
||||
QListWidgetItem* MainWindow::searchItem(QString MAC) {
|
||||
QListWidgetItem* item = nullptr;
|
||||
for (int i = 0; i < ui->devices->count(); i++) {
|
||||
item = ui->devices->item(i);
|
||||
if(item->text().contains(MAC)){
|
||||
if (item->text().contains(MAC)) {
|
||||
break;
|
||||
}
|
||||
item = nullptr;
|
||||
@@ -189,70 +174,56 @@ QListWidgetItem *MainWindow::searchItem(QString MAC)
|
||||
return item;
|
||||
}
|
||||
|
||||
void MainWindow::on_devices_itemDoubleClicked(QListWidgetItem *item)
|
||||
{
|
||||
//Copy the IP to the clipboard
|
||||
void MainWindow::on_devices_itemDoubleClicked(QListWidgetItem* item) {
|
||||
// Copy the IP to the clipboard
|
||||
QString itemText = item->text();
|
||||
int start = itemText.indexOf('@')+2;
|
||||
int end = itemText.indexOf('(')-1;
|
||||
QString ip = itemText.mid(start,end - start);
|
||||
QClipboard *clipboard = QGuiApplication::clipboard();
|
||||
int start = itemText.indexOf('@') + 2;
|
||||
int end = itemText.indexOf('(') - 1;
|
||||
QString ip = itemText.mid(start, end - start);
|
||||
QClipboard* clipboard = QGuiApplication::clipboard();
|
||||
clipboard->setText(ip);
|
||||
}
|
||||
|
||||
void MainWindow::on_devices_customContextMenuRequested(const QPoint &pos)
|
||||
{
|
||||
//create menu
|
||||
QAction copyAction(QIcon(":/res/copy-icon.png"),"Copy IP");
|
||||
void MainWindow::on_devices_customContextMenuRequested(const QPoint& pos) {
|
||||
// create menu
|
||||
QAction copyAction(QIcon(":/res/copy-icon.png"), "Copy IP");
|
||||
QMenu menu;
|
||||
menu.addAction(©Action);
|
||||
|
||||
//execute menu
|
||||
QAction * action = menu.exec(ui->devices->mapToGlobal(pos));
|
||||
if(action == ©Action){
|
||||
QListWidgetItem *item = ui->devices->itemAt(pos);
|
||||
if(item){
|
||||
// execute menu
|
||||
QAction* action = menu.exec(ui->devices->mapToGlobal(pos));
|
||||
if (action == ©Action) {
|
||||
QListWidgetItem* item = ui->devices->itemAt(pos);
|
||||
if (item) {
|
||||
on_devices_itemDoubleClicked(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionAbout_triggered()
|
||||
{
|
||||
void MainWindow::on_actionAbout_triggered() {
|
||||
About ab(this);
|
||||
ab.exec();
|
||||
}
|
||||
|
||||
void MainWindow::on_name_textEdited(const QString &arg1)
|
||||
{
|
||||
void MainWindow::on_name_textEdited(const QString& arg1) {
|
||||
this->name = arg1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MainWindow::on_surname_textEdited(const QString &arg1)
|
||||
{
|
||||
void MainWindow::on_surname_textEdited(const QString& arg1) {
|
||||
this->surname = arg1;
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_comboBox_currentIndexChanged(int index)
|
||||
{
|
||||
if(index == 0){
|
||||
void MainWindow::on_comboBox_currentIndexChanged(int index) {
|
||||
if (index == 0) {
|
||||
ui->ChangeOwner->setDisabled(true);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
ui->ChangeOwner->setDisabled(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_ChangeOwner_clicked()
|
||||
{
|
||||
void MainWindow::on_ChangeOwner_clicked() {
|
||||
this->data = ("func1:name: " + this->name + ", surname: " + this->surname + "").toUtf8();
|
||||
this->func = 1;
|
||||
SendRequest();
|
||||
m_timer->start();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,52 +6,53 @@
|
||||
#include <QtWidgets>
|
||||
#define QD qDebug() << __FILE__ << __LINE__
|
||||
|
||||
#include "about.h"
|
||||
#include <QString>
|
||||
#include "about.h"
|
||||
|
||||
// UDP protocol:
|
||||
//REQ= Where are you?v1.0
|
||||
//ANS= XX:XX:XX:XX:XX:XX is present and my owner is YYYYYY ZZZZZZ
|
||||
// REQ= Where are you?v1.0
|
||||
// ANS= XX:XX:XX:XX:XX:XX is present and my owner is YYYYYY ZZZZZZ
|
||||
#define UDP_PORT 64000
|
||||
#define UDP_REQUEST "Where are you?"
|
||||
#define UDP_ANS_OWNER "my owner is "
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class MainWindow; }
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
public:
|
||||
MainWindow(QWidget* parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
private slots:
|
||||
private slots:
|
||||
void SendRequest();
|
||||
void processPendingDatagrams();
|
||||
|
||||
void on_pbRefresh_clicked();
|
||||
void on_devices_itemDoubleClicked(QListWidgetItem *item);
|
||||
void on_devices_customContextMenuRequested(const QPoint &pos);
|
||||
void on_devices_itemDoubleClicked(QListWidgetItem* item);
|
||||
void on_devices_customContextMenuRequested(const QPoint& pos);
|
||||
|
||||
void on_actionAbout_triggered();
|
||||
|
||||
void on_name_textEdited(const QString &arg1);
|
||||
void on_name_textEdited(const QString& arg1);
|
||||
|
||||
void on_surname_textEdited(const QString &arg1);
|
||||
void on_surname_textEdited(const QString& arg1);
|
||||
|
||||
void on_comboBox_currentIndexChanged(int index);
|
||||
|
||||
void on_ChangeOwner_clicked();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
QTimer * m_timer;
|
||||
QUdpSocket *m_udpSocket = nullptr;
|
||||
private:
|
||||
Ui::MainWindow* ui;
|
||||
QTimer* m_timer;
|
||||
QUdpSocket* m_udpSocket = nullptr;
|
||||
void processDatagram(QString msg, QString host);
|
||||
QListWidgetItem *searchItem(QString MAC);
|
||||
QListWidgetItem* searchItem(QString MAC);
|
||||
QString name;
|
||||
QString surname;
|
||||
QByteArray data;
|
||||
|
||||
@@ -60,7 +60,8 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
// Write the header of the output file
|
||||
fprintf(out_file, "/**\n"
|
||||
fprintf(out_file,
|
||||
"/**\n"
|
||||
" * @file %s\n"
|
||||
" * @brief Linked list file system (llfs) data file.\n"
|
||||
" * This file was generated by mkllfs %s.\n"
|
||||
@@ -125,7 +126,8 @@ int main(int argc, char** argv) {
|
||||
|
||||
// Make the last file the root file of the llfs
|
||||
fprintf(out_file, "\n");
|
||||
fprintf(out_file, "const struct llfs_data_file *llfs_root =%s%s;\n", (strcmp(prev_llfs_name, "NULL") == 0 ? " " : " &"), prev_llfs_name);
|
||||
fprintf(out_file, "const struct llfs_data_file *llfs_root =%s%s;\n",
|
||||
(strcmp(prev_llfs_name, "NULL") == 0 ? " " : " &"), prev_llfs_name);
|
||||
|
||||
// Print the number of files
|
||||
printf("Successfully converted %d files.\r\n", file_count);
|
||||
|
||||
425
mkllfs/tinydir.h
425
mkllfs/tinydir.h
@@ -45,63 +45,62 @@ extern "C" {
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef _MSC_VER
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# include <tchar.h>
|
||||
# pragma warning(push)
|
||||
# pragma warning (disable : 4996)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <tchar.h>
|
||||
#include <windows.h>
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996)
|
||||
#else
|
||||
# include <dirent.h>
|
||||
# include <libgen.h>
|
||||
# include <sys/stat.h>
|
||||
# include <stddef.h>
|
||||
#include <dirent.h>
|
||||
#include <libgen.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef __MINGW32__
|
||||
# include <tchar.h>
|
||||
#include <tchar.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* types */
|
||||
|
||||
/* Windows UNICODE wide character support */
|
||||
#if defined _MSC_VER || defined __MINGW32__
|
||||
# define _tinydir_char_t TCHAR
|
||||
# define TINYDIR_STRING(s) _TEXT(s)
|
||||
# define _tinydir_strlen _tcslen
|
||||
# define _tinydir_strcpy _tcscpy
|
||||
# define _tinydir_strcat _tcscat
|
||||
# define _tinydir_strcmp _tcscmp
|
||||
# define _tinydir_strrchr _tcsrchr
|
||||
# define _tinydir_strncmp _tcsncmp
|
||||
#define _tinydir_char_t TCHAR
|
||||
#define TINYDIR_STRING(s) _TEXT(s)
|
||||
#define _tinydir_strlen _tcslen
|
||||
#define _tinydir_strcpy _tcscpy
|
||||
#define _tinydir_strcat _tcscat
|
||||
#define _tinydir_strcmp _tcscmp
|
||||
#define _tinydir_strrchr _tcsrchr
|
||||
#define _tinydir_strncmp _tcsncmp
|
||||
#else
|
||||
# define _tinydir_char_t char
|
||||
# define TINYDIR_STRING(s) s
|
||||
# define _tinydir_strlen strlen
|
||||
# define _tinydir_strcpy strcpy
|
||||
# define _tinydir_strcat strcat
|
||||
# define _tinydir_strcmp strcmp
|
||||
# define _tinydir_strrchr strrchr
|
||||
# define _tinydir_strncmp strncmp
|
||||
#define _tinydir_char_t char
|
||||
#define TINYDIR_STRING(s) s
|
||||
#define _tinydir_strlen strlen
|
||||
#define _tinydir_strcpy strcpy
|
||||
#define _tinydir_strcat strcat
|
||||
#define _tinydir_strcmp strcmp
|
||||
#define _tinydir_strrchr strrchr
|
||||
#define _tinydir_strncmp strncmp
|
||||
#endif
|
||||
|
||||
#if (defined _MSC_VER || defined __MINGW32__)
|
||||
# include <windows.h>
|
||||
# define _TINYDIR_PATH_MAX MAX_PATH
|
||||
#include <windows.h>
|
||||
#define _TINYDIR_PATH_MAX MAX_PATH
|
||||
#elif defined __linux__
|
||||
# include <limits.h>
|
||||
# ifdef PATH_MAX
|
||||
# define _TINYDIR_PATH_MAX PATH_MAX
|
||||
# endif
|
||||
#include <limits.h>
|
||||
#ifdef PATH_MAX
|
||||
#define _TINYDIR_PATH_MAX PATH_MAX
|
||||
#endif
|
||||
#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
||||
# include <sys/param.h>
|
||||
# if defined(BSD)
|
||||
# include <limits.h>
|
||||
# ifdef PATH_MAX
|
||||
# define _TINYDIR_PATH_MAX PATH_MAX
|
||||
# endif
|
||||
# endif
|
||||
#include <sys/param.h>
|
||||
#if defined(BSD)
|
||||
#include <limits.h>
|
||||
#ifdef PATH_MAX
|
||||
#define _TINYDIR_PATH_MAX PATH_MAX
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _TINYDIR_PATH_MAX
|
||||
@@ -110,9 +109,9 @@ extern "C" {
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* extra chars for the "\\*" mask */
|
||||
# define _TINYDIR_PATH_EXTRA 2
|
||||
#define _TINYDIR_PATH_EXTRA 2
|
||||
#else
|
||||
# define _TINYDIR_PATH_EXTRA 0
|
||||
#define _TINYDIR_PATH_EXTRA 0
|
||||
#endif
|
||||
|
||||
#define _TINYDIR_FILENAME_MAX 256
|
||||
@@ -122,16 +121,16 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define _TINYDIR_FUNC static __inline
|
||||
#define _TINYDIR_FUNC static __inline
|
||||
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||
# define _TINYDIR_FUNC static __inline__
|
||||
#define _TINYDIR_FUNC static __inline__
|
||||
#elif defined(__cplusplus)
|
||||
# define _TINYDIR_FUNC static inline
|
||||
#define _TINYDIR_FUNC static inline
|
||||
#elif defined(__GNUC__)
|
||||
/* Suppress unused function warning */
|
||||
# define _TINYDIR_FUNC __attribute__((unused)) static
|
||||
#define _TINYDIR_FUNC __attribute__((unused)) static
|
||||
#else
|
||||
# define _TINYDIR_FUNC static
|
||||
#define _TINYDIR_FUNC static
|
||||
#endif
|
||||
|
||||
/* readdir_r usage; define TINYDIR_USE_READDIR_R to use it (if supported) */
|
||||
@@ -139,31 +138,27 @@ extern "C" {
|
||||
|
||||
/* readdir_r is a POSIX-only function, and may not be available under various
|
||||
* environments/settings, e.g. MinGW. Use readdir fallback */
|
||||
#if _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE ||\
|
||||
_POSIX_SOURCE
|
||||
# define _TINYDIR_HAS_READDIR_R
|
||||
#if _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE || _POSIX_SOURCE
|
||||
#define _TINYDIR_HAS_READDIR_R
|
||||
#endif
|
||||
#if _POSIX_C_SOURCE >= 200112L
|
||||
# define _TINYDIR_HAS_FPATHCONF
|
||||
# include <unistd.h>
|
||||
#define _TINYDIR_HAS_FPATHCONF
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if _BSD_SOURCE || _SVID_SOURCE || \
|
||||
(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)
|
||||
# define _TINYDIR_HAS_DIRFD
|
||||
# include <sys/types.h>
|
||||
#if _BSD_SOURCE || _SVID_SOURCE || (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)
|
||||
#define _TINYDIR_HAS_DIRFD
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if defined _TINYDIR_HAS_FPATHCONF && defined _TINYDIR_HAS_DIRFD &&\
|
||||
defined _PC_NAME_MAX
|
||||
# define _TINYDIR_USE_FPATHCONF
|
||||
#if defined _TINYDIR_HAS_FPATHCONF && defined _TINYDIR_HAS_DIRFD && defined _PC_NAME_MAX
|
||||
#define _TINYDIR_USE_FPATHCONF
|
||||
#endif
|
||||
#if defined __MINGW32__ || !defined _TINYDIR_HAS_READDIR_R ||\
|
||||
!(defined _TINYDIR_USE_FPATHCONF || defined NAME_MAX)
|
||||
# define _TINYDIR_USE_READDIR
|
||||
#if defined __MINGW32__ || !defined _TINYDIR_HAS_READDIR_R || !(defined _TINYDIR_USE_FPATHCONF || defined NAME_MAX)
|
||||
#define _TINYDIR_USE_READDIR
|
||||
#endif
|
||||
|
||||
/* Use readdir by default */
|
||||
#else
|
||||
# define _TINYDIR_USE_READDIR
|
||||
#define _TINYDIR_USE_READDIR
|
||||
#endif
|
||||
|
||||
/* MINGW32 has two versions of dirent, ASCII and UNICODE*/
|
||||
@@ -195,11 +190,10 @@ extern "C" {
|
||||
#define _TINYDIR_FREE(_ptr) free(_ptr)
|
||||
#endif /* !defined(_TINYDIR_MALLOC) */
|
||||
|
||||
typedef struct tinydir_file
|
||||
{
|
||||
typedef struct tinydir_file {
|
||||
_tinydir_char_t path[_TINYDIR_PATH_MAX];
|
||||
_tinydir_char_t name[_TINYDIR_FILENAME_MAX];
|
||||
_tinydir_char_t *extension;
|
||||
_tinydir_char_t* extension;
|
||||
int is_dir;
|
||||
int is_reg;
|
||||
|
||||
@@ -212,63 +206,59 @@ typedef struct tinydir_file
|
||||
#endif
|
||||
} tinydir_file;
|
||||
|
||||
typedef struct tinydir_dir
|
||||
{
|
||||
typedef struct tinydir_dir {
|
||||
_tinydir_char_t path[_TINYDIR_PATH_MAX];
|
||||
int has_next;
|
||||
size_t n_files;
|
||||
|
||||
tinydir_file *_files;
|
||||
tinydir_file* _files;
|
||||
#ifdef _MSC_VER
|
||||
HANDLE _h;
|
||||
WIN32_FIND_DATA _f;
|
||||
#else
|
||||
_TINYDIR_DIR *_d;
|
||||
struct _tinydir_dirent *_e;
|
||||
_TINYDIR_DIR* _d;
|
||||
struct _tinydir_dirent* _e;
|
||||
#ifndef _TINYDIR_USE_READDIR
|
||||
struct _tinydir_dirent *_ep;
|
||||
struct _tinydir_dirent* _ep;
|
||||
#endif
|
||||
#endif
|
||||
} tinydir_dir;
|
||||
|
||||
|
||||
/* declarations */
|
||||
|
||||
_TINYDIR_FUNC
|
||||
int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path);
|
||||
int tinydir_open(tinydir_dir* dir, const _tinydir_char_t* path);
|
||||
_TINYDIR_FUNC
|
||||
int tinydir_open_sorted(tinydir_dir *dir, const _tinydir_char_t *path);
|
||||
int tinydir_open_sorted(tinydir_dir* dir, const _tinydir_char_t* path);
|
||||
_TINYDIR_FUNC
|
||||
void tinydir_close(tinydir_dir *dir);
|
||||
void tinydir_close(tinydir_dir* dir);
|
||||
|
||||
_TINYDIR_FUNC
|
||||
int tinydir_next(tinydir_dir *dir);
|
||||
int tinydir_next(tinydir_dir* dir);
|
||||
_TINYDIR_FUNC
|
||||
int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file);
|
||||
int tinydir_readfile(const tinydir_dir* dir, tinydir_file* file);
|
||||
_TINYDIR_FUNC
|
||||
int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i);
|
||||
int tinydir_readfile_n(const tinydir_dir* dir, tinydir_file* file, size_t i);
|
||||
_TINYDIR_FUNC
|
||||
int tinydir_open_subdir_n(tinydir_dir *dir, size_t i);
|
||||
int tinydir_open_subdir_n(tinydir_dir* dir, size_t i);
|
||||
|
||||
_TINYDIR_FUNC
|
||||
int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path);
|
||||
int tinydir_file_open(tinydir_file* file, const _tinydir_char_t* path);
|
||||
_TINYDIR_FUNC
|
||||
void _tinydir_get_ext(tinydir_file *file);
|
||||
void _tinydir_get_ext(tinydir_file* file);
|
||||
_TINYDIR_FUNC
|
||||
int _tinydir_file_cmp(const void *a, const void *b);
|
||||
int _tinydir_file_cmp(const void* a, const void* b);
|
||||
#ifndef _MSC_VER
|
||||
#ifndef _TINYDIR_USE_READDIR
|
||||
_TINYDIR_FUNC
|
||||
size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp);
|
||||
size_t _tinydir_dirent_buf_size(_TINYDIR_DIR* dirp);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* definitions*/
|
||||
|
||||
_TINYDIR_FUNC
|
||||
int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path)
|
||||
{
|
||||
int tinydir_open(tinydir_dir* dir, const _tinydir_char_t* path) {
|
||||
#ifndef _MSC_VER
|
||||
#ifndef _TINYDIR_USE_READDIR
|
||||
int error;
|
||||
@@ -277,15 +267,13 @@ int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path)
|
||||
#else
|
||||
_tinydir_char_t path_buf[_TINYDIR_PATH_MAX];
|
||||
#endif
|
||||
_tinydir_char_t *pathp;
|
||||
_tinydir_char_t* pathp;
|
||||
|
||||
if (dir == NULL || path == NULL || _tinydir_strlen(path) == 0)
|
||||
{
|
||||
if (dir == NULL || path == NULL || _tinydir_strlen(path) == 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX)
|
||||
{
|
||||
if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
@@ -305,8 +293,7 @@ int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path)
|
||||
_tinydir_strcpy(dir->path, path);
|
||||
/* Remove trailing slashes */
|
||||
pathp = &dir->path[_tinydir_strlen(dir->path) - 1];
|
||||
while (pathp != dir->path && (*pathp == TINYDIR_STRING('\\') || *pathp == TINYDIR_STRING('/')))
|
||||
{
|
||||
while (pathp != dir->path && (*pathp == TINYDIR_STRING('\\') || *pathp == TINYDIR_STRING('/'))) {
|
||||
*pathp = TINYDIR_STRING('\0');
|
||||
pathp++;
|
||||
}
|
||||
@@ -318,13 +305,11 @@ int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path)
|
||||
#else
|
||||
dir->_h = FindFirstFile(path_buf, &dir->_f);
|
||||
#endif
|
||||
if (dir->_h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (dir->_h == INVALID_HANDLE_VALUE) {
|
||||
errno = ENOENT;
|
||||
#else
|
||||
dir->_d = _tinydir_opendir(path);
|
||||
if (dir->_d == NULL)
|
||||
{
|
||||
if (dir->_d == NULL) {
|
||||
#endif
|
||||
goto bail;
|
||||
}
|
||||
@@ -337,76 +322,68 @@ int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path)
|
||||
#else
|
||||
/* allocate dirent buffer for readdir_r */
|
||||
size = _tinydir_dirent_buf_size(dir->_d); /* conversion to int */
|
||||
if (size == -1) return -1;
|
||||
if (size == -1)
|
||||
return -1;
|
||||
dir->_ep = (struct _tinydir_dirent*)_TINYDIR_MALLOC(size);
|
||||
if (dir->_ep == NULL) return -1;
|
||||
if (dir->_ep == NULL)
|
||||
return -1;
|
||||
|
||||
error = readdir_r(dir->_d, dir->_ep, &dir->_e);
|
||||
if (error != 0) return -1;
|
||||
if (error != 0)
|
||||
return -1;
|
||||
#endif
|
||||
if (dir->_e == NULL)
|
||||
{
|
||||
if (dir->_e == NULL) {
|
||||
dir->has_next = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
bail:
|
||||
bail:
|
||||
tinydir_close(dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_TINYDIR_FUNC
|
||||
int tinydir_open_sorted(tinydir_dir *dir, const _tinydir_char_t *path)
|
||||
{
|
||||
int tinydir_open_sorted(tinydir_dir* dir, const _tinydir_char_t* path) {
|
||||
/* Count the number of files first, to pre-allocate the files array */
|
||||
size_t n_files = 0;
|
||||
if (tinydir_open(dir, path) == -1)
|
||||
{
|
||||
if (tinydir_open(dir, path) == -1) {
|
||||
return -1;
|
||||
}
|
||||
while (dir->has_next)
|
||||
{
|
||||
while (dir->has_next) {
|
||||
n_files++;
|
||||
if (tinydir_next(dir) == -1)
|
||||
{
|
||||
if (tinydir_next(dir) == -1) {
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
tinydir_close(dir);
|
||||
|
||||
if (n_files == 0 || tinydir_open(dir, path) == -1)
|
||||
{
|
||||
if (n_files == 0 || tinydir_open(dir, path) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dir->n_files = 0;
|
||||
dir->_files = (tinydir_file *)_TINYDIR_MALLOC(sizeof *dir->_files * n_files);
|
||||
if (dir->_files == NULL)
|
||||
{
|
||||
dir->_files = (tinydir_file*)_TINYDIR_MALLOC(sizeof *dir->_files * n_files);
|
||||
if (dir->_files == NULL) {
|
||||
goto bail;
|
||||
}
|
||||
while (dir->has_next)
|
||||
{
|
||||
tinydir_file *p_file;
|
||||
while (dir->has_next) {
|
||||
tinydir_file* p_file;
|
||||
dir->n_files++;
|
||||
|
||||
p_file = &dir->_files[dir->n_files - 1];
|
||||
if (tinydir_readfile(dir, p_file) == -1)
|
||||
{
|
||||
if (tinydir_readfile(dir, p_file) == -1) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (tinydir_next(dir) == -1)
|
||||
{
|
||||
if (tinydir_next(dir) == -1) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* Just in case the number of files has changed between the first and
|
||||
second reads, terminate without writing into unallocated memory */
|
||||
if (dir->n_files == n_files)
|
||||
{
|
||||
if (dir->n_files == n_files) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -415,16 +392,14 @@ int tinydir_open_sorted(tinydir_dir *dir, const _tinydir_char_t *path)
|
||||
|
||||
return 0;
|
||||
|
||||
bail:
|
||||
bail:
|
||||
tinydir_close(dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_TINYDIR_FUNC
|
||||
void tinydir_close(tinydir_dir *dir)
|
||||
{
|
||||
if (dir == NULL)
|
||||
{
|
||||
void tinydir_close(tinydir_dir* dir) {
|
||||
if (dir == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -434,14 +409,12 @@ void tinydir_close(tinydir_dir *dir)
|
||||
_TINYDIR_FREE(dir->_files);
|
||||
dir->_files = NULL;
|
||||
#ifdef _MSC_VER
|
||||
if (dir->_h != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (dir->_h != INVALID_HANDLE_VALUE) {
|
||||
FindClose(dir->_h);
|
||||
}
|
||||
dir->_h = INVALID_HANDLE_VALUE;
|
||||
#else
|
||||
if (dir->_d)
|
||||
{
|
||||
if (dir->_d) {
|
||||
_tinydir_closedir(dir->_d);
|
||||
}
|
||||
dir->_d = NULL;
|
||||
@@ -454,15 +427,12 @@ void tinydir_close(tinydir_dir *dir)
|
||||
}
|
||||
|
||||
_TINYDIR_FUNC
|
||||
int tinydir_next(tinydir_dir *dir)
|
||||
{
|
||||
if (dir == NULL)
|
||||
{
|
||||
int tinydir_next(tinydir_dir* dir) {
|
||||
if (dir == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (!dir->has_next)
|
||||
{
|
||||
if (!dir->has_next) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
@@ -473,12 +443,10 @@ int tinydir_next(tinydir_dir *dir)
|
||||
#ifdef _TINYDIR_USE_READDIR
|
||||
dir->_e = _tinydir_readdir(dir->_d);
|
||||
#else
|
||||
if (dir->_ep == NULL)
|
||||
{
|
||||
if (dir->_ep == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (readdir_r(dir->_d, dir->_ep, &dir->_e) != 0)
|
||||
{
|
||||
if (readdir_r(dir->_d, dir->_ep, &dir->_e) != 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
@@ -487,9 +455,7 @@ int tinydir_next(tinydir_dir *dir)
|
||||
{
|
||||
dir->has_next = 0;
|
||||
#ifdef _MSC_VER
|
||||
if (GetLastError() != ERROR_SUCCESS &&
|
||||
GetLastError() != ERROR_NO_MORE_FILES)
|
||||
{
|
||||
if (GetLastError() != ERROR_SUCCESS && GetLastError() != ERROR_NO_MORE_FILES) {
|
||||
tinydir_close(dir);
|
||||
errno = EIO;
|
||||
return -1;
|
||||
@@ -501,11 +467,9 @@ int tinydir_next(tinydir_dir *dir)
|
||||
}
|
||||
|
||||
_TINYDIR_FUNC
|
||||
int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file)
|
||||
{
|
||||
const _tinydir_char_t *filename;
|
||||
if (dir == NULL || file == NULL)
|
||||
{
|
||||
int tinydir_readfile(const tinydir_dir* dir, tinydir_file* file) {
|
||||
const _tinydir_char_t* filename;
|
||||
if (dir == NULL || file == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
@@ -524,16 +488,12 @@ int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file)
|
||||
#else
|
||||
dir->_e->d_name;
|
||||
#endif
|
||||
if (_tinydir_strlen(dir->path) +
|
||||
_tinydir_strlen(filename) + 1 + _TINYDIR_PATH_EXTRA >=
|
||||
_TINYDIR_PATH_MAX)
|
||||
{
|
||||
if (_tinydir_strlen(dir->path) + _tinydir_strlen(filename) + 1 + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX) {
|
||||
/* the path for the file will be too long */
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
if (_tinydir_strlen(filename) >= _TINYDIR_FILENAME_MAX)
|
||||
{
|
||||
if (_tinydir_strlen(filename) >= _TINYDIR_FILENAME_MAX) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
@@ -546,17 +506,15 @@ int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file)
|
||||
#ifndef _MSC_VER
|
||||
#ifdef __MINGW32__
|
||||
if (_tstat(
|
||||
#elif (defined _BSD_SOURCE) || (defined _DEFAULT_SOURCE) \
|
||||
|| ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) \
|
||||
|| ((defined _POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) \
|
||||
|| ((defined __APPLE__) && (defined __MACH__)) \
|
||||
#elif (defined _BSD_SOURCE) || (defined _DEFAULT_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) \
|
||||
|| ((defined _POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) || ((defined __APPLE__) && (defined __MACH__)) \
|
||||
|| (defined BSD)
|
||||
if (lstat(
|
||||
#else
|
||||
if (stat(
|
||||
#endif
|
||||
file->path, &file->_s) == -1)
|
||||
{
|
||||
file->path, &file->_s)
|
||||
== -1) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
@@ -570,19 +528,18 @@ int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file)
|
||||
#endif
|
||||
file->is_reg =
|
||||
#ifdef _MSC_VER
|
||||
!!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) ||
|
||||
(
|
||||
!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) &&
|
||||
!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
|
||||
!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) &&
|
||||
!!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NORMAL)
|
||||
|| (!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DEVICE)
|
||||
&& !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
&& !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) &&
|
||||
#ifdef FILE_ATTRIBUTE_INTEGRITY_STREAM
|
||||
!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_INTEGRITY_STREAM) &&
|
||||
#endif
|
||||
#ifdef FILE_ATTRIBUTE_NO_SCRUB_DATA
|
||||
!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NO_SCRUB_DATA) &&
|
||||
#endif
|
||||
!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) &&
|
||||
!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY));
|
||||
!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE)
|
||||
&& !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY));
|
||||
#else
|
||||
S_ISREG(file->_s.st_mode);
|
||||
#endif
|
||||
@@ -591,15 +548,12 @@ int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file)
|
||||
}
|
||||
|
||||
_TINYDIR_FUNC
|
||||
int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i)
|
||||
{
|
||||
if (dir == NULL || file == NULL)
|
||||
{
|
||||
int tinydir_readfile_n(const tinydir_dir* dir, tinydir_file* file, size_t i) {
|
||||
if (dir == NULL || file == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (i >= dir->n_files)
|
||||
{
|
||||
if (i >= dir->n_files) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
@@ -611,24 +565,20 @@ int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i)
|
||||
}
|
||||
|
||||
_TINYDIR_FUNC
|
||||
int tinydir_open_subdir_n(tinydir_dir *dir, size_t i)
|
||||
{
|
||||
int tinydir_open_subdir_n(tinydir_dir* dir, size_t i) {
|
||||
_tinydir_char_t path[_TINYDIR_PATH_MAX];
|
||||
if (dir == NULL)
|
||||
{
|
||||
if (dir == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (i >= dir->n_files || !dir->_files[i].is_dir)
|
||||
{
|
||||
if (i >= dir->n_files || !dir->_files[i].is_dir) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
_tinydir_strcpy(path, dir->_files[i].path);
|
||||
tinydir_close(dir);
|
||||
if (tinydir_open_sorted(dir, path) == -1)
|
||||
{
|
||||
if (tinydir_open_sorted(dir, path) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -637,27 +587,24 @@ int tinydir_open_subdir_n(tinydir_dir *dir, size_t i)
|
||||
|
||||
/* Open a single file given its path */
|
||||
_TINYDIR_FUNC
|
||||
int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path)
|
||||
{
|
||||
int tinydir_file_open(tinydir_file* file, const _tinydir_char_t* path) {
|
||||
tinydir_dir dir;
|
||||
int result = 0;
|
||||
int found = 0;
|
||||
_tinydir_char_t dir_name_buf[_TINYDIR_PATH_MAX];
|
||||
_tinydir_char_t file_name_buf[_TINYDIR_FILENAME_MAX];
|
||||
_tinydir_char_t *dir_name;
|
||||
_tinydir_char_t *base_name;
|
||||
_tinydir_char_t* dir_name;
|
||||
_tinydir_char_t* base_name;
|
||||
#if (defined _MSC_VER || defined __MINGW32__)
|
||||
_tinydir_char_t drive_buf[_TINYDIR_PATH_MAX];
|
||||
_tinydir_char_t ext_buf[_TINYDIR_FILENAME_MAX];
|
||||
#endif
|
||||
|
||||
if (file == NULL || path == NULL || _tinydir_strlen(path) == 0)
|
||||
{
|
||||
if (file == NULL || path == NULL || _tinydir_strlen(path) == 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX)
|
||||
{
|
||||
if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
@@ -665,23 +612,13 @@ int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path)
|
||||
/* Get the parent path */
|
||||
#if (defined _MSC_VER || defined __MINGW32__)
|
||||
#if ((defined _MSC_VER) && (_MSC_VER >= 1400))
|
||||
errno = _tsplitpath_s(
|
||||
path,
|
||||
drive_buf, _TINYDIR_DRIVE_MAX,
|
||||
dir_name_buf, _TINYDIR_FILENAME_MAX,
|
||||
file_name_buf, _TINYDIR_FILENAME_MAX,
|
||||
ext_buf, _TINYDIR_FILENAME_MAX);
|
||||
errno = _tsplitpath_s(path, drive_buf, _TINYDIR_DRIVE_MAX, dir_name_buf, _TINYDIR_FILENAME_MAX, file_name_buf,
|
||||
_TINYDIR_FILENAME_MAX, ext_buf, _TINYDIR_FILENAME_MAX);
|
||||
#else
|
||||
_tsplitpath(
|
||||
path,
|
||||
drive_buf,
|
||||
dir_name_buf,
|
||||
file_name_buf,
|
||||
ext_buf);
|
||||
_tsplitpath(path, drive_buf, dir_name_buf, file_name_buf, ext_buf);
|
||||
#endif
|
||||
|
||||
if (errno)
|
||||
{
|
||||
if (errno) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -695,8 +632,7 @@ int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path)
|
||||
|
||||
/* Emulate the behavior of dirname by returning "." for dir name if it's
|
||||
empty */
|
||||
if (drive_buf[0] == '\0' && dir_name_buf[0] == '\0')
|
||||
{
|
||||
if (drive_buf[0] == '\0' && dir_name_buf[0] == '\0') {
|
||||
_tinydir_strcpy(dir_name_buf, TINYDIR_STRING("."));
|
||||
}
|
||||
/* Concatenate the drive letter and dir name to form full dir name */
|
||||
@@ -719,7 +655,7 @@ int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path)
|
||||
if ((_tinydir_strcmp(base_name, TINYDIR_STRING("/"))) == 0)
|
||||
#endif
|
||||
{
|
||||
memset(file, 0, sizeof * file);
|
||||
memset(file, 0, sizeof *file);
|
||||
file->is_dir = 1;
|
||||
file->is_reg = 0;
|
||||
_tinydir_strcpy(file->path, dir_name);
|
||||
@@ -728,59 +664,48 @@ int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path)
|
||||
}
|
||||
|
||||
/* Open the parent directory */
|
||||
if (tinydir_open(&dir, dir_name) == -1)
|
||||
{
|
||||
if (tinydir_open(&dir, dir_name) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read through the parent directory and look for the file */
|
||||
while (dir.has_next)
|
||||
{
|
||||
if (tinydir_readfile(&dir, file) == -1)
|
||||
{
|
||||
while (dir.has_next) {
|
||||
if (tinydir_readfile(&dir, file) == -1) {
|
||||
result = -1;
|
||||
goto bail;
|
||||
}
|
||||
if (_tinydir_strcmp(file->name, base_name) == 0)
|
||||
{
|
||||
if (_tinydir_strcmp(file->name, base_name) == 0) {
|
||||
/* File found */
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
tinydir_next(&dir);
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
if (!found) {
|
||||
result = -1;
|
||||
errno = ENOENT;
|
||||
}
|
||||
|
||||
bail:
|
||||
bail:
|
||||
tinydir_close(&dir);
|
||||
return result;
|
||||
}
|
||||
|
||||
_TINYDIR_FUNC
|
||||
void _tinydir_get_ext(tinydir_file *file)
|
||||
{
|
||||
_tinydir_char_t *period = _tinydir_strrchr(file->name, TINYDIR_STRING('.'));
|
||||
if (period == NULL)
|
||||
{
|
||||
void _tinydir_get_ext(tinydir_file* file) {
|
||||
_tinydir_char_t* period = _tinydir_strrchr(file->name, TINYDIR_STRING('.'));
|
||||
if (period == NULL) {
|
||||
file->extension = &(file->name[_tinydir_strlen(file->name)]);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
file->extension = period + 1;
|
||||
}
|
||||
}
|
||||
|
||||
_TINYDIR_FUNC
|
||||
int _tinydir_file_cmp(const void *a, const void *b)
|
||||
{
|
||||
const tinydir_file *fa = (const tinydir_file *)a;
|
||||
const tinydir_file *fb = (const tinydir_file *)b;
|
||||
if (fa->is_dir != fb->is_dir)
|
||||
{
|
||||
int _tinydir_file_cmp(const void* a, const void* b) {
|
||||
const tinydir_file* fa = (const tinydir_file*)a;
|
||||
const tinydir_file* fb = (const tinydir_file*)b;
|
||||
if (fa->is_dir != fb->is_dir) {
|
||||
return -(fa->is_dir - fb->is_dir);
|
||||
}
|
||||
return _tinydir_strncmp(fa->name, fb->name, _TINYDIR_FILENAME_MAX);
|
||||
@@ -793,15 +718,14 @@ The following authored by Ben Hutchings <ben@decadent.org.uk>
|
||||
from https://womble.decadent.org.uk/readdir_r-advisory.html
|
||||
*/
|
||||
/* Calculate the required buffer size (in bytes) for directory *
|
||||
* entries read from the given directory handle. Return -1 if this *
|
||||
* this cannot be done. *
|
||||
* *
|
||||
* This code does not trust values of NAME_MAX that are less than *
|
||||
* 255, since some systems (including at least HP-UX) incorrectly *
|
||||
* define it to be a smaller value. */
|
||||
* entries read from the given directory handle. Return -1 if this *
|
||||
* this cannot be done. *
|
||||
* *
|
||||
* This code does not trust values of NAME_MAX that are less than *
|
||||
* 255, since some systems (including at least HP-UX) incorrectly *
|
||||
* define it to be a smaller value. */
|
||||
_TINYDIR_FUNC
|
||||
size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp)
|
||||
{
|
||||
size_t _tinydir_dirent_buf_size(_TINYDIR_DIR* dirp) {
|
||||
long name_max;
|
||||
size_t name_end;
|
||||
/* parameter may be unused */
|
||||
@@ -821,8 +745,7 @@ size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp)
|
||||
#error "buffer size for readdir_r cannot be determined"
|
||||
#endif
|
||||
name_end = (size_t)offsetof(struct _tinydir_dirent, d_name) + name_max + 1;
|
||||
return (name_end > sizeof(struct _tinydir_dirent) ?
|
||||
name_end : sizeof(struct _tinydir_dirent));
|
||||
return (name_end > sizeof(struct _tinydir_dirent) ? name_end : sizeof(struct _tinydir_dirent));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -831,8 +754,8 @@ size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp)
|
||||
}
|
||||
#endif
|
||||
|
||||
# if defined (_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
# endif
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -20,13 +20,16 @@
|
||||
#include "lcd_api.h"
|
||||
|
||||
// Defines used by UDP callback
|
||||
#define UDP_BROADCAST_MAX_DATA_SIZE ((UDP_BROADCAST_MAX_NAME_SIZE * 2) - 2 + 25) // Define the maximum expected data size
|
||||
#define UDP_BROADCAST_MAX_DATA_SIZE \
|
||||
((UDP_BROADCAST_MAX_NAME_SIZE * 2) - 2 + 25) // Define the maximum expected data size
|
||||
#define UDP_BROADCAST_UDP_QUESTION1 "Where are you?v1.0" // Expected question from UDP client
|
||||
#define UDP_BROADCAST_MAX_FUNC_LEN 7
|
||||
#define UDP_BROADCAST_MAX_COLON_COMMA_COUNT 4
|
||||
|
||||
// Defines used by owner details
|
||||
#define UDP_BROADCAST_MAX_REPLY_SIZE (UDP_BROADCAST_MAX_MAC_ADDR_LEN + sizeof(UDP_BROADCAST_REPLY_MIDDLE_TEXT) + (UDP_BROADCAST_MAX_NAME_SIZE * 2) + UDP_BROADCAST_MAX_REPLY_SIZE_EXTRA)
|
||||
#define UDP_BROADCAST_MAX_REPLY_SIZE \
|
||||
(UDP_BROADCAST_MAX_MAC_ADDR_LEN + sizeof(UDP_BROADCAST_REPLY_MIDDLE_TEXT) + (UDP_BROADCAST_MAX_NAME_SIZE * 2) \
|
||||
+ UDP_BROADCAST_MAX_REPLY_SIZE_EXTRA)
|
||||
#define UDP_BROADCAST_REPLY_MIDDLE_TEXT "is present and my owner is"
|
||||
|
||||
#define UDP_BROADCAST_MAX_MAC_ADDR_LEN 19 // Format is: "xx:xx:xx:xx:xx:xx"
|
||||
@@ -36,7 +39,6 @@
|
||||
#define UDP_BROADCAST_LCD_NAME_PRE_TEXT "New owner: "
|
||||
#define UDP_BROADCAST_LCD_TEXT_SIZE (strlen(UDP_BROADCAST_LCD_NAME_PRE_TEXT) + UDP_BROADCAST_MAX_NAME_SIZE)
|
||||
|
||||
|
||||
/**
|
||||
* @struct owner_details_t
|
||||
* @brief contains information about the owner
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
#ifndef __ANIMATEDGIF__
|
||||
#define __ANIMATEDGIF__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define memcpy_P memcpy
|
||||
#define PROGMEM
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
//
|
||||
#define MAX_CODE_SIZE 12
|
||||
#define MAX_COLORS 256
|
||||
#define LZW_BUF_SIZE (6*MAX_CHUNK_SIZE)
|
||||
#define LZW_HIGHWATER (4*MAX_CHUNK_SIZE)
|
||||
#define LZW_BUF_SIZE (6 * MAX_CHUNK_SIZE)
|
||||
#define LZW_HIGHWATER (4 * MAX_CHUNK_SIZE)
|
||||
#ifdef __LINUX__
|
||||
#define MAX_WIDTH 2048
|
||||
#else
|
||||
@@ -50,10 +50,10 @@
|
||||
// This buffer is used to store the pixel sequence in reverse order
|
||||
// it needs to be large enough to hold the longest possible
|
||||
// sequence (1<<MAX_CODE_SIZE)
|
||||
#define FILE_BUF_SIZE (1<<MAX_CODE_SIZE)
|
||||
#define FILE_BUF_SIZE (1 << MAX_CODE_SIZE)
|
||||
|
||||
#define PIXEL_FIRST 0
|
||||
#define PIXEL_LAST (1<<MAX_CODE_SIZE)
|
||||
#define PIXEL_LAST (1 << MAX_CODE_SIZE)
|
||||
#define LINK_UNUSED 5911 // 0x1717 to use memset
|
||||
#define LINK_END 5912
|
||||
#define MAX_HASH 5003
|
||||
@@ -71,10 +71,7 @@ enum {
|
||||
// RAW = 8-bit palettized pixels requiring transparent pixel handling
|
||||
// COOKED = 16 or 24-bpp fully rendered pixels ready for display
|
||||
//
|
||||
enum {
|
||||
GIF_DRAW_RAW = 0,
|
||||
GIF_DRAW_COOKED
|
||||
};
|
||||
enum { GIF_DRAW_RAW = 0, GIF_DRAW_COOKED };
|
||||
|
||||
enum {
|
||||
GIF_SUCCESS = 0,
|
||||
@@ -89,31 +86,28 @@ enum {
|
||||
GIF_ERROR_MEMORY
|
||||
};
|
||||
|
||||
typedef struct gif_file_tag
|
||||
{
|
||||
typedef struct gif_file_tag {
|
||||
int32_t iPos; // current file position
|
||||
int32_t iSize; // file size
|
||||
uint8_t *pData; // memory file pointer
|
||||
void * fHandle; // class pointer to File/SdFat or whatever you want
|
||||
uint8_t* pData; // memory file pointer
|
||||
void* fHandle; // class pointer to File/SdFat or whatever you want
|
||||
} GIFFILE;
|
||||
|
||||
typedef struct gif_info_tag
|
||||
{
|
||||
typedef struct gif_info_tag {
|
||||
int32_t iFrameCount; // total frames in file
|
||||
int32_t iDuration; // duration of animation in milliseconds
|
||||
int32_t iMaxDelay; // maximum frame delay
|
||||
int32_t iMinDelay; // minimum frame delay
|
||||
} GIFINFO;
|
||||
|
||||
typedef struct gif_draw_tag
|
||||
{
|
||||
typedef struct gif_draw_tag {
|
||||
int iX, iY; // Corner offset of this frame on the canvas
|
||||
int y; // current line being drawn (0 = top line of image)
|
||||
int iWidth, iHeight; // size of this frame
|
||||
void *pUser; // user supplied pointer
|
||||
uint8_t *pPixels; // 8-bit source pixels for this line
|
||||
uint16_t *pPalette; // little or big-endian RGB565 palette entries (default)
|
||||
uint8_t *pPalette24; // RGB888 palette (optional)
|
||||
void* pUser; // user supplied pointer
|
||||
uint8_t* pPixels; // 8-bit source pixels for this line
|
||||
uint16_t* pPalette; // little or big-endian RGB565 palette entries (default)
|
||||
uint8_t* pPalette24; // RGB888 palette (optional)
|
||||
uint8_t ucTransparent; // transparent color
|
||||
uint8_t ucHasTransparency; // flag indicating the transparent color is in use
|
||||
uint8_t ucDisposalMethod; // frame disposal method
|
||||
@@ -122,18 +116,17 @@ typedef struct gif_draw_tag
|
||||
} GIFDRAW;
|
||||
|
||||
// Callback function prototypes
|
||||
typedef int32_t (GIF_READ_CALLBACK)(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen);
|
||||
typedef int32_t (GIF_SEEK_CALLBACK)(GIFFILE *pFile, int32_t iPosition);
|
||||
typedef void (GIF_DRAW_CALLBACK)(GIFDRAW *pDraw);
|
||||
typedef void * (GIF_OPEN_CALLBACK)(const char *szFilename, int32_t *pFileSize);
|
||||
typedef void (GIF_CLOSE_CALLBACK)(void *pHandle);
|
||||
typedef void * (GIF_ALLOC_CALLBACK)(uint32_t iSize);
|
||||
typedef void (GIF_FREE_CALLBACK)(void *buffer);
|
||||
typedef int32_t(GIF_READ_CALLBACK)(GIFFILE* pFile, uint8_t* pBuf, int32_t iLen);
|
||||
typedef int32_t(GIF_SEEK_CALLBACK)(GIFFILE* pFile, int32_t iPosition);
|
||||
typedef void(GIF_DRAW_CALLBACK)(GIFDRAW* pDraw);
|
||||
typedef void*(GIF_OPEN_CALLBACK)(const char* szFilename, int32_t* pFileSize);
|
||||
typedef void(GIF_CLOSE_CALLBACK)(void* pHandle);
|
||||
typedef void*(GIF_ALLOC_CALLBACK)(uint32_t iSize);
|
||||
typedef void(GIF_FREE_CALLBACK)(void* buffer);
|
||||
//
|
||||
// our private structure to hold a GIF image decode state
|
||||
//
|
||||
typedef struct gif_image_tag
|
||||
{
|
||||
typedef struct gif_image_tag {
|
||||
int iWidth, iHeight, iCanvasWidth, iCanvasHeight;
|
||||
int iX, iY; // GIF corner offset
|
||||
int iBpp;
|
||||
@@ -145,22 +138,22 @@ typedef struct gif_image_tag
|
||||
int iLZWSize; // current quantity of data in the LZW buffer
|
||||
int iCommentPos; // file offset of start of comment data
|
||||
short sCommentLen; // length of comment
|
||||
GIF_READ_CALLBACK *pfnRead;
|
||||
GIF_SEEK_CALLBACK *pfnSeek;
|
||||
GIF_DRAW_CALLBACK *pfnDraw;
|
||||
GIF_OPEN_CALLBACK *pfnOpen;
|
||||
GIF_CLOSE_CALLBACK *pfnClose;
|
||||
GIF_READ_CALLBACK* pfnRead;
|
||||
GIF_SEEK_CALLBACK* pfnSeek;
|
||||
GIF_DRAW_CALLBACK* pfnDraw;
|
||||
GIF_OPEN_CALLBACK* pfnOpen;
|
||||
GIF_CLOSE_CALLBACK* pfnClose;
|
||||
GIFFILE GIFFile;
|
||||
void *pUser;
|
||||
unsigned char *pFrameBuffer;
|
||||
void* pUser;
|
||||
unsigned char* pFrameBuffer;
|
||||
unsigned char *pPixels, *pOldPixels;
|
||||
unsigned char ucLineBuf[MAX_WIDTH]; // current line
|
||||
unsigned char ucFileBuf[FILE_BUF_SIZE]; // holds temp data and pixel stack
|
||||
unsigned short pPalette[(MAX_COLORS * 3)/2]; // can hold RGB565 or RGB888 - set in begin()
|
||||
unsigned short pLocalPalette[(MAX_COLORS * 3)/2]; // color palettes for GIF images
|
||||
unsigned short pPalette[(MAX_COLORS * 3) / 2]; // can hold RGB565 or RGB888 - set in begin()
|
||||
unsigned short pLocalPalette[(MAX_COLORS * 3) / 2]; // color palettes for GIF images
|
||||
unsigned char ucLZW[LZW_BUF_SIZE]; // holds 6 chunks (6x255) of GIF LZW data packed together
|
||||
unsigned short usGIFTable[1<<MAX_CODE_SIZE];
|
||||
unsigned char ucGIFPixels[(PIXEL_LAST*2)];
|
||||
unsigned short usGIFTable[1 << MAX_CODE_SIZE];
|
||||
unsigned char ucGIFPixels[(PIXEL_LAST * 2)];
|
||||
unsigned char bEndOfFrame;
|
||||
unsigned char ucGIFBits, ucBackground, ucTransparent, ucCodeStart, ucMap, bUseLocalPalette;
|
||||
unsigned char ucPaletteType; // RGB565 or RGB888
|
||||
@@ -171,52 +164,58 @@ typedef struct gif_image_tag
|
||||
//
|
||||
// The GIF class wraps portable C code which does the actual work
|
||||
//
|
||||
class AnimatedGIF
|
||||
{
|
||||
class AnimatedGIF {
|
||||
public:
|
||||
int open(uint8_t *pData, int iDataSize, GIF_DRAW_CALLBACK *pfnDraw);
|
||||
int openFLASH(uint8_t *pData, int iDataSize, GIF_DRAW_CALLBACK *pfnDraw);
|
||||
int open(const char *szFilename, GIF_OPEN_CALLBACK *pfnOpen, GIF_CLOSE_CALLBACK *pfnClose, GIF_READ_CALLBACK *pfnRead, GIF_SEEK_CALLBACK *pfnSeek, GIF_DRAW_CALLBACK *pfnDraw);
|
||||
int open(uint8_t* pData, int iDataSize, GIF_DRAW_CALLBACK* pfnDraw);
|
||||
int openFLASH(uint8_t* pData, int iDataSize, GIF_DRAW_CALLBACK* pfnDraw);
|
||||
int open(const char* szFilename,
|
||||
GIF_OPEN_CALLBACK* pfnOpen,
|
||||
GIF_CLOSE_CALLBACK* pfnClose,
|
||||
GIF_READ_CALLBACK* pfnRead,
|
||||
GIF_SEEK_CALLBACK* pfnSeek,
|
||||
GIF_DRAW_CALLBACK* pfnDraw);
|
||||
void close();
|
||||
void reset();
|
||||
void begin(unsigned char ucPaletteType = GIF_PALETTE_RGB565_LE);
|
||||
void begin(int iEndian, unsigned char ucPaletteType) { begin(ucPaletteType); };
|
||||
int playFrame(bool bSync, int *delayMilliseconds, void *pUser = NULL);
|
||||
void begin(int iEndian, unsigned char ucPaletteType) {
|
||||
begin(ucPaletteType);
|
||||
};
|
||||
int playFrame(bool bSync, int* delayMilliseconds, void* pUser = NULL);
|
||||
int getCanvasWidth();
|
||||
int allocFrameBuf(GIF_ALLOC_CALLBACK *pfnAlloc);
|
||||
int allocFrameBuf(GIF_ALLOC_CALLBACK* pfnAlloc);
|
||||
int setDrawType(int iType);
|
||||
int freeFrameBuf(GIF_FREE_CALLBACK *pfnFree);
|
||||
uint8_t *getFrameBuf();
|
||||
int freeFrameBuf(GIF_FREE_CALLBACK* pfnFree);
|
||||
uint8_t* getFrameBuf();
|
||||
int getCanvasHeight();
|
||||
int getLoopCount();
|
||||
int getInfo(GIFINFO *pInfo);
|
||||
int getInfo(GIFINFO* pInfo);
|
||||
int getLastError();
|
||||
int getComment(char *destBuffer);
|
||||
int getComment(char* destBuffer);
|
||||
|
||||
private:
|
||||
GIFIMAGE _gif;
|
||||
};
|
||||
#else
|
||||
// C interface
|
||||
int GIF_openRAM(GIFIMAGE *pGIF, uint8_t *pData, int iDataSize, GIF_DRAW_CALLBACK *pfnDraw);
|
||||
int GIF_openFile(GIFIMAGE *pGIF, const char *szFilename, GIF_DRAW_CALLBACK *pfnDraw);
|
||||
void GIF_close(GIFIMAGE *pGIF);
|
||||
void GIF_begin(GIFIMAGE *pGIF, unsigned char ucPaletteType);
|
||||
void GIF_reset(GIFIMAGE *pGIF);
|
||||
int GIF_playFrame(GIFIMAGE *pGIF, int *delayMilliseconds, void *pUser);
|
||||
int GIF_getCanvasWidth(GIFIMAGE *pGIF);
|
||||
int GIF_getCanvasHeight(GIFIMAGE *pGIF);
|
||||
int GIF_getComment(GIFIMAGE *pGIF, char *destBuffer);
|
||||
int GIF_getInfo(GIFIMAGE *pGIF, GIFINFO *pInfo);
|
||||
int GIF_getLastError(GIFIMAGE *pGIF);
|
||||
int GIF_getLoopCount(GIFIMAGE *pGIF);
|
||||
int GIF_openRAM(GIFIMAGE* pGIF, uint8_t* pData, int iDataSize, GIF_DRAW_CALLBACK* pfnDraw);
|
||||
int GIF_openFile(GIFIMAGE* pGIF, const char* szFilename, GIF_DRAW_CALLBACK* pfnDraw);
|
||||
void GIF_close(GIFIMAGE* pGIF);
|
||||
void GIF_begin(GIFIMAGE* pGIF, unsigned char ucPaletteType);
|
||||
void GIF_reset(GIFIMAGE* pGIF);
|
||||
int GIF_playFrame(GIFIMAGE* pGIF, int* delayMilliseconds, void* pUser);
|
||||
int GIF_getCanvasWidth(GIFIMAGE* pGIF);
|
||||
int GIF_getCanvasHeight(GIFIMAGE* pGIF);
|
||||
int GIF_getComment(GIFIMAGE* pGIF, char* destBuffer);
|
||||
int GIF_getInfo(GIFIMAGE* pGIF, GIFINFO* pInfo);
|
||||
int GIF_getLastError(GIFIMAGE* pGIF);
|
||||
int GIF_getLoopCount(GIFIMAGE* pGIF);
|
||||
#endif // __cplusplus
|
||||
|
||||
// Due to unaligned memory causing an exception, we have to do these macros the slow way
|
||||
#define INTELSHORT(p) ((*p) + (*(p+1)<<8))
|
||||
#define INTELLONG(p) ((*p) + (*(p+1)<<8) + (*(p+2)<<16) + (*(p+3)<<24))
|
||||
#define MOTOSHORT(p) (((*(p))<<8) + (*(p+1)))
|
||||
#define MOTOLONG(p) (((*p)<<24) + ((*(p+1))<<16) + ((*(p+2))<<8) + (*(p+3)))
|
||||
#define INTELSHORT(p) ((*p) + (*(p + 1) << 8))
|
||||
#define INTELLONG(p) ((*p) + (*(p + 1) << 8) + (*(p + 2) << 16) + (*(p + 3) << 24))
|
||||
#define MOTOSHORT(p) (((*(p)) << 8) + (*(p + 1)))
|
||||
#define MOTOLONG(p) (((*p) << 24) + ((*(p + 1)) << 16) + ((*(p + 2)) << 8) + (*(p + 3)))
|
||||
|
||||
// Must be a 32-bit target processor
|
||||
#define REGISTER_WIDTH 32
|
||||
|
||||
@@ -7,15 +7,15 @@
|
||||
|
||||
#ifndef INC_LCD_API_H_
|
||||
#define INC_LCD_API_H_
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define LOGGER_LEVEL_ALL
|
||||
#include "log.h"
|
||||
#include "../../Drivers/BSP/STM32746G-Discovery/stm32746g_discovery_lcd.h"
|
||||
#include "llfs.h"
|
||||
#include "gifdec.h"
|
||||
#include "llfs.h"
|
||||
#include "log.h"
|
||||
|
||||
/**
|
||||
* @brief The maximum amount of GIFs that can be displayed at the same time
|
||||
@@ -61,7 +61,6 @@
|
||||
#define LCD_FONT20 (&Font20)
|
||||
#define LCD_FONT24 (&Font24)
|
||||
|
||||
|
||||
extern LTDC_HandleTypeDef hLtdcHandler;
|
||||
|
||||
typedef struct {
|
||||
@@ -105,7 +104,7 @@ void lcd_task(void);
|
||||
* @param[in] bg_color Text background color
|
||||
* @param[in] font Font size, see defines above in file
|
||||
*/
|
||||
void lcd_display_text(const char* text, uint32_t x_pos, uint32_t y_pos, uint32_t color, uint32_t bg_color, sFONT *font);
|
||||
void lcd_display_text(const char* text, uint32_t x_pos, uint32_t y_pos, uint32_t color, uint32_t bg_color, sFONT* font);
|
||||
|
||||
/**
|
||||
* @brief Draw BMP image on screen
|
||||
@@ -121,7 +120,12 @@ void lcd_display_text(const char* text, uint32_t x_pos, uint32_t y_pos, uint32_t
|
||||
* @param[in] y_size Height of image
|
||||
* @param[in] color_mode Color mode (see defined color modes above in file)
|
||||
*/
|
||||
void lcd_draw_raw_img(const void* p_src, uint32_t x_pos, uint32_t y_pos, uint32_t x_size, uint32_t y_size, uint32_t color_mode);
|
||||
void lcd_draw_raw_img(const void* p_src,
|
||||
uint32_t x_pos,
|
||||
uint32_t y_pos,
|
||||
uint32_t x_size,
|
||||
uint32_t y_size,
|
||||
uint32_t color_mode);
|
||||
|
||||
/**
|
||||
* @brief Draw BMP image on screen
|
||||
@@ -187,7 +191,8 @@ void lcd_stop_all_gifs(void);
|
||||
/**
|
||||
* @brief Draw GIF image on screen from memory
|
||||
* Draw GIF image from memory to the LCD screen at position X, Y
|
||||
* @warning If the GIF has a loop count specified, it will stop after the specified amount of loops and the lcd_gif_t handle will be invalid for further use
|
||||
* @warning If the GIF has a loop count specified, it will stop after the specified amount of loops and the lcd_gif_t
|
||||
* handle will be invalid for further use
|
||||
* @note Before drawing over a GIF, make sure to call lcd_stop_gif(), otherwise the GIF will keep overwriting the screen
|
||||
*
|
||||
* @param src Pointer to the GIF image data
|
||||
@@ -201,7 +206,8 @@ lcd_gif_t* lcd_draw_gif(uint8_t* src, size_t size, uint32_t x_pos, uint32_t y_po
|
||||
/**
|
||||
* @brief Draw GIF image on screen from filesystem
|
||||
* Draw GIF image from filesystem to the LCD screen at position X, Y
|
||||
* @warning If the GIF has a loop count specified, it will stop after the specified amount of loops and the lcd_git_t handle will be invalidated
|
||||
* @warning If the GIF has a loop count specified, it will stop after the specified amount of loops and the lcd_git_t
|
||||
* handle will be invalidated
|
||||
* @note Before drawing over a GIF, make sure to call lcd_stop_gif(), otherwise the GIF will keep overwriting the screen
|
||||
*
|
||||
* @param name The filename of the GIF image
|
||||
@@ -214,7 +220,8 @@ lcd_gif_t* lcd_draw_gif_from_fs(const char* name, uint32_t x_pos, uint32_t y_pos
|
||||
/**
|
||||
* @brief Draw GIF image on screen from filesystem
|
||||
* Draw GIF image from filesystem to the LCD screen at position X, Y
|
||||
* @warning If the GIF has a loop count specified, it will stop after the specified amount of loops and the lcd_git_t handle will be invalidated
|
||||
* @warning If the GIF has a loop count specified, it will stop after the specified amount of loops and the lcd_git_t
|
||||
* handle will be invalidated
|
||||
* @note Before drawing over a GIF, make sure to call lcd_stop_gif(), otherwise the GIF will keep overwriting the screen
|
||||
*
|
||||
* @param file The pointer to the llfs_file_t
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#ifndef LOG_H
|
||||
#define LOG_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/times.h>
|
||||
@@ -88,27 +88,37 @@
|
||||
#endif
|
||||
|
||||
#if LOGGER_LEVEL <= 1
|
||||
#define LOG_DEBUG(tag, fmt, ...) printf(LOG_COLOR_D"[Debug] (%8lu) [%s]: " fmt LOG_RESET_COLOR "\r\n", logger_get_timestamp(), tag, ##__VA_ARGS__)
|
||||
#define LOG_DEBUG(tag, fmt, ...) \
|
||||
printf(LOG_COLOR_D "[Debug] (%8lu) [%s]: " fmt LOG_RESET_COLOR "\r\n", logger_get_timestamp(), tag, \
|
||||
##__VA_ARGS__)
|
||||
#else
|
||||
#define LOG_DEBUG(tag, fmt, ...)
|
||||
#endif
|
||||
#if LOGGER_LEVEL <= 2
|
||||
#define LOG_INFO(tag, fmt, ...) printf(LOG_COLOR_I"[Info] (%8lu) [%s]: " fmt LOG_RESET_COLOR "\r\n", logger_get_timestamp(), tag, ##__VA_ARGS__)
|
||||
#define LOG_INFO(tag, fmt, ...) \
|
||||
printf(LOG_COLOR_I "[Info] (%8lu) [%s]: " fmt LOG_RESET_COLOR "\r\n", logger_get_timestamp(), tag, \
|
||||
##__VA_ARGS__)
|
||||
#else
|
||||
#define LOG_INFO(tag, fmt, ...)
|
||||
#endif
|
||||
#if LOGGER_LEVEL <= 3
|
||||
#define LOG_WARN(tag, fmt, ...) printf(LOG_COLOR_W"[Warning] (%8lu) [%s]: " fmt LOG_RESET_COLOR "\r\n", logger_get_timestamp(), tag, ##__VA_ARGS__)
|
||||
#define LOG_WARN(tag, fmt, ...) \
|
||||
printf(LOG_COLOR_W "[Warning] (%8lu) [%s]: " fmt LOG_RESET_COLOR "\r\n", logger_get_timestamp(), tag, \
|
||||
##__VA_ARGS__)
|
||||
#else
|
||||
#define LOG_WARN(tag, fmt, ...)
|
||||
#endif
|
||||
#if LOGGER_LEVEL <= 4
|
||||
#define LOG_CRIT(tag, fmt, ...) printf(LOG_COLOR_C"[Critical] (%8lu) [%s]: " fmt LOG_RESET_COLOR "\r\n", logger_get_timestamp(), tag, ##__VA_ARGS__)
|
||||
#define LOG_CRIT(tag, fmt, ...) \
|
||||
printf(LOG_COLOR_C "[Critical] (%8lu) [%s]: " fmt LOG_RESET_COLOR "\r\n", logger_get_timestamp(), tag, \
|
||||
##__VA_ARGS__)
|
||||
#else
|
||||
#define LOG_CRIT(tag, fmt, ...)
|
||||
#endif
|
||||
#if LOGGER_LEVEL <= 4
|
||||
#define LOG_FATAL(tag, fmt, ...) printf(LOG_COLOR_F"[Fatal] (%8lu) [%s]: " fmt LOG_RESET_COLOR "\r\n", logger_get_timestamp(), tag, ##__VA_ARGS__)
|
||||
#define LOG_FATAL(tag, fmt, ...) \
|
||||
printf(LOG_COLOR_F "[Fatal] (%8lu) [%s]: " fmt LOG_RESET_COLOR "\r\n", logger_get_timestamp(), tag, \
|
||||
##__VA_ARGS__)
|
||||
#else
|
||||
#define LOG_FATAL(tag, fmt, ...)
|
||||
#endif
|
||||
@@ -117,6 +127,6 @@
|
||||
* Use the LOG_* macros instead e.g., LOG_DEBUG(TAG, "Debug message");
|
||||
*/
|
||||
uint32_t logger_get_timestamp(void);
|
||||
int _write(int file, char *data, int len);
|
||||
int _write(int file, char* data, int len);
|
||||
|
||||
#endif /* LOG_H */
|
||||
@@ -11,15 +11,13 @@
|
||||
|
||||
#define MODBUSPORT 502 // 502 is the default
|
||||
|
||||
|
||||
#include <tcp.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <tcp.h>
|
||||
#include "lcd_api.h"
|
||||
#include "llfs.h"
|
||||
|
||||
|
||||
/**
|
||||
* @fn void modbus_init
|
||||
* @brief Initializes the modbus tcp
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
/**
|
||||
* @file tcp_cmd.h
|
||||
* @brief TCP CMD interface
|
||||
* @author Gert R.
|
||||
*/
|
||||
* @file tcp_cmd.h
|
||||
* @brief TCP CMD interface
|
||||
* @author Gert R.
|
||||
*/
|
||||
|
||||
#ifndef INC_TCP_CMD_H_
|
||||
#define INC_TCP_CMD_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <tcp.h>
|
||||
#include "lcd_api.h"
|
||||
#include "llfs.h"
|
||||
#include "log.h"
|
||||
#include <tcp.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
void tcp_cmd_init( void );
|
||||
|
||||
void tcp_cmd_init(void);
|
||||
|
||||
#endif /* INC_TCP_CMD_H_ */
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#define INC_WEBSITE_BACKEND_
|
||||
|
||||
/* Include headers C lib */
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Defines */
|
||||
#define LOGGER_LEVEL_ALL
|
||||
@@ -20,12 +20,12 @@
|
||||
#define SD_IMG "st.bmp"
|
||||
|
||||
/* Include headers */
|
||||
#include "httpd.h"
|
||||
#include "lcd_api.h"
|
||||
#include "llfs.h"
|
||||
#include "log.h"
|
||||
#include "lwip.h"
|
||||
#include "httpd.h"
|
||||
#include "lwip/apps/fs.h"
|
||||
#include "llfs.h"
|
||||
#include "lcd_api.h"
|
||||
|
||||
/**
|
||||
* @fn void wbe_init(void)
|
||||
|
||||
@@ -49,20 +49,18 @@ static void udp_broadcast_set_owner_details_mac(void) {
|
||||
* @see UDP_BROADCAST_LCD_NAME_PRE_TEXT in front of it
|
||||
*/
|
||||
|
||||
static void udp_broadcast_name_to_lcd(void){
|
||||
static void udp_broadcast_name_to_lcd(void) {
|
||||
char text[UDP_BROADCAST_LCD_TEXT_SIZE];
|
||||
|
||||
memset(text,' ',UDP_BROADCAST_LCD_TEXT_SIZE); // Fill with spaces
|
||||
memset(text, ' ', UDP_BROADCAST_LCD_TEXT_SIZE); // Fill with spaces
|
||||
text[UDP_BROADCAST_LCD_TEXT_SIZE - 1] = '\0'; // Make the last a NULL byte
|
||||
lcd_display_text(text, owner_name_x_pos, owner_name_y_pos, LCD_BLACK, LCD_WHITE, LCD_FONT12);
|
||||
|
||||
snprintf(text, UDP_BROADCAST_LCD_TEXT_SIZE, "%s%s",UDP_BROADCAST_LCD_NAME_PRE_TEXT,
|
||||
udp_owner.name);
|
||||
snprintf(text, UDP_BROADCAST_LCD_TEXT_SIZE, "%s%s", UDP_BROADCAST_LCD_NAME_PRE_TEXT, udp_owner.name);
|
||||
|
||||
lcd_display_text(text, owner_name_x_pos, owner_name_y_pos, LCD_BLACK, LCD_WHITE, LCD_FONT12);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @fn uint8_t udp_broadcast_set_owner_details_name(owner_details_t*, const char*)
|
||||
* @brief set_owner_details_name() sets the owner's name in the owner_details_t struct
|
||||
@@ -76,7 +74,6 @@ static void udp_broadcast_name_to_lcd(void){
|
||||
*/
|
||||
|
||||
static uint8_t udp_broadcast_set_owner_details_name(const char* name) {
|
||||
|
||||
if (name == NULL) {
|
||||
LOG_WARN(TAG, "%s: string given is a NULL pointer", __func__);
|
||||
return 1;
|
||||
@@ -104,7 +101,7 @@ static uint8_t udp_broadcast_set_owner_details_surname(const char* surname) {
|
||||
return 1;
|
||||
}
|
||||
LOG_DEBUG(TAG, "set: %s", surname);
|
||||
strncpy(udp_owner.surname, surname, sizeof(udp_owner.surname)-1); // -1: compensate for '\0'
|
||||
strncpy(udp_owner.surname, surname, sizeof(udp_owner.surname) - 1); // -1: compensate for '\0'
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -144,8 +141,8 @@ static void udp_broadcast_format_reply(void) {
|
||||
udp_owner.mac_address[1], udp_owner.mac_address[2], udp_owner.mac_address[3], udp_owner.mac_address[4],
|
||||
udp_owner.mac_address[5]);
|
||||
|
||||
snprintf(reply_buf, UDP_BROADCAST_MAX_REPLY_SIZE, "%s %s %s %s", mac_addr_str, UDP_BROADCAST_REPLY_MIDDLE_TEXT, udp_owner.surname,
|
||||
udp_owner.name);
|
||||
snprintf(reply_buf, UDP_BROADCAST_MAX_REPLY_SIZE, "%s %s %s %s", mac_addr_str, UDP_BROADCAST_REPLY_MIDDLE_TEXT,
|
||||
udp_owner.surname, udp_owner.name);
|
||||
udp_broadcast_set_owner_details_reply(reply_buf);
|
||||
}
|
||||
|
||||
@@ -163,7 +160,6 @@ static void udp_broadcast_format_reply(void) {
|
||||
*/
|
||||
err_t udp_broadcast_set_owner_details(const char* name, const char* surname) {
|
||||
if (!udp_broadcast_set_owner_details_name(name) && !udp_broadcast_set_owner_details_surname(surname)) {
|
||||
|
||||
// If both return 0 it's okay
|
||||
udp_broadcast_set_owner_details_mac();
|
||||
udp_broadcast_format_reply();
|
||||
@@ -234,7 +230,7 @@ static uint8_t udp_broadcast_check_function(const char data[UDP_BROADCAST_MAX_DA
|
||||
memset(func, 0, sizeof(func));
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
memcpy(func,data,UDP_BROADCAST_MAX_FUNC_LEN - 1);
|
||||
memcpy(func, data, UDP_BROADCAST_MAX_FUNC_LEN - 1);
|
||||
if (strcmp(func, "func1:") != 0) {
|
||||
LOG_WARN(TAG, "%s: datagram does not contain function that's currently available", __func__);
|
||||
return 1;
|
||||
@@ -245,15 +241,15 @@ static uint8_t udp_broadcast_check_function(const char data[UDP_BROADCAST_MAX_DA
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
if (enders[2] - enders[1] < UDP_BROADCAST_MAX_NAME_SIZE + 2 && data_len - enders[3] < UDP_BROADCAST_MAX_NAME_SIZE + 2
|
||||
&& strncmp(data + enders[0], ":name", 5) == 0 && strncmp(data + enders[2], ", surname", 9) == 0) {
|
||||
|
||||
if (enders[2] - enders[1] < UDP_BROADCAST_MAX_NAME_SIZE + 2
|
||||
&& data_len - enders[3] < UDP_BROADCAST_MAX_NAME_SIZE + 2 && strncmp(data + enders[0], ":name", 5) == 0
|
||||
&& strncmp(data + enders[2], ", surname", 9) == 0) {
|
||||
counter = 0;
|
||||
for (uint8_t i = enders[1] + 2; i < enders[2]; i++) {
|
||||
buffer[counter] = data[i];
|
||||
counter++;
|
||||
}
|
||||
if (buffer[0]=='\0') {
|
||||
if (buffer[0] == '\0') {
|
||||
strncpy(buffer, "name", sizeof(buffer) - 1); // -1: compensate for '\0'
|
||||
}
|
||||
LOG_INFO(TAG, "new owner name:%s", buffer);
|
||||
@@ -264,7 +260,7 @@ static uint8_t udp_broadcast_check_function(const char data[UDP_BROADCAST_MAX_DA
|
||||
buffer[counter] = data[i];
|
||||
counter++;
|
||||
}
|
||||
if (buffer[0]=='\0') {
|
||||
if (buffer[0] == '\0') {
|
||||
strncpy(buffer, "default", sizeof(buffer) - 1); // -1: compensate for '\0'
|
||||
}
|
||||
LOG_INFO(TAG, "new owner surname:%s", buffer);
|
||||
@@ -272,7 +268,7 @@ static uint8_t udp_broadcast_check_function(const char data[UDP_BROADCAST_MAX_DA
|
||||
udp_broadcast_format_reply();
|
||||
return 0;
|
||||
}
|
||||
LOG_WARN(TAG,"%s: function didn't receive the right formatting", __func__);
|
||||
LOG_WARN(TAG, "%s: function didn't receive the right formatting", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -328,7 +324,7 @@ static void udp_receive_callback(void* arg,
|
||||
LOG_INFO(TAG, "%s: received data from %s at port: %d: %s", __func__, source_ip_str, port, data);
|
||||
LOG_INFO(TAG, "%s: checking which function was called", __func__);
|
||||
|
||||
if(!udp_broadcast_check_function(data)){ // Should return 0 to reply
|
||||
if (!udp_broadcast_check_function(data)) { // Should return 0 to reply
|
||||
p_data->payload = udp_owner.reply;
|
||||
p_data->len = strlen(udp_owner.reply);
|
||||
p_data->tot_len = strlen(udp_owner.reply);
|
||||
@@ -336,7 +332,6 @@ static void udp_receive_callback(void* arg,
|
||||
LOG_INFO(TAG, "%s: tried to reply to %s at port: %d: %s", __func__, source_ip_str, 64000, udp_owner.reply);
|
||||
}
|
||||
|
||||
|
||||
defer:
|
||||
pbuf_free(p);
|
||||
pbuf_free(p_data);
|
||||
@@ -375,8 +370,6 @@ err_t udp_broadcast_connection_init(void) {
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @fn err_t udp_broadcast_init()
|
||||
* @brief udp_broadcast_init() initializes the owner's variables and calls upon @see udp_broadcast_connection_init()
|
||||
@@ -391,7 +384,7 @@ err_t udp_broadcast_connection_init(void) {
|
||||
err_t udp_broadcast_init(uint32_t x_pos, uint32_t y_pos) {
|
||||
owner_name_x_pos = x_pos;
|
||||
owner_name_y_pos = y_pos;
|
||||
if(udp_broadcast_set_owner_details("name", "default") != ERR_OK){
|
||||
if (udp_broadcast_set_owner_details("name", "default") != ERR_OK) {
|
||||
LOG_WARN(TAG, "%s: don't give NULL pointers as arguments for the owner's details", __func__);
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
@@ -24,25 +24,24 @@
|
||||
#define memcpy_P memcpy
|
||||
#endif
|
||||
|
||||
static const unsigned char cGIFBits[9] = {1,4,4,4,8,8,8,8,8}; // convert odd bpp values to ones we can handle
|
||||
static const unsigned char cGIFBits[9] = {1, 4, 4, 4, 8, 8, 8, 8, 8}; // convert odd bpp values to ones we can handle
|
||||
|
||||
// forward references
|
||||
static int GIFInit(GIFIMAGE *pGIF);
|
||||
static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly);
|
||||
static int GIFGetMoreData(GIFIMAGE *pPage);
|
||||
static void GIFMakePels(GIFIMAGE *pPage, unsigned int code);
|
||||
static int DecodeLZW(GIFIMAGE *pImage, int iOptions);
|
||||
static int32_t readMem(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen);
|
||||
static int32_t seekMem(GIFFILE *pFile, int32_t iPosition);
|
||||
int GIF_getInfo(GIFIMAGE *pPage, GIFINFO *pInfo);
|
||||
static int GIFInit(GIFIMAGE* pGIF);
|
||||
static int GIFParseInfo(GIFIMAGE* pPage, int bInfoOnly);
|
||||
static int GIFGetMoreData(GIFIMAGE* pPage);
|
||||
static void GIFMakePels(GIFIMAGE* pPage, unsigned int code);
|
||||
static int DecodeLZW(GIFIMAGE* pImage, int iOptions);
|
||||
static int32_t readMem(GIFFILE* pFile, uint8_t* pBuf, int32_t iLen);
|
||||
static int32_t seekMem(GIFFILE* pFile, int32_t iPosition);
|
||||
int GIF_getInfo(GIFIMAGE* pPage, GIFINFO* pInfo);
|
||||
#if 1
|
||||
static int32_t readFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen);
|
||||
static int32_t seekFile(GIFFILE *pFile, int32_t iPosition);
|
||||
static void closeFile(void *handle);
|
||||
static int32_t readFile(GIFFILE* pFile, uint8_t* pBuf, int32_t iLen);
|
||||
static int32_t seekFile(GIFFILE* pFile, int32_t iPosition);
|
||||
static void closeFile(void* handle);
|
||||
|
||||
// C API
|
||||
int GIF_openRAM(GIFIMAGE *pGIF, uint8_t *pData, int iDataSize, GIF_DRAW_CALLBACK *pfnDraw)
|
||||
{
|
||||
int GIF_openRAM(GIFIMAGE* pGIF, uint8_t* pData, int iDataSize, GIF_DRAW_CALLBACK* pfnDraw) {
|
||||
pGIF->iError = GIF_SUCCESS;
|
||||
pGIF->pfnRead = readMem;
|
||||
pGIF->pfnSeek = seekMem;
|
||||
@@ -54,20 +53,17 @@ int GIF_openRAM(GIFIMAGE *pGIF, uint8_t *pData, int iDataSize, GIF_DRAW_CALLBACK
|
||||
return GIFInit(pGIF);
|
||||
} /* GIF_openRAM() */
|
||||
|
||||
void GIF_close(GIFIMAGE *pGIF)
|
||||
{
|
||||
void GIF_close(GIFIMAGE* pGIF) {
|
||||
if (pGIF->pfnClose)
|
||||
(*pGIF->pfnClose)(pGIF->GIFFile.fHandle);
|
||||
} /* GIF_close() */
|
||||
|
||||
void GIF_begin(GIFIMAGE *pGIF, unsigned char ucPaletteType)
|
||||
{
|
||||
void GIF_begin(GIFIMAGE* pGIF, unsigned char ucPaletteType) {
|
||||
memset(pGIF, 0, sizeof(GIFIMAGE));
|
||||
pGIF->ucPaletteType = ucPaletteType;
|
||||
} /* GIF_begin() */
|
||||
|
||||
void GIF_reset(GIFIMAGE *pGIF)
|
||||
{
|
||||
void GIF_reset(GIFIMAGE* pGIF) {
|
||||
(*pGIF->pfnSeek)(&pGIF->GIFFile, 0);
|
||||
} /* GIF_reset() */
|
||||
|
||||
@@ -77,65 +73,56 @@ void GIF_reset(GIFIMAGE *pGIF)
|
||||
// 0 = good decode, no more frames
|
||||
// -1 = error
|
||||
//
|
||||
int GIF_playFrame(GIFIMAGE *pGIF, int *delayMilliseconds, void *pUser)
|
||||
{
|
||||
int GIF_playFrame(GIFIMAGE* pGIF, int* delayMilliseconds, void* pUser) {
|
||||
int rc;
|
||||
|
||||
if (delayMilliseconds)
|
||||
*delayMilliseconds = 0; // clear any old valid
|
||||
if (pGIF->GIFFile.iPos >= pGIF->GIFFile.iSize-1) // no more data exists
|
||||
if (pGIF->GIFFile.iPos >= pGIF->GIFFile.iSize - 1) // no more data exists
|
||||
{
|
||||
(*pGIF->pfnSeek)(&pGIF->GIFFile, 0); // seek to start
|
||||
}
|
||||
if (GIFParseInfo(pGIF, 0))
|
||||
{
|
||||
if (GIFParseInfo(pGIF, 0)) {
|
||||
pGIF->pUser = pUser;
|
||||
if (pGIF->iError == GIF_EMPTY_FRAME) // don't try to decode it
|
||||
return 0;
|
||||
rc = DecodeLZW(pGIF, 0);
|
||||
if (rc != 0) // problem
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0; // error parsing the frame info, we may be at the end of the file
|
||||
}
|
||||
// Return 1 for more frames or 0 if this was the last frame
|
||||
if (delayMilliseconds) // if not NULL, return the frame delay time
|
||||
*delayMilliseconds = pGIF->iFrameDelay;
|
||||
return (pGIF->GIFFile.iPos < pGIF->GIFFile.iSize-1);
|
||||
return (pGIF->GIFFile.iPos < pGIF->GIFFile.iSize - 1);
|
||||
} /* GIF_playFrame() */
|
||||
|
||||
int GIF_getCanvasWidth(GIFIMAGE *pGIF)
|
||||
{
|
||||
int GIF_getCanvasWidth(GIFIMAGE* pGIF) {
|
||||
return pGIF->iCanvasWidth;
|
||||
} /* GIF_getCanvasWidth() */
|
||||
|
||||
int GIF_getCanvasHeight(GIFIMAGE *pGIF)
|
||||
{
|
||||
int GIF_getCanvasHeight(GIFIMAGE* pGIF) {
|
||||
return pGIF->iCanvasHeight;
|
||||
} /* GIF_getCanvasHeight() */
|
||||
|
||||
int GIF_getLoopCount(GIFIMAGE *pGIF)
|
||||
{
|
||||
int GIF_getLoopCount(GIFIMAGE* pGIF) {
|
||||
return pGIF->iRepeatCount;
|
||||
} /* GIF_getLoopCount() */
|
||||
|
||||
int GIF_getComment(GIFIMAGE *pGIF, char *pDest)
|
||||
{
|
||||
int GIF_getComment(GIFIMAGE* pGIF, char* pDest) {
|
||||
int32_t iOldPos;
|
||||
|
||||
iOldPos = pGIF->GIFFile.iPos; // keep old position
|
||||
(*pGIF->pfnSeek)(&pGIF->GIFFile, pGIF->iCommentPos);
|
||||
(*pGIF->pfnRead)(&pGIF->GIFFile, (uint8_t *)pDest, pGIF->sCommentLen);
|
||||
(*pGIF->pfnRead)(&pGIF->GIFFile, (uint8_t*)pDest, pGIF->sCommentLen);
|
||||
(*pGIF->pfnSeek)(&pGIF->GIFFile, iOldPos);
|
||||
pDest[pGIF->sCommentLen] = 0; // zero terminate the string
|
||||
return (int)pGIF->sCommentLen;
|
||||
|
||||
} /* GIF_getComment() */
|
||||
|
||||
int GIF_getLastError(GIFIMAGE *pGIF)
|
||||
{
|
||||
int GIF_getLastError(GIFIMAGE* pGIF) {
|
||||
return pGIF->iError;
|
||||
} /* GIF_getLastError() */
|
||||
|
||||
@@ -143,8 +130,7 @@ int GIF_getLastError(GIFIMAGE *pGIF)
|
||||
//
|
||||
// Helper functions for memory based images
|
||||
//
|
||||
static int32_t readMem(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen)
|
||||
{
|
||||
static int32_t readMem(GIFFILE* pFile, uint8_t* pBuf, int32_t iLen) {
|
||||
int32_t iBytesRead;
|
||||
|
||||
iBytesRead = iLen;
|
||||
@@ -157,8 +143,7 @@ static int32_t readMem(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen)
|
||||
return iBytesRead;
|
||||
} /* readMem() */
|
||||
|
||||
static int32_t readFLASH(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen)
|
||||
{
|
||||
static int32_t readFLASH(GIFFILE* pFile, uint8_t* pBuf, int32_t iLen) {
|
||||
int32_t iBytesRead;
|
||||
|
||||
iBytesRead = iLen;
|
||||
@@ -171,31 +156,31 @@ static int32_t readFLASH(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen)
|
||||
return iBytesRead;
|
||||
} /* readFLASH() */
|
||||
|
||||
static int32_t seekMem(GIFFILE *pFile, int32_t iPosition)
|
||||
{
|
||||
if (iPosition < 0) iPosition = 0;
|
||||
else if (iPosition >= pFile->iSize) iPosition = pFile->iSize-1;
|
||||
static int32_t seekMem(GIFFILE* pFile, int32_t iPosition) {
|
||||
if (iPosition < 0)
|
||||
iPosition = 0;
|
||||
else if (iPosition >= pFile->iSize)
|
||||
iPosition = pFile->iSize - 1;
|
||||
pFile->iPos = iPosition;
|
||||
return iPosition;
|
||||
} /* seekMem() */
|
||||
|
||||
#if defined ( __LINUX__ ) || defined( __MCUXPRESSO )
|
||||
static void closeFile(void *handle)
|
||||
{
|
||||
fclose((FILE *)handle);
|
||||
#if defined(__LINUX__) || defined(__MCUXPRESSO)
|
||||
static void closeFile(void* handle) {
|
||||
fclose((FILE*)handle);
|
||||
} /* closeFile() */
|
||||
|
||||
static int32_t seekFile(GIFFILE *pFile, int32_t iPosition)
|
||||
{
|
||||
if (iPosition < 0) iPosition = 0;
|
||||
else if (iPosition >= pFile->iSize) iPosition = pFile->iSize-1;
|
||||
static int32_t seekFile(GIFFILE* pFile, int32_t iPosition) {
|
||||
if (iPosition < 0)
|
||||
iPosition = 0;
|
||||
else if (iPosition >= pFile->iSize)
|
||||
iPosition = pFile->iSize - 1;
|
||||
pFile->iPos = iPosition;
|
||||
fseek((FILE *)pFile->fHandle, iPosition, SEEK_SET);
|
||||
fseek((FILE*)pFile->fHandle, iPosition, SEEK_SET);
|
||||
return iPosition;
|
||||
} /* seekMem() */
|
||||
|
||||
static int32_t readFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen)
|
||||
{
|
||||
static int32_t readFile(GIFFILE* pFile, uint8_t* pBuf, int32_t iLen) {
|
||||
int32_t iBytesRead;
|
||||
|
||||
iBytesRead = iLen;
|
||||
@@ -203,7 +188,7 @@ static int32_t readFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen)
|
||||
iBytesRead = pFile->iSize - pFile->iPos;
|
||||
if (iBytesRead <= 0)
|
||||
return 0;
|
||||
iBytesRead = (int)fread(pBuf, 1, iBytesRead, (FILE *)pFile->fHandle);
|
||||
iBytesRead = (int)fread(pBuf, 1, iBytesRead, (FILE*)pFile->fHandle);
|
||||
pFile->iPos += iBytesRead;
|
||||
return iBytesRead;
|
||||
} /* readFile() */
|
||||
@@ -218,8 +203,7 @@ static int32_t readFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen)
|
||||
// returns 1 for success, 0 for failure
|
||||
// Fills in the canvas size of the GIFIMAGE structure
|
||||
//
|
||||
static int GIFInit(GIFIMAGE *pGIF)
|
||||
{
|
||||
static int GIFInit(GIFIMAGE* pGIF) {
|
||||
pGIF->GIFFile.iPos = 0; // start at beginning of file
|
||||
if (!GIFParseInfo(pGIF, 1)) // gather info for the first frame
|
||||
return 0; // something went wrong; not a GIF file?
|
||||
@@ -237,8 +221,7 @@ static int GIFInit(GIFIMAGE *pGIF)
|
||||
// and return the canvas size only
|
||||
// Returns 1 for success, 0 for failure
|
||||
//
|
||||
static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly)
|
||||
{
|
||||
static int GIFParseInfo(GIFIMAGE* pPage, int bInfoOnly) {
|
||||
int i, j, iColorTableBits;
|
||||
int iBytesRead;
|
||||
unsigned char c, *p;
|
||||
@@ -281,25 +264,22 @@ static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly)
|
||||
if (p[10] & 0x80) // global color table?
|
||||
{ // by default, convert to byte-reversed RGB565 for immediate use
|
||||
// Read enough additional data for the color table
|
||||
iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], 3*(1<<iColorTableBits));
|
||||
if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE || pPage->ucPaletteType == GIF_PALETTE_RGB565_BE)
|
||||
{
|
||||
for (i=0; i<(1<<iColorTableBits); i++)
|
||||
{
|
||||
iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], 3 * (1 << iColorTableBits));
|
||||
if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE || pPage->ucPaletteType == GIF_PALETTE_RGB565_BE) {
|
||||
for (i = 0; i < (1 << iColorTableBits); i++) {
|
||||
uint16_t usRGB565;
|
||||
usRGB565 = ((p[iOffset] >> 3) << 11); // R
|
||||
usRGB565 |= ((p[iOffset+1] >> 2) << 5); // G
|
||||
usRGB565 |= (p[iOffset+2] >> 3); // B
|
||||
usRGB565 |= ((p[iOffset + 1] >> 2) << 5); // G
|
||||
usRGB565 |= (p[iOffset + 2] >> 3); // B
|
||||
if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE)
|
||||
pPage->pPalette[i] = usRGB565;
|
||||
else
|
||||
pPage->pPalette[i] = __builtin_bswap16(usRGB565); // SPI wants MSB first
|
||||
iOffset += 3;
|
||||
}
|
||||
}
|
||||
else // just copy it as-is
|
||||
} else // just copy it as-is
|
||||
{
|
||||
memcpy(pPage->pPalette, &p[iOffset], (1<<iColorTableBits) * 3);
|
||||
memcpy(pPage->pPalette, &p[iOffset], (1 << iColorTableBits) * 3);
|
||||
iOffset += (1 << iColorTableBits) * 3;
|
||||
}
|
||||
}
|
||||
@@ -309,17 +289,18 @@ static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly)
|
||||
if (p[iOffset] == '!') /* Extension block */
|
||||
{
|
||||
iOffset++;
|
||||
switch(p[iOffset++]) /* Block type */
|
||||
switch (p[iOffset++]) /* Block type */
|
||||
{
|
||||
case 0xf9: /* Graphic extension */
|
||||
if (p[iOffset] == 4) // correct length
|
||||
{
|
||||
pPage->ucGIFBits = p[iOffset+1]; // packed fields
|
||||
pPage->iFrameDelay = (INTELSHORT(&p[iOffset+2]))*10; // delay in ms
|
||||
if (pPage->iFrameDelay <= 1) // 0-1 is going to make it run at 60fps; use 100 (10fps) as a reasonable substitute
|
||||
pPage->ucGIFBits = p[iOffset + 1]; // packed fields
|
||||
pPage->iFrameDelay = (INTELSHORT(&p[iOffset + 2])) * 10; // delay in ms
|
||||
if (pPage->iFrameDelay
|
||||
<= 1) // 0-1 is going to make it run at 60fps; use 100 (10fps) as a reasonable substitute
|
||||
pPage->iFrameDelay = 100;
|
||||
if (pPage->ucGIFBits & 1) // transparent color is used
|
||||
pPage->ucTransparent = p[iOffset+4]; // transparent color index
|
||||
pPage->ucTransparent = p[iOffset + 4]; // transparent color index
|
||||
iOffset += 6;
|
||||
}
|
||||
// else // error
|
||||
@@ -329,20 +310,20 @@ static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly)
|
||||
while (c) /* Skip all data sub-blocks */
|
||||
{
|
||||
c = p[iOffset++]; /* Block length */
|
||||
if ((iBytesRead - iOffset) < (c+32)) // need to read more data first
|
||||
if ((iBytesRead - iOffset) < (c + 32)) // need to read more data first
|
||||
{
|
||||
memmove(pPage->ucFileBuf, &pPage->ucFileBuf[iOffset], (iBytesRead-iOffset)); // move existing data down
|
||||
memmove(pPage->ucFileBuf, &pPage->ucFileBuf[iOffset],
|
||||
(iBytesRead - iOffset)); // move existing data down
|
||||
iBytesRead -= iOffset;
|
||||
iStartPos += iOffset;
|
||||
iOffset = 0;
|
||||
iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], c+32);
|
||||
iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], c + 32);
|
||||
}
|
||||
if (c == 11) // fixed block length
|
||||
{ // Netscape app block contains the repeat count
|
||||
if (memcmp(&p[iOffset], "NETSCAPE2.0", 11) == 0)
|
||||
{
|
||||
if (p[iOffset+11] == 3 && p[iOffset+12] == 1) // loop count
|
||||
pPage->iRepeatCount = INTELSHORT(&p[iOffset+13]);
|
||||
if (memcmp(&p[iOffset], "NETSCAPE2.0", 11) == 0) {
|
||||
if (p[iOffset + 11] == 3 && p[iOffset + 12] == 1) // loop count
|
||||
pPage->iRepeatCount = INTELSHORT(&p[iOffset + 13]);
|
||||
}
|
||||
}
|
||||
iOffset += (int)c; /* Skip to next sub-block */
|
||||
@@ -371,13 +352,14 @@ static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly)
|
||||
while (c) /* Skip all data sub-blocks */
|
||||
{
|
||||
c = p[iOffset++]; /* Block length */
|
||||
if ((iBytesRead - iOffset) < (c+32)) // need to read more data first
|
||||
if ((iBytesRead - iOffset) < (c + 32)) // need to read more data first
|
||||
{
|
||||
memmove(pPage->ucFileBuf, &pPage->ucFileBuf[iOffset], (iBytesRead-iOffset)); // move existing data down
|
||||
memmove(pPage->ucFileBuf, &pPage->ucFileBuf[iOffset],
|
||||
(iBytesRead - iOffset)); // move existing data down
|
||||
iBytesRead -= iOffset;
|
||||
iStartPos += iOffset;
|
||||
iOffset = 0;
|
||||
iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], c+32);
|
||||
iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], c + 32);
|
||||
}
|
||||
if (pPage->iCommentPos == 0) // Save first block info
|
||||
{
|
||||
@@ -392,8 +374,7 @@ static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly)
|
||||
pPage->iError = GIF_DECODE_ERROR;
|
||||
return 0;
|
||||
} /* switch */
|
||||
}
|
||||
else // invalid byte, stop decoding
|
||||
} else // invalid byte, stop decoding
|
||||
{
|
||||
if (pPage->GIFFile.iSize - iStartPos < 32) // non-image bytes at end of file?
|
||||
pPage->iError = GIF_EMPTY_FRAME;
|
||||
@@ -412,9 +393,9 @@ static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly)
|
||||
iOffset++;
|
||||
// This particular frame's size and position on the main frame (if animated)
|
||||
pPage->iX = INTELSHORT(&p[iOffset]);
|
||||
pPage->iY = INTELSHORT(&p[iOffset+2]);
|
||||
pPage->iWidth = INTELSHORT(&p[iOffset+4]);
|
||||
pPage->iHeight = INTELSHORT(&p[iOffset+6]);
|
||||
pPage->iY = INTELSHORT(&p[iOffset + 2]);
|
||||
pPage->iWidth = INTELSHORT(&p[iOffset + 4]);
|
||||
pPage->iHeight = INTELSHORT(&p[iOffset + 6]);
|
||||
iOffset += 8;
|
||||
|
||||
/* Image descriptor
|
||||
@@ -426,29 +407,26 @@ static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly)
|
||||
*/
|
||||
pPage->ucMap = p[iOffset++];
|
||||
if (pPage->ucMap & 0x80) // local color table?
|
||||
{// by default, convert to byte-reversed RGB565 for immediate use
|
||||
j = (1<<((pPage->ucMap & 7)+1));
|
||||
{ // by default, convert to byte-reversed RGB565 for immediate use
|
||||
j = (1 << ((pPage->ucMap & 7) + 1));
|
||||
// Read enough additional data for the color table
|
||||
iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], j*3);
|
||||
if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE || pPage->ucPaletteType == GIF_PALETTE_RGB565_BE)
|
||||
{
|
||||
for (i=0; i<j; i++)
|
||||
{
|
||||
iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], j * 3);
|
||||
if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE || pPage->ucPaletteType == GIF_PALETTE_RGB565_BE) {
|
||||
for (i = 0; i < j; i++) {
|
||||
uint16_t usRGB565;
|
||||
usRGB565 = ((p[iOffset] >> 3) << 11); // R
|
||||
usRGB565 |= ((p[iOffset+1] >> 2) << 5); // G
|
||||
usRGB565 |= (p[iOffset+2] >> 3); // B
|
||||
usRGB565 |= ((p[iOffset + 1] >> 2) << 5); // G
|
||||
usRGB565 |= (p[iOffset + 2] >> 3); // B
|
||||
if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE)
|
||||
pPage->pLocalPalette[i] = usRGB565;
|
||||
else
|
||||
pPage->pLocalPalette[i] = __builtin_bswap16(usRGB565); // SPI wants MSB first
|
||||
iOffset += 3;
|
||||
}
|
||||
}
|
||||
else // just copy it as-is
|
||||
} else // just copy it as-is
|
||||
{
|
||||
memcpy(pPage->pLocalPalette, &p[iOffset], j * 3);
|
||||
iOffset += j*3;
|
||||
iOffset += j * 3;
|
||||
}
|
||||
pPage->bUseLocalPalette = 1;
|
||||
}
|
||||
@@ -459,18 +437,15 @@ static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly)
|
||||
// into "pure" LZW
|
||||
pPage->iLZWSize = 0; // we're starting with no LZW data yet
|
||||
c = 1; // get chunk length
|
||||
while (c && iOffset < iBytesRead)
|
||||
{
|
||||
while (c && iOffset < iBytesRead) {
|
||||
// Serial.printf("iOffset=%d, iBytesRead=%d\n", iOffset, iBytesRead);
|
||||
c = p[iOffset++]; // get chunk length
|
||||
// Serial.printf("Chunk size = %d\n", c);
|
||||
if (c <= (iBytesRead - iOffset))
|
||||
{
|
||||
if (c <= (iBytesRead - iOffset)) {
|
||||
memcpy(&pPage->ucLZW[pPage->iLZWSize], &p[iOffset], c);
|
||||
pPage->iLZWSize += c;
|
||||
iOffset += c;
|
||||
}
|
||||
else // partial chunk in our buffer
|
||||
} else // partial chunk in our buffer
|
||||
{
|
||||
int iPartialLen = (iBytesRead - iOffset);
|
||||
memcpy(&pPage->ucLZW[pPage->iLZWSize], &p[iOffset], iPartialLen);
|
||||
@@ -484,8 +459,7 @@ static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly)
|
||||
}
|
||||
// seeking on an SD card is VERY VERY SLOW, so use the data we've already read by de-chunking it
|
||||
// in this case, there's too much data, so we have to seek backwards a bit
|
||||
if (iOffset < iBytesRead)
|
||||
{
|
||||
if (iOffset < iBytesRead) {
|
||||
// Serial.printf("Need to seek back %d bytes\n", iBytesRead - iOffset);
|
||||
(*pPage->pfnSeek)(&pPage->GIFFile, iStartPos + iOffset); // position file to new spot
|
||||
}
|
||||
@@ -494,8 +468,7 @@ static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly)
|
||||
//
|
||||
// Gather info about an animated GIF file
|
||||
//
|
||||
int GIF_getInfo(GIFIMAGE *pPage, GIFINFO *pInfo)
|
||||
{
|
||||
int GIF_getInfo(GIFIMAGE* pPage, GIFINFO* pInfo) {
|
||||
int iOff, iNumFrames;
|
||||
int iDelay, iMaxDelay, iMinDelay, iTotalDelay;
|
||||
int iReadAmount;
|
||||
@@ -510,7 +483,7 @@ int GIF_getInfo(GIFIMAGE *pPage, GIFINFO *pInfo)
|
||||
iMinDelay = 10000;
|
||||
iNumFrames = 1;
|
||||
iDataRemaining = pPage->GIFFile.iSize;
|
||||
cBuf = (uint8_t *) pPage->ucFileBuf;
|
||||
cBuf = (uint8_t*)pPage->ucFileBuf;
|
||||
(*pPage->pfnSeek)(&pPage->GIFFile, 0);
|
||||
iDataAvailable = (*pPage->pfnRead)(&pPage->GIFFile, cBuf, FILE_BUF_SIZE);
|
||||
iDataRemaining -= iDataAvailable;
|
||||
@@ -521,25 +494,23 @@ int GIF_getInfo(GIFIMAGE *pPage, GIFINFO *pInfo)
|
||||
if (c & 0x80) /* Deal with global color table */
|
||||
{
|
||||
c &= 7; /* Get the number of colors defined */
|
||||
iOff += (2<<c)*3; /* skip color table */
|
||||
iOff += (2 << c) * 3; /* skip color table */
|
||||
}
|
||||
while (!bDone) // && iNumFrames < MAX_FRAMES)
|
||||
{
|
||||
bExt = 1; /* skip extension blocks */
|
||||
while (bExt && iOff < iDataAvailable)
|
||||
{
|
||||
while (bExt && iOff < iDataAvailable) {
|
||||
if ((iDataAvailable - iOff) < 258) // need to read more data first
|
||||
{
|
||||
memmove(cBuf, &cBuf[iOff], (iDataAvailable-iOff)); // move existing data down
|
||||
memmove(cBuf, &cBuf[iOff], (iDataAvailable - iOff)); // move existing data down
|
||||
iDataAvailable -= iOff;
|
||||
iOff = 0;
|
||||
iReadAmount = (*pPage->pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], FILE_BUF_SIZE-iDataAvailable);
|
||||
iReadAmount = (*pPage->pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], FILE_BUF_SIZE - iDataAvailable);
|
||||
iDataAvailable += iReadAmount;
|
||||
iDataRemaining -= iReadAmount;
|
||||
// lFileOff += iReadAmount;
|
||||
}
|
||||
switch(cBuf[iOff])
|
||||
{
|
||||
switch (cBuf[iOff]) {
|
||||
case 0x3b: /* End of file */
|
||||
/* we were fooled into thinking there were more pages */
|
||||
iNumFrames--;
|
||||
@@ -549,17 +520,19 @@ int GIF_getInfo(GIFIMAGE *pPage, GIFINFO *pInfo)
|
||||
// FF = Application Extension
|
||||
// 01 = Plain Text Extension
|
||||
case 0x21: /* Extension block */
|
||||
if (cBuf[iOff+1] == 0xf9 && cBuf[iOff+2] == 4) // Graphic Control Extension
|
||||
if (cBuf[iOff + 1] == 0xf9 && cBuf[iOff + 2] == 4) // Graphic Control Extension
|
||||
{
|
||||
//cBuf[iOff+3]; // page disposition flags
|
||||
iDelay = cBuf[iOff+4]; // delay low byte
|
||||
iDelay |= ((uint16_t)(cBuf[iOff+5]) << 8); // delay high byte
|
||||
// cBuf[iOff+3]; // page disposition flags
|
||||
iDelay = cBuf[iOff + 4]; // delay low byte
|
||||
iDelay |= ((uint16_t)(cBuf[iOff + 5]) << 8); // delay high byte
|
||||
if (iDelay < 2) // too fast, provide a default
|
||||
iDelay = 2;
|
||||
iDelay *= 10; // turn JIFFIES into milliseconds
|
||||
iTotalDelay += iDelay;
|
||||
if (iDelay > iMaxDelay) iMaxDelay = iDelay;
|
||||
else if (iDelay < iMinDelay) iMinDelay = iDelay;
|
||||
if (iDelay > iMaxDelay)
|
||||
iMaxDelay = iDelay;
|
||||
else if (iDelay < iMinDelay)
|
||||
iMinDelay = iDelay;
|
||||
// (cBuf[iOff+6]; // transparent color index
|
||||
}
|
||||
iOff += 2; /* skip to length */
|
||||
@@ -567,16 +540,16 @@ int GIF_getInfo(GIFIMAGE *pPage, GIFINFO *pInfo)
|
||||
iOff++;
|
||||
// block terminator or optional sub blocks
|
||||
c = cBuf[iOff++]; /* Skip any sub-blocks */
|
||||
while (c)
|
||||
{
|
||||
while (c) {
|
||||
iOff += (int)c;
|
||||
c = cBuf[iOff++];
|
||||
if ((iDataAvailable - iOff) < (c+258)) // need to read more data first
|
||||
if ((iDataAvailable - iOff) < (c + 258)) // need to read more data first
|
||||
{
|
||||
memmove(cBuf, &cBuf[iOff], (iDataAvailable-iOff)); // move existing data down
|
||||
memmove(cBuf, &cBuf[iOff], (iDataAvailable - iOff)); // move existing data down
|
||||
iDataAvailable -= iOff;
|
||||
iOff = 0;
|
||||
iReadAmount = (*pPage->pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], FILE_BUF_SIZE-iDataAvailable);
|
||||
iReadAmount = (*pPage->pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable],
|
||||
FILE_BUF_SIZE - iDataAvailable);
|
||||
iDataAvailable += iReadAmount;
|
||||
iDataRemaining -= iReadAmount;
|
||||
// lFileOff += iReadAmount;
|
||||
@@ -603,25 +576,25 @@ int GIF_getInfo(GIFIMAGE *pPage, GIFINFO *pInfo)
|
||||
goto gifpagesz;
|
||||
}
|
||||
/* Start of image data */
|
||||
c = cBuf[iOff+9]; /* Get the flags byte */
|
||||
c = cBuf[iOff + 9]; /* Get the flags byte */
|
||||
iOff += 10; /* Skip image position and size */
|
||||
if (c & 0x80) /* Local color table */
|
||||
{
|
||||
c &= 7;
|
||||
iOff += (2<<c)*3;
|
||||
iOff += (2 << c) * 3;
|
||||
}
|
||||
iOff++; /* Skip LZW code size byte */
|
||||
if ((iDataAvailable - iOff) < (c+258)) // need to read more data first
|
||||
if ((iDataAvailable - iOff) < (c + 258)) // need to read more data first
|
||||
{
|
||||
if (iOff < iDataAvailable) {
|
||||
memmove(cBuf, &cBuf[iOff], (iDataAvailable-iOff)); // move existing data down
|
||||
memmove(cBuf, &cBuf[iOff], (iDataAvailable - iOff)); // move existing data down
|
||||
iDataAvailable -= iOff;
|
||||
iOff = 0;
|
||||
} else { // already points beyond end
|
||||
iOff -= iDataAvailable;
|
||||
iDataAvailable = 0;
|
||||
}
|
||||
iReadAmount = (*pPage->pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], FILE_BUF_SIZE-iDataAvailable);
|
||||
iReadAmount = (*pPage->pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], FILE_BUF_SIZE - iDataAvailable);
|
||||
iDataAvailable += iReadAmount;
|
||||
iDataRemaining -= iReadAmount;
|
||||
// lFileOff += iReadAmount;
|
||||
@@ -629,9 +602,9 @@ int GIF_getInfo(GIFIMAGE *pPage, GIFINFO *pInfo)
|
||||
c = cBuf[iOff++];
|
||||
while (c) /* While there are more data blocks */
|
||||
{
|
||||
if (iOff > (3*FILE_BUF_SIZE/4) && iDataRemaining > 0) /* Near end of buffer, re-align */
|
||||
if (iOff > (3 * FILE_BUF_SIZE / 4) && iDataRemaining > 0) /* Near end of buffer, re-align */
|
||||
{
|
||||
memmove(cBuf, &cBuf[iOff], (iDataAvailable-iOff)); // move existing data down
|
||||
memmove(cBuf, &cBuf[iOff], (iDataAvailable - iOff)); // move existing data down
|
||||
iDataAvailable -= iOff;
|
||||
iOff = 0;
|
||||
iReadAmount = (FILE_BUF_SIZE - iDataAvailable);
|
||||
@@ -651,17 +624,16 @@ int GIF_getInfo(GIFIMAGE *pPage, GIFINFO *pInfo)
|
||||
c = cBuf[iOff++]; /* Get length of next */
|
||||
}
|
||||
/* End of image data, check for more pages... */
|
||||
if (cBuf[iOff] == 0x3b || (iDataRemaining == 0 && (iDataAvailable - iOff) < 32))
|
||||
{
|
||||
if (cBuf[iOff] == 0x3b || (iDataRemaining == 0 && (iDataAvailable - iOff) < 32)) {
|
||||
bDone = 1; /* End of file has been reached */
|
||||
}
|
||||
else /* More pages to scan */
|
||||
} else /* More pages to scan */
|
||||
{
|
||||
iNumFrames++;
|
||||
// read new page data starting at this offset
|
||||
if (pPage->GIFFile.iSize > FILE_BUF_SIZE && iDataRemaining > 0) // since we didn't read the whole file in one shot
|
||||
if (pPage->GIFFile.iSize > FILE_BUF_SIZE
|
||||
&& iDataRemaining > 0) // since we didn't read the whole file in one shot
|
||||
{
|
||||
memmove(cBuf, &cBuf[iOff], (iDataAvailable-iOff)); // move existing data down
|
||||
memmove(cBuf, &cBuf[iOff], (iDataAvailable - iOff)); // move existing data down
|
||||
iDataAvailable -= iOff;
|
||||
iOff = 0;
|
||||
iReadAmount = (FILE_BUF_SIZE - iDataAvailable);
|
||||
@@ -687,25 +659,22 @@ gifpagesz:
|
||||
// returns 1 to signify more data available for this image
|
||||
// 0 indicates there is no more data
|
||||
//
|
||||
static int GIFGetMoreData(GIFIMAGE *pPage)
|
||||
{
|
||||
static int GIFGetMoreData(GIFIMAGE* pPage) {
|
||||
int iDelta = (pPage->iLZWSize - pPage->iLZWOff);
|
||||
unsigned char c = 1;
|
||||
// move any existing data down
|
||||
if (pPage->bEndOfFrame || iDelta >= (LZW_BUF_SIZE - MAX_CHUNK_SIZE) || iDelta <= 0)
|
||||
return 1; // frame is finished or buffer is already full; no need to read more data
|
||||
if (pPage->iLZWOff != 0)
|
||||
{
|
||||
if (pPage->iLZWOff != 0) {
|
||||
// NB: memcpy() fails on some systems because the src and dest ptrs overlap
|
||||
// so copy the bytes in a simple loop to avoid problems
|
||||
for (int i=0; i<pPage->iLZWSize - pPage->iLZWOff; i++) {
|
||||
for (int i = 0; i < pPage->iLZWSize - pPage->iLZWOff; i++) {
|
||||
pPage->ucLZW[i] = pPage->ucLZW[i + pPage->iLZWOff];
|
||||
}
|
||||
pPage->iLZWSize -= pPage->iLZWOff;
|
||||
pPage->iLZWOff = 0;
|
||||
}
|
||||
while (c && pPage->GIFFile.iPos < pPage->GIFFile.iSize && pPage->iLZWSize < (LZW_BUF_SIZE-MAX_CHUNK_SIZE))
|
||||
{
|
||||
while (c && pPage->GIFFile.iPos < pPage->GIFFile.iSize && pPage->iLZWSize < (LZW_BUF_SIZE - MAX_CHUNK_SIZE)) {
|
||||
(*pPage->pfnRead)(&pPage->GIFFile, &c, 1); // current length
|
||||
(*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucLZW[pPage->iLZWSize], c);
|
||||
pPage->iLZWSize += c;
|
||||
@@ -718,8 +687,7 @@ static int GIFGetMoreData(GIFIMAGE *pPage)
|
||||
// Handle transparent pixels and disposal method
|
||||
// Used only when a frame buffer is allocated
|
||||
//
|
||||
static void DrawNewPixels(GIFIMAGE *pPage, GIFDRAW *pDraw)
|
||||
{
|
||||
static void DrawNewPixels(GIFIMAGE* pPage, GIFDRAW* pDraw) {
|
||||
uint8_t *d, *s;
|
||||
int x, iPitch = pPage->iCanvasWidth;
|
||||
|
||||
@@ -733,16 +701,13 @@ static void DrawNewPixels(GIFIMAGE *pPage, GIFDRAW *pDraw)
|
||||
if (pDraw->ucHasTransparency) // if transparency used
|
||||
{
|
||||
uint8_t c, ucTransparent = pDraw->ucTransparent;
|
||||
for (x=0; x<pDraw->iWidth; x++)
|
||||
{
|
||||
for (x = 0; x < pDraw->iWidth; x++) {
|
||||
c = *s++;
|
||||
if (c != ucTransparent)
|
||||
*d = c;
|
||||
d++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
memcpy(d, s, pDraw->iWidth); // just overwrite the old pixels
|
||||
}
|
||||
} /* DrawNewPixels() */
|
||||
@@ -751,30 +716,24 @@ static void DrawNewPixels(GIFIMAGE *pPage, GIFDRAW *pDraw)
|
||||
// to either RGB565 or RGB888 output
|
||||
// Used only when a frame buffer has been allocated
|
||||
//
|
||||
static void ConvertNewPixels(GIFIMAGE *pPage, GIFDRAW *pDraw)
|
||||
{
|
||||
static void ConvertNewPixels(GIFIMAGE* pPage, GIFDRAW* pDraw) {
|
||||
uint8_t *d, *s;
|
||||
int x;
|
||||
|
||||
s = &pPage->pFrameBuffer[(pPage->iCanvasWidth * (pDraw->iY + pDraw->y)) + pDraw->iX];
|
||||
d = &pPage->pFrameBuffer[pPage->iCanvasHeight * pPage->iCanvasWidth]; // point past bottom of frame buffer
|
||||
if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE || pPage->ucPaletteType == GIF_PALETTE_RGB565_BE)
|
||||
{
|
||||
if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE || pPage->ucPaletteType == GIF_PALETTE_RGB565_BE) {
|
||||
uint16_t *pPal, *pu16;
|
||||
pPal = (uint16_t *)pDraw->pPalette;
|
||||
pu16 = (uint16_t *)d;
|
||||
for (x=0; x<pPage->iWidth; x++)
|
||||
{
|
||||
pPal = (uint16_t*)pDraw->pPalette;
|
||||
pu16 = (uint16_t*)d;
|
||||
for (x = 0; x < pPage->iWidth; x++) {
|
||||
*pu16++ = pPal[*s++]; // convert to RGB565 pixels
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *pPal;
|
||||
} else {
|
||||
uint8_t* pPal;
|
||||
int pixel;
|
||||
pPal = (uint8_t *)pDraw->pPalette;
|
||||
for (x=0; x<pPage->iWidth; x++)
|
||||
{
|
||||
pPal = (uint8_t*)pDraw->pPalette;
|
||||
for (x = 0; x < pPage->iWidth; x++) {
|
||||
pixel = *s++;
|
||||
*d++ = pPal[(pixel * 3) + 0]; // convert to RGB888 pixels
|
||||
*d++ = pPal[(pixel * 3) + 1];
|
||||
@@ -786,10 +745,9 @@ static void ConvertNewPixels(GIFIMAGE *pPage, GIFDRAW *pDraw)
|
||||
//
|
||||
// GIFMakePels
|
||||
//
|
||||
static void GIFMakePels(GIFIMAGE *pPage, unsigned int code)
|
||||
{
|
||||
static void GIFMakePels(GIFIMAGE* pPage, unsigned int code) {
|
||||
int iPixCount;
|
||||
unsigned short *giftabs;
|
||||
unsigned short* giftabs;
|
||||
unsigned char *buf, *s, *pEnd, *gifpels;
|
||||
unsigned char ucNeedMore = 0;
|
||||
/* Copy this string of sequential pixels to output buffer */
|
||||
@@ -798,8 +756,7 @@ static void GIFMakePels(GIFIMAGE *pPage, unsigned int code)
|
||||
buf = pPage->ucLineBuf + (pPage->iWidth - pPage->iXCount);
|
||||
giftabs = pPage->usGIFTable;
|
||||
gifpels = &pPage->ucGIFPixels[PIXEL_LAST];
|
||||
while (code < LINK_UNUSED)
|
||||
{
|
||||
while (code < LINK_UNUSED) {
|
||||
if (s == pPage->ucFileBuf) /* Houston, we have a problem */
|
||||
{
|
||||
return; /* Exit with error */
|
||||
@@ -809,15 +766,13 @@ static void GIFMakePels(GIFIMAGE *pPage, unsigned int code)
|
||||
}
|
||||
iPixCount = (int)(intptr_t)(pPage->ucFileBuf + FILE_BUF_SIZE - s);
|
||||
|
||||
while (iPixCount && pPage->iYCount > 0)
|
||||
{
|
||||
while (iPixCount && pPage->iYCount > 0) {
|
||||
if (pPage->iXCount > iPixCount) /* Pixels fit completely on the line */
|
||||
{
|
||||
// memcpy(buf, s, iPixCount);
|
||||
// buf += iPixCount;
|
||||
pEnd = buf + iPixCount;
|
||||
while (buf < pEnd)
|
||||
{
|
||||
while (buf < pEnd) {
|
||||
*buf++ = *s++;
|
||||
}
|
||||
pPage->iXCount -= iPixCount;
|
||||
@@ -825,13 +780,11 @@ static void GIFMakePels(GIFIMAGE *pPage, unsigned int code)
|
||||
if (ucNeedMore)
|
||||
GIFGetMoreData(pPage); // check if we need to read more LZW data every 4 lines
|
||||
return;
|
||||
}
|
||||
else /* Pixels cross into next line */
|
||||
} else /* Pixels cross into next line */
|
||||
{
|
||||
GIFDRAW gd;
|
||||
pEnd = buf + pPage->iXCount;
|
||||
while (buf < pEnd)
|
||||
{
|
||||
while (buf < pEnd) {
|
||||
*buf++ = *s++;
|
||||
}
|
||||
iPixCount -= pPage->iXCount;
|
||||
@@ -843,13 +796,13 @@ static void GIFMakePels(GIFIMAGE *pPage, unsigned int code)
|
||||
gd.iHeight = pPage->iHeight;
|
||||
gd.pPixels = pPage->ucLineBuf;
|
||||
gd.pPalette = (pPage->bUseLocalPalette) ? pPage->pLocalPalette : pPage->pPalette;
|
||||
gd.pPalette24 = (uint8_t *)gd.pPalette; // just cast the pointer for RGB888
|
||||
gd.ucIsGlobalPalette = pPage->bUseLocalPalette==1?0:1;
|
||||
gd.pPalette24 = (uint8_t*)gd.pPalette; // just cast the pointer for RGB888
|
||||
gd.ucIsGlobalPalette = pPage->bUseLocalPalette == 1 ? 0 : 1;
|
||||
gd.y = pPage->iHeight - pPage->iYCount;
|
||||
// Ugly logic to handle the interlaced line position, but it
|
||||
// saves having to have another set of state variables
|
||||
if (pPage->ucMap & 0x40) { // interlaced?
|
||||
int height = pPage->iHeight-1;
|
||||
int height = pPage->iHeight - 1;
|
||||
if (gd.y > height / 2)
|
||||
gd.y = gd.y * 2 - (height | 1);
|
||||
else if (gd.y > height / 4)
|
||||
@@ -859,7 +812,7 @@ static void GIFMakePels(GIFIMAGE *pPage, unsigned int code)
|
||||
else
|
||||
gd.y = gd.y * 8;
|
||||
}
|
||||
gd.ucDisposalMethod = (pPage->ucGIFBits & 0x1c)>>2;
|
||||
gd.ucDisposalMethod = (pPage->ucGIFBits & 0x1c) >> 2;
|
||||
gd.ucTransparent = pPage->ucTransparent;
|
||||
gd.ucHasTransparency = pPage->ucGIFBits & 1;
|
||||
gd.ucBackground = pPage->ucBackground;
|
||||
@@ -867,8 +820,7 @@ static void GIFMakePels(GIFIMAGE *pPage, unsigned int code)
|
||||
if (pPage->pFrameBuffer) // update the frame buffer
|
||||
{
|
||||
DrawNewPixels(pPage, &gd);
|
||||
if (pPage->ucDrawType == GIF_DRAW_COOKED)
|
||||
{
|
||||
if (pPage->ucDrawType == GIF_DRAW_COOKED) {
|
||||
ConvertNewPixels(pPage, &gd); // prepare for output
|
||||
gd.pPixels = &pPage->pFrameBuffer[pPage->iCanvasWidth * pPage->iCanvasHeight];
|
||||
}
|
||||
@@ -887,23 +839,27 @@ static void GIFMakePels(GIFIMAGE *pPage, unsigned int code)
|
||||
//
|
||||
// Macro to extract a variable length code
|
||||
//
|
||||
#define GET_CODE if (bitnum > (REGISTER_WIDTH - codesize)) { pImage->iLZWOff += (bitnum >> 3); \
|
||||
bitnum &= 7; ulBits = INTELLONG(&p[pImage->iLZWOff]); } \
|
||||
code = (unsigned short) (ulBits >> bitnum); /* Read a 32-bit chunk */ \
|
||||
code &= sMask; bitnum += codesize;
|
||||
#define GET_CODE \
|
||||
if (bitnum > (REGISTER_WIDTH - codesize)) { \
|
||||
pImage->iLZWOff += (bitnum >> 3); \
|
||||
bitnum &= 7; \
|
||||
ulBits = INTELLONG(&p[pImage->iLZWOff]); \
|
||||
} \
|
||||
code = (unsigned short)(ulBits >> bitnum); /* Read a 32-bit chunk */ \
|
||||
code &= sMask; \
|
||||
bitnum += codesize;
|
||||
|
||||
//
|
||||
// Decode LZW into an image
|
||||
//
|
||||
static int DecodeLZW(GIFIMAGE *pImage, int iOptions)
|
||||
{
|
||||
static int DecodeLZW(GIFIMAGE* pImage, int iOptions) {
|
||||
int i, bitnum;
|
||||
unsigned short oldcode, codesize, nextcode, nextlim;
|
||||
unsigned short *giftabs, cc, eoi;
|
||||
signed short sMask;
|
||||
unsigned char *gifpels, *p;
|
||||
// int iStripSize;
|
||||
//unsigned char **index;
|
||||
// unsigned char **index;
|
||||
uint32_t ulBits;
|
||||
unsigned short code;
|
||||
(void)iOptions; // not used for now
|
||||
@@ -925,9 +881,8 @@ static int DecodeLZW(GIFIMAGE *pImage, int iOptions)
|
||||
|
||||
// Initialize code table
|
||||
// this part only needs to be initialized once
|
||||
for (i = 0; i < cc; i++)
|
||||
{
|
||||
gifpels[PIXEL_FIRST + i] = gifpels[PIXEL_LAST + i] = (unsigned short) i;
|
||||
for (i = 0; i < cc; i++) {
|
||||
gifpels[PIXEL_FIRST + i] = gifpels[PIXEL_LAST + i] = (unsigned short)i;
|
||||
giftabs[i] = LINK_END;
|
||||
}
|
||||
init_codetable:
|
||||
@@ -935,9 +890,9 @@ init_codetable:
|
||||
sMask = 0xffff << (pImage->ucCodeStart + 1);
|
||||
sMask = 0xffff - sMask;
|
||||
nextcode = cc + 2;
|
||||
nextlim = (unsigned short) ((1 << codesize));
|
||||
nextlim = (unsigned short)((1 << codesize));
|
||||
// This part of the table needs to be reset multiple times
|
||||
memset(&giftabs[cc], LINK_UNUSED, (4096 - cc)*sizeof(short));
|
||||
memset(&giftabs[cc], LINK_UNUSED, (4096 - cc) * sizeof(short));
|
||||
ulBits = INTELLONG(&p[pImage->iLZWOff]); // start by reading 4 bytes of LZW data
|
||||
GET_CODE
|
||||
if (code == cc) // we just reset the dictionary, so get another code
|
||||
@@ -947,13 +902,13 @@ init_codetable:
|
||||
oldcode = code;
|
||||
GIFMakePels(pImage, code); // first code is output as the first pixel
|
||||
// Main decode loop
|
||||
while (code != eoi && pImage->iYCount > 0) // && y < pImage->iHeight+1) /* Loop through all lines of the image (or strip) */
|
||||
while (code != eoi
|
||||
&& pImage->iYCount > 0) // && y < pImage->iHeight+1) /* Loop through all lines of the image (or strip) */
|
||||
{
|
||||
GET_CODE
|
||||
if (code == cc) /* Clear code?, and not first code */
|
||||
goto init_codetable;
|
||||
if (code != eoi)
|
||||
{
|
||||
if (code != eoi) {
|
||||
if (nextcode < nextlim) // for deferred cc case, don't let it overwrite the last entry (fff)
|
||||
{
|
||||
giftabs[nextcode] = oldcode;
|
||||
@@ -964,8 +919,7 @@ init_codetable:
|
||||
gifpels[PIXEL_LAST + nextcode] = gifpels[PIXEL_FIRST + code];
|
||||
}
|
||||
nextcode++;
|
||||
if (nextcode >= nextlim && codesize < MAX_CODE_SIZE)
|
||||
{
|
||||
if (nextcode >= nextlim && codesize < MAX_CODE_SIZE) {
|
||||
codesize++;
|
||||
nextlim <<= 1;
|
||||
sMask = (sMask << 1) | 1;
|
||||
@@ -975,14 +929,13 @@ init_codetable:
|
||||
}
|
||||
} /* while not end of LZW code stream */
|
||||
return 0;
|
||||
//gif_forced_error:
|
||||
// gif_forced_error:
|
||||
// free(pImage->pPixels);
|
||||
// pImage->pPixels = NULL;
|
||||
// return -1;
|
||||
} /* DecodeLZW() */
|
||||
|
||||
void GIF_setDrawCallback(GIFIMAGE *pGIF, GIF_DRAW_CALLBACK *pfnDraw)
|
||||
{
|
||||
void GIF_setDrawCallback(GIFIMAGE* pGIF, GIF_DRAW_CALLBACK* pfnDraw) {
|
||||
pGIF->pfnDraw = pfnDraw;
|
||||
} /* GIF_setDrawCallback() */
|
||||
//
|
||||
@@ -990,18 +943,19 @@ void GIF_setDrawCallback(GIFIMAGE *pGIF, GIF_DRAW_CALLBACK *pfnDraw)
|
||||
// writes new values over previous line
|
||||
// expects RGB565 little endian pixels as input
|
||||
//
|
||||
void GIF_scaleHalf(uint16_t *pCurrent, uint16_t *pPrev, int iWidth, int bBigEndian)
|
||||
{
|
||||
void GIF_scaleHalf(uint16_t* pCurrent, uint16_t* pPrev, int iWidth, int bBigEndian) {
|
||||
int x;
|
||||
uint16_t *d = pPrev;
|
||||
uint32_t gSum, rbSum, pix0,pix1,pix2,pix3;
|
||||
uint16_t* d = pPrev;
|
||||
uint32_t gSum, rbSum, pix0, pix1, pix2, pix3;
|
||||
const uint32_t RBMask = 0xf81f, GMask = 0x7e0;
|
||||
|
||||
for (x=0; x<iWidth; x+=2)
|
||||
{
|
||||
pix0 = pCurrent[0]; pix1 = pCurrent[1];
|
||||
pix2 = pPrev[0]; pix3 = pPrev[1];
|
||||
pCurrent += 2; pPrev += 2;
|
||||
for (x = 0; x < iWidth; x += 2) {
|
||||
pix0 = pCurrent[0];
|
||||
pix1 = pCurrent[1];
|
||||
pix2 = pPrev[0];
|
||||
pix3 = pPrev[1];
|
||||
pCurrent += 2;
|
||||
pPrev += 2;
|
||||
gSum = (pix0 & GMask) + (pix1 & GMask) + (pix2 & GMask) + (pix3 & GMask);
|
||||
gSum = ((gSum + 0x40) >> 2) & GMask; // for rounding towards 1
|
||||
rbSum = (pix0 & RBMask) + (pix1 & RBMask) + (pix2 & RBMask) + (pix3 & RBMask);
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include "lcd_api.h"
|
||||
|
||||
|
||||
static const char* TAG = "lcd_api";
|
||||
|
||||
static DMA2D_HandleTypeDef hDma2dHandler2;
|
||||
@@ -85,7 +84,12 @@ void lcd_task(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_display_text(const char* text, uint32_t x_pos, uint32_t y_pos, uint32_t color, uint32_t bg_color, sFONT* font) {
|
||||
void lcd_display_text(const char* text,
|
||||
uint32_t x_pos,
|
||||
uint32_t y_pos,
|
||||
uint32_t color,
|
||||
uint32_t bg_color,
|
||||
sFONT* font) {
|
||||
BSP_LCD_SelectLayer(1);
|
||||
LOG_INFO(TAG, "Display text: %s @x=%d,y=%d", text, x_pos, y_pos);
|
||||
|
||||
@@ -118,7 +122,12 @@ void lcd_display_text(const char* text, uint32_t x_pos, uint32_t y_pos, uint32_t
|
||||
BSP_LCD_DisplayStringAt(x_pos, y_pos, (uint8_t*)text, LEFT_MODE);
|
||||
}
|
||||
|
||||
void lcd_draw_raw_img(const void* p_src, uint32_t x_pos, uint32_t y_pos, uint32_t x_size, uint32_t y_size, uint32_t color_mode) {
|
||||
void lcd_draw_raw_img(const void* p_src,
|
||||
uint32_t x_pos,
|
||||
uint32_t y_pos,
|
||||
uint32_t x_size,
|
||||
uint32_t y_size,
|
||||
uint32_t color_mode) {
|
||||
LOG_INFO(TAG, "Displaying raw image: @x=%lu, @y=%lu, width=%lu, height=%lu", x_pos, y_pos, x_size, y_size);
|
||||
BSP_LCD_SelectLayer(0);
|
||||
uint32_t address = hLtdcHandler.LayerCfg[1].FBStartAdress + (((BSP_LCD_GetXSize() * y_pos) + x_pos) * (4));
|
||||
@@ -197,7 +206,7 @@ void lcd_clear_images(void) {
|
||||
BSP_LCD_Clear(0);
|
||||
}
|
||||
|
||||
void lcd_set_bg_color_layer0(uint32_t color){
|
||||
void lcd_set_bg_color_layer0(uint32_t color) {
|
||||
BSP_LCD_SelectLayer(0);
|
||||
BSP_LCD_Clear(color);
|
||||
}
|
||||
@@ -344,10 +353,10 @@ static void gif_draw_cb(GIFDRAW* pDraw) {
|
||||
}
|
||||
|
||||
// Get the color from the palette and convert it to ARGB8888
|
||||
uint8_t *p = palette + (pixel * 3);
|
||||
uint8_t* p = palette + (pixel * 3);
|
||||
uint32_t color = (0xFF << 24) | (p[0] << 16) | (p[1] << 8) | p[2];
|
||||
|
||||
// Draw the pixel
|
||||
((uint32_t *)address)[x] = color;
|
||||
((uint32_t*)address)[x] = color;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#define LOGGER_LEVEL_WARN
|
||||
#include "log.h"
|
||||
#include "llfs.h"
|
||||
#include "log.h"
|
||||
|
||||
/**
|
||||
* @brief The maximum number of files that can be opened concurrently using the POSIX API
|
||||
@@ -331,7 +331,7 @@ off_t _lseek(int file, int ptr, int dir) {
|
||||
*/
|
||||
int _fstat(int file, struct stat* st) {
|
||||
FILE* stream;
|
||||
llfs_file_t *llfs_file;
|
||||
llfs_file_t* llfs_file;
|
||||
|
||||
// Check if the file is stdin, stdout or stderr
|
||||
if (file == STDIN_FILENO || file == STDOUT_FILENO || file == STDERR_FILENO) {
|
||||
@@ -442,4 +442,3 @@ static uint8_t file_ext_cmp(const char* const filename, const char* const ext) {
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
547361
project/Core/Src/llfs_data.c
547361
project/Core/Src/llfs_data.c
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,8 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "stm32f7xx_hal.h"
|
||||
#include "log.h"
|
||||
#include "stm32f7xx_hal.h"
|
||||
|
||||
extern UART_HandleTypeDef huart1;
|
||||
|
||||
@@ -18,7 +18,7 @@ extern UART_HandleTypeDef huart1;
|
||||
* @return The current timestamp in milliseconds since boot
|
||||
*/
|
||||
|
||||
int _write(int file, char *data, int len) {
|
||||
int _write(int file, char* data, int len) {
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
switch (file) {
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
static const char *TAG = "main";
|
||||
static const char* TAG = "main";
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
@@ -149,8 +149,8 @@ int main(void) {
|
||||
// Initialize the UDP broadcast service
|
||||
|
||||
if (udp_broadcast_init(10, 255) != ERR_OK) {
|
||||
LOG_WARN(TAG,
|
||||
"error initializing udp connection, check warnings from udp_broadcast_init() or udp_broadcast_connection_init()");
|
||||
LOG_WARN(TAG, "error initializing udp connection, check warnings from udp_broadcast_init() or "
|
||||
"udp_broadcast_connection_init()");
|
||||
}
|
||||
if (udp_broadcast_set_owner_details("Joran", "Van Nieuwenhoven") != ERR_OK) {
|
||||
LOG_WARN(TAG, "error setting owner's details");
|
||||
|
||||
@@ -28,13 +28,7 @@
|
||||
#define SERVER_IP4_D 11
|
||||
#define SERVER_PORT 1883
|
||||
|
||||
typedef enum input_topic {
|
||||
set_text,
|
||||
set_text_color,
|
||||
set_color,
|
||||
set_image,
|
||||
other_topic
|
||||
} input_topic_t;
|
||||
typedef enum input_topic { set_text, set_text_color, set_color, set_image, other_topic } input_topic_t;
|
||||
|
||||
// Function prototypes
|
||||
static void mqtt_pub_request_cb(void*, err_t);
|
||||
@@ -47,7 +41,8 @@ static void mosquitto_connect(mqtt_client_t*);
|
||||
static uint32_t color_picker(char*);
|
||||
static void create_publish_string(char*, char*, size_t);
|
||||
|
||||
// Global variables used in mqtt_incoming_publish_cb and mqtt_incoming_data_cb to give an easy to use ID to the subscribed topics
|
||||
// Global variables used in mqtt_incoming_publish_cb and mqtt_incoming_data_cb to give an easy to use ID to the
|
||||
// subscribed topics
|
||||
static sFONT* font;
|
||||
static uint16_t xpos;
|
||||
static uint16_t ypos;
|
||||
@@ -80,9 +75,10 @@ static void publish_data(mqtt_client_t* client, void* arg) {
|
||||
|
||||
LOG_DEBUG(TAG, "Entering publish");
|
||||
|
||||
create_publish_string("*.bmp", pub_payload,sizeof(pub_payload));
|
||||
create_publish_string("*.bmp", pub_payload, sizeof(pub_payload));
|
||||
|
||||
err = mqtt_publish(client, "getImageList", pub_payload, strlen(pub_payload), PUBLISH_QOS, PUBLISH_RETAIN, mqtt_pub_request_cb, arg);
|
||||
err = mqtt_publish(client, "getImageList", pub_payload, strlen(pub_payload), PUBLISH_QOS, PUBLISH_RETAIN,
|
||||
mqtt_pub_request_cb, arg);
|
||||
if (err != ERR_OK) {
|
||||
LOG_DEBUG(TAG, "Publish err: %d", err);
|
||||
}
|
||||
@@ -90,7 +86,8 @@ static void publish_data(mqtt_client_t* client, void* arg) {
|
||||
pub_payload[0] = '\0';
|
||||
create_publish_string("*.gif", pub_payload, sizeof(pub_payload));
|
||||
|
||||
err = mqtt_publish(client, "getGifList", pub_payload, strlen(pub_payload), PUBLISH_QOS, PUBLISH_RETAIN, mqtt_pub_request_cb, arg);
|
||||
err = mqtt_publish(client, "getGifList", pub_payload, strlen(pub_payload), PUBLISH_QOS, PUBLISH_RETAIN,
|
||||
mqtt_pub_request_cb, arg);
|
||||
if (err != ERR_OK) {
|
||||
LOG_DEBUG(TAG, "Publish err: %d", err);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ static err_t tcp_cmd_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t
|
||||
|
||||
char* endptr;
|
||||
|
||||
|
||||
if (err == ERR_OK && p != NULL) {
|
||||
tcp_recved(pcb, p->tot_len);
|
||||
pc = (char*)p->payload;
|
||||
@@ -48,13 +47,15 @@ static err_t tcp_cmd_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t
|
||||
|
||||
if (!strncmp(tcp_buffer, "help", 4)) {
|
||||
check = 1;
|
||||
tcp_write(pcb, "help : laat lijst zien met alle commando's\r\n"
|
||||
tcp_write(pcb,
|
||||
"help : laat lijst zien met alle commando's\r\n"
|
||||
"text : geeft tekst mee die op LCD komt (uw_text)\r\n"
|
||||
"color : kleur achtergrond van scherm (255 255 255)\r\n"
|
||||
"textColor : kleur van tekst (255 255 255)\r\n"
|
||||
"listImages: laat een lijst zien van de mogelijke afbeeldingen\r\n"
|
||||
"setImage : veranderd te afbeelding (naam_afbeelding)\r\n"
|
||||
"exit : sluit de verbinding\r\n", 354, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);
|
||||
"exit : sluit de verbinding\r\n",
|
||||
354, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);
|
||||
} else if (!strncmp(tcp_buffer, "text ", 5)) {
|
||||
size_t i;
|
||||
for (i = 0; i < len - 4; i++) {
|
||||
@@ -64,7 +65,6 @@ static err_t tcp_cmd_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t
|
||||
lcd_clear_text();
|
||||
lcd_display_text(text, 10, 10, result_txt, result_bg, LCD_FONT24);
|
||||
|
||||
|
||||
check = 1;
|
||||
} else if (!strncmp(tcp_buffer, "color", 5)) {
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
@@ -96,7 +96,8 @@ static err_t tcp_cmd_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t
|
||||
number_of_files = llfs_file_list(file_list, number_of_files, NULL);
|
||||
|
||||
for (size_t i = 0; i < number_of_files; i++) {
|
||||
tcp_write(pcb, file_list[i].name, strlen(file_list[i].name), TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);
|
||||
tcp_write(pcb, file_list[i].name, strlen(file_list[i].name),
|
||||
TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);
|
||||
tcp_write(pcb, "\r\n", 2, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);
|
||||
}
|
||||
} else {
|
||||
@@ -117,7 +118,7 @@ static err_t tcp_cmd_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t
|
||||
|
||||
number_of_files = llfs_file_count();
|
||||
|
||||
if(number_of_files > 0) {
|
||||
if (number_of_files > 0) {
|
||||
llfs_file_t file_list[number_of_files];
|
||||
|
||||
number_of_files = llfs_file_list(file_list, number_of_files, NULL);
|
||||
@@ -154,7 +155,8 @@ static err_t tcp_cmd_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t
|
||||
}
|
||||
|
||||
if (!check && (strncmp(tcp_buffer, "\r\n", 2) != 0)) {
|
||||
tcp_write(pcb, "Onbestaand commando: help voor lijst van commando's\r\n", 53, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);
|
||||
tcp_write(pcb, "Onbestaand commando: help voor lijst van commando's\r\n", 53,
|
||||
TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);
|
||||
}
|
||||
|
||||
pbuf_free(p);
|
||||
@@ -184,10 +186,12 @@ static err_t tcp_cmd_accept(void* arg, struct tcp_pcb* pcb, err_t err) {
|
||||
tcp_recv(pcb, tcp_cmd_recv);
|
||||
tcp_err(pcb, NULL);
|
||||
tcp_poll(pcb, NULL, 4);
|
||||
tcp_write(pcb, " Welcom bij de TCP CMD Interface\r\n"
|
||||
tcp_write(pcb,
|
||||
" Welcom bij de TCP CMD Interface\r\n"
|
||||
"(Typ help voor een lijst van de commando's! X om te sluiten)\r\n"
|
||||
"============================================================\r\n"
|
||||
"User: ", 168, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);
|
||||
"User: ",
|
||||
168, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);
|
||||
tcp_sent(pcb, NULL);
|
||||
return ERR_OK;
|
||||
}
|
||||
@@ -200,4 +204,3 @@ void tcp_cmd_init(void) {
|
||||
tcp_pcb = tcp_listen(tcp_pcb);
|
||||
tcp_accept(tcp_pcb, tcp_cmd_accept);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,10 @@ static void* tftp_open(const char* fname, const char* mode, uint8_t write);
|
||||
static void tftp_close(void* handle);
|
||||
static int tftp_read(void* handle, void* buf, int bytes);
|
||||
static int tftp_write(void* handle, struct pbuf* p);
|
||||
static struct tftp_context tftpContext_s = {.open = tftp_open, .close = tftp_close, .read = tftp_read, .write = tftp_write};
|
||||
static struct tftp_context tftpContext_s = {.open = tftp_open,
|
||||
.close = tftp_close,
|
||||
.read = tftp_read,
|
||||
.write = tftp_write};
|
||||
/**
|
||||
* @brief tftp custom file functions to set the offset and read the data
|
||||
* @param[in,out] handle Custom file handles
|
||||
|
||||
@@ -14,7 +14,6 @@ static void wbe_decoding_url(const char* encoded, char* decoded);
|
||||
static uint32_t wbe_color_value(const char* rgb);
|
||||
|
||||
void wbe_init(void) {
|
||||
|
||||
httpd_init();
|
||||
LOG_DEBUG("WBE", "Initialize webserver");
|
||||
|
||||
@@ -25,15 +24,13 @@ void wbe_init(void) {
|
||||
}
|
||||
|
||||
int fs_open_custom(struct fs_file* file, const char* name) {
|
||||
|
||||
// Variables
|
||||
llfs_file_t *wanted_file = llfs_file_open(name + 1);
|
||||
llfs_file_t* wanted_file = llfs_file_open(name + 1);
|
||||
size_t buffer_len = 0;
|
||||
static char image_stringbuffer[STR_MAX] = "";
|
||||
|
||||
// The wanted file was found in the filesystem
|
||||
if (wanted_file != NULL) {
|
||||
|
||||
// Debug info
|
||||
LOG_DEBUG("WBE", "The file : %s was found", wanted_file->name);
|
||||
|
||||
@@ -53,7 +50,6 @@ int fs_open_custom(struct fs_file* file, const char* name) {
|
||||
* information string that contains the names of the available images.
|
||||
*/
|
||||
if (strncmp(name, "/images.info", strlen("/images.info")) == 0) {
|
||||
|
||||
// Create the information string for the images in the filesystem
|
||||
buffer_len = wbe_get_images(image_stringbuffer, llfs_file_count());
|
||||
|
||||
@@ -70,7 +66,6 @@ int fs_open_custom(struct fs_file* file, const char* name) {
|
||||
|
||||
// Endpoint when client wants to send information to the backend
|
||||
if (strncmp(name, "/cgi", 3) == 0) {
|
||||
|
||||
// Give the original index.html back to the client
|
||||
wanted_file = llfs_file_open("index.html");
|
||||
|
||||
@@ -84,14 +79,12 @@ int fs_open_custom(struct fs_file* file, const char* name) {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fs_close_custom(struct fs_file* file) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,7 +96,6 @@ void fs_close_custom(struct fs_file* file) {
|
||||
* @param[in] file_count_fs, the number of files in the filesystem
|
||||
*/
|
||||
static size_t wbe_get_images(char* images_string, size_t file_count_fs) {
|
||||
|
||||
// Allocate space for the files
|
||||
llfs_file_t file_list[file_count_fs];
|
||||
|
||||
@@ -137,21 +129,17 @@ static size_t wbe_get_images(char* images_string, size_t file_count_fs) {
|
||||
* @param[in] cnt, the number of files
|
||||
*/
|
||||
static inline void wbe_build_infostring(const llfs_file_t* file_list, char* info_string, const size_t cnt) {
|
||||
|
||||
// Add the filenames to the info string
|
||||
for (size_t i = 0; i < cnt; ++i) {
|
||||
|
||||
strncat(info_string, file_list[i].name, strlen(file_list[i].name));
|
||||
strncat(info_string, "|", 2);
|
||||
}
|
||||
|
||||
//Remove last seperator '|'
|
||||
// Remove last seperator '|'
|
||||
info_string[strlen(info_string) - 1] = '\0';
|
||||
|
||||
}
|
||||
|
||||
void httpd_cgi_handler(struct fs_file* file, const char* uri, int num_parm, char** pc_param, char** pc_value) {
|
||||
|
||||
// Variables
|
||||
uint32_t vktxt = LCD_GREEN;
|
||||
uint32_t vka = LCD_BLACK;
|
||||
@@ -163,9 +151,7 @@ void httpd_cgi_handler(struct fs_file* file, const char* uri, int num_parm, char
|
||||
char s_vka[CLR_MAX]; // Color of the background. (also in #RGB)
|
||||
|
||||
if (strcmp("/cgi", uri) == 0) {
|
||||
|
||||
for (size_t i = 0; i < num_parm; ++i) {
|
||||
|
||||
// The given sentence
|
||||
if (strcmp("vtxt", pc_param[i]) == 0) {
|
||||
wbe_decoding_url(pc_value[i], vtxt);
|
||||
@@ -189,7 +175,6 @@ void httpd_cgi_handler(struct fs_file* file, const char* uri, int num_parm, char
|
||||
if (s_vka != NULL) {
|
||||
vka = wbe_color_value(s_vka);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Name of the image
|
||||
@@ -203,9 +188,7 @@ void httpd_cgi_handler(struct fs_file* file, const char* uri, int num_parm, char
|
||||
|
||||
// Display on LCD
|
||||
wbe_display(vtxt, vktxt, vka, vfo);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,18 +202,15 @@ void httpd_cgi_handler(struct fs_file* file, const char* uri, int num_parm, char
|
||||
* @param[in] decoded, string that will contain the decoded URL.
|
||||
*/
|
||||
static void wbe_decoding_url(const char* encoded, char* decoded) {
|
||||
|
||||
// Variables
|
||||
char *endptr;
|
||||
char* endptr;
|
||||
size_t decoded_index = 0;
|
||||
size_t encoded_length = strlen(encoded);
|
||||
uint32_t hex_val;
|
||||
|
||||
for (size_t i = 0; i < encoded_length; ++i) {
|
||||
|
||||
// If we encounter a %xx, decode it to ascii
|
||||
if ((encoded[i] == '%') && (i + 2 < encoded_length)) {
|
||||
|
||||
// Decode %xx
|
||||
hex_val = (uint32_t)strtoul(&encoded[i + 1], &endptr, 16);
|
||||
|
||||
@@ -246,25 +226,21 @@ static void wbe_decoding_url(const char* encoded, char* decoded) {
|
||||
|
||||
// If we encounter a +, add a space character
|
||||
} else if (encoded[i] == '+') {
|
||||
|
||||
decoded[decoded_index++] = ' ';
|
||||
|
||||
// If no % or +, just put what stands in 'encoded'
|
||||
} else {
|
||||
|
||||
decoded[decoded_index++] = encoded[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Finish the string
|
||||
decoded[decoded_index] = '\0';
|
||||
|
||||
}
|
||||
|
||||
static uint32_t wbe_color_value(const char* rgb) {
|
||||
|
||||
// Variables
|
||||
char *endptr;
|
||||
char* endptr;
|
||||
uint32_t color = LCD_BLACK;
|
||||
char argb[11] = "0xff";
|
||||
|
||||
@@ -284,10 +260,9 @@ static uint32_t wbe_color_value(const char* rgb) {
|
||||
}
|
||||
|
||||
void wbe_display(const char* txt, const uint32_t txt_color, const uint32_t bg_color, const char* image) {
|
||||
|
||||
// Variables
|
||||
lcd_gif_t *gif;
|
||||
const char *extension;
|
||||
lcd_gif_t* gif;
|
||||
const char* extension;
|
||||
|
||||
// clear the screen
|
||||
lcd_clear_text();
|
||||
|
||||
13
tests/mocs.c
13
tests/mocs.c
@@ -12,7 +12,12 @@ int tftp_init(struct tftp_context* context) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lcd_display_text(const char* text, uint16_t x_pos, uint16_t y_pos, uint32_t color, uint32_t bg_color, sFONT* font) {
|
||||
void lcd_display_text(const char* text,
|
||||
uint16_t x_pos,
|
||||
uint16_t y_pos,
|
||||
uint32_t color,
|
||||
uint32_t bg_color,
|
||||
sFONT* font) {
|
||||
UNUSED(color);
|
||||
UNUSED(bg_color);
|
||||
UNUSED(font);
|
||||
@@ -54,19 +59,19 @@ struct tcp_pcb* tcp_new(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err_t tcp_bind(void *pcb, void *ipaddr, uint16_t port) {
|
||||
err_t tcp_bind(void* pcb, void* ipaddr, uint16_t port) {
|
||||
UNUSED(pcb);
|
||||
UNUSED(ipaddr);
|
||||
UNUSED(port);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
struct tcp_pcb* tcp_listen(void *pcb) {
|
||||
struct tcp_pcb* tcp_listen(void* pcb) {
|
||||
UNUSED(pcb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void tcp_accept(void *pcb, tcp_accept_fn arg) {
|
||||
void tcp_accept(void* pcb, tcp_accept_fn arg) {
|
||||
UNUSED(pcb);
|
||||
UNUSED(arg);
|
||||
}
|
||||
|
||||
77
tests/mocs.h
77
tests/mocs.h
@@ -4,8 +4,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef UNUSED
|
||||
#define UNUSED(x) (void)(x)
|
||||
@@ -16,51 +16,51 @@ extern "C" {
|
||||
typedef int8_t err_t;
|
||||
/** Definitions for error constants. */
|
||||
typedef enum {
|
||||
/** No error, everything OK. */
|
||||
/** No error, everything OK. */
|
||||
ERR_OK = 0,
|
||||
/** Out of memory error. */
|
||||
/** Out of memory error. */
|
||||
ERR_MEM = -1,
|
||||
/** Buffer error. */
|
||||
/** Buffer error. */
|
||||
ERR_BUF = -2,
|
||||
/** Timeout. */
|
||||
/** Timeout. */
|
||||
ERR_TIMEOUT = -3,
|
||||
/** Routing problem. */
|
||||
/** Routing problem. */
|
||||
ERR_RTE = -4,
|
||||
/** Operation in progress */
|
||||
/** Operation in progress */
|
||||
ERR_INPROGRESS = -5,
|
||||
/** Illegal value. */
|
||||
/** Illegal value. */
|
||||
ERR_VAL = -6,
|
||||
/** Operation would block. */
|
||||
/** Operation would block. */
|
||||
ERR_WOULDBLOCK = -7,
|
||||
/** Address in use. */
|
||||
/** Address in use. */
|
||||
ERR_USE = -8,
|
||||
/** Already connecting. */
|
||||
/** Already connecting. */
|
||||
ERR_ALREADY = -9,
|
||||
/** Conn already established.*/
|
||||
/** Conn already established.*/
|
||||
ERR_ISCONN = -10,
|
||||
/** Not connected. */
|
||||
/** Not connected. */
|
||||
ERR_CONN = -11,
|
||||
/** Low-level netif error */
|
||||
/** Low-level netif error */
|
||||
ERR_IF = -12,
|
||||
|
||||
/** Connection aborted. */
|
||||
/** Connection aborted. */
|
||||
ERR_ABRT = -13,
|
||||
/** Connection reset. */
|
||||
/** Connection reset. */
|
||||
ERR_RST = -14,
|
||||
/** Connection closed. */
|
||||
/** Connection closed. */
|
||||
ERR_CLSD = -15,
|
||||
/** Illegal argument. */
|
||||
/** Illegal argument. */
|
||||
ERR_ARG = -16
|
||||
} err_enum_t;
|
||||
|
||||
struct pbuf {
|
||||
struct pbuf *next;
|
||||
void *payload;
|
||||
struct pbuf* next;
|
||||
void* payload;
|
||||
uint16_t tot_len;
|
||||
uint16_t len;
|
||||
uint8_t type_internal;
|
||||
uint8_t flags;
|
||||
//LWIP_PBUF_REF_T ref;
|
||||
// LWIP_PBUF_REF_T ref;
|
||||
|
||||
uint8_t if_idx;
|
||||
};
|
||||
@@ -86,14 +86,13 @@ typedef void sFONT;
|
||||
#define TCP_PRIO_MAX 127
|
||||
#define IP_ADDR_ANY 0
|
||||
|
||||
typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb,
|
||||
struct pbuf *p, err_t err);
|
||||
typedef err_t (*tcp_recv_fn)(void* arg, struct tcp_pcb* tpcb, struct pbuf* p, err_t err);
|
||||
|
||||
typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err);
|
||||
typedef err_t (*tcp_accept_fn)(void* arg, struct tcp_pcb* newpcb, err_t err);
|
||||
|
||||
uint32_t logger_get_timestamp(void);
|
||||
|
||||
void lcd_display_text(const char* text, uint16_t x_pos, uint16_t y_pos, uint32_t color, uint32_t bg_color, sFONT *font);
|
||||
void lcd_display_text(const char* text, uint16_t x_pos, uint16_t y_pos, uint32_t color, uint32_t bg_color, sFONT* font);
|
||||
void lcd_draw_img_from_fs(char* filename, uint32_t x_pos, uint32_t y_pos);
|
||||
void lcd_draw_gif_from_fs(char* filename, uint32_t x_pos, uint32_t y_pos);
|
||||
void lcd_draw_bmp_img(uint8_t* bmp_buff, uint32_t x_pos, uint32_t y_pos);
|
||||
@@ -103,23 +102,23 @@ void lcd_clear_images(void);
|
||||
void lcd_clear_text(void);
|
||||
|
||||
struct tcp_pcb* tcp_new(void);
|
||||
err_t tcp_bind(void *pcb, void *ipaddr, uint16_t port);
|
||||
struct tcp_pcb* tcp_listen(void *pcb);
|
||||
void tcp_accept(void *pcb, tcp_accept_fn arg);
|
||||
void tcp_arg(void *pcb, void *arg);
|
||||
void tcp_sent(void *pcb, void *arg);
|
||||
void tcp_recv(void *pcb, tcp_recv_fn arg);
|
||||
void tcp_setprio(void *pcb, uint8_t prio);
|
||||
void tcp_err(void *pcb, void* err);
|
||||
void tcp_poll(void *pcb, void* poll, uint8_t interval);
|
||||
void tcp_close(void *pcb);
|
||||
err_t tcp_bind(void* pcb, void* ipaddr, uint16_t port);
|
||||
struct tcp_pcb* tcp_listen(void* pcb);
|
||||
void tcp_accept(void* pcb, tcp_accept_fn arg);
|
||||
void tcp_arg(void* pcb, void* arg);
|
||||
void tcp_sent(void* pcb, void* arg);
|
||||
void tcp_recv(void* pcb, tcp_recv_fn arg);
|
||||
void tcp_setprio(void* pcb, uint8_t prio);
|
||||
void tcp_err(void* pcb, void* err);
|
||||
void tcp_poll(void* pcb, void* poll, uint8_t interval);
|
||||
void tcp_close(void* pcb);
|
||||
|
||||
void tcp_write(void *pcb, const char *data, size_t len, uint8_t apiflags);
|
||||
void tcp_output(void *pcb);
|
||||
void tcp_recved(void *pcb, uint16_t len);
|
||||
void tcp_write(void* pcb, const char* data, size_t len, uint8_t apiflags);
|
||||
void tcp_output(void* pcb);
|
||||
void tcp_recved(void* pcb, uint16_t len);
|
||||
void pbuf_free(struct pbuf* p);
|
||||
|
||||
size_t tcp_sndbuf(void *pcb);
|
||||
size_t tcp_sndbuf(void* pcb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,35 +1,23 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mocs.h"
|
||||
#include "tftp.h"
|
||||
|
||||
tftp_custom_file_t file = {
|
||||
.data = (char*)"1234567890",
|
||||
.len = 11,
|
||||
.name = (char*)"test.txt",
|
||||
.offset = 0
|
||||
};
|
||||
tftp_custom_file_t write_file = {
|
||||
.data = NULL,
|
||||
.len = 0,
|
||||
.name = (char*)"test.txt",
|
||||
.offset = 0
|
||||
};
|
||||
tftp_custom_file_t file = {.data = (char*)"1234567890", .len = 11, .name = (char*)"test.txt", .offset = 0};
|
||||
tftp_custom_file_t write_file = {.data = NULL, .len = 0, .name = (char*)"test.txt", .offset = 0};
|
||||
|
||||
TEST(TFTP, custom_fseek)
|
||||
{
|
||||
TEST(TFTP, custom_fseek) {
|
||||
tftp_custom_fseek(&file, 5, SEEK_SET);
|
||||
EXPECT_EQ(file.offset, 5);
|
||||
tftp_custom_fseek(&file, 5, SEEK_CUR);
|
||||
EXPECT_EQ(file.offset, 10);
|
||||
}
|
||||
|
||||
TEST(TFTP, custom_fread)
|
||||
{
|
||||
TEST(TFTP, custom_fread) {
|
||||
char buf[11];
|
||||
tftp_custom_fseek(&file, 0, SEEK_SET);
|
||||
size_t bytes = tftp_custom_fread(buf, 11, &file);
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "mocs.h"
|
||||
|
||||
struct tftp_context {
|
||||
|
||||
Reference in New Issue
Block a user