@@ -159,7 +159,6 @@ static float pollIntervalMultiplier = 1.0;
159159static uint32_t printerPollInterval = defaultPrinterPollInterval;
160160
161161static struct ThumbnailData thumbnailData;
162- static struct Thumbnail thumbnail;
163162
164163enum ThumbnailState {
165164 Init = 0 ,
@@ -172,6 +171,7 @@ enum ThumbnailState {
172171static struct ThumbnailContext {
173172 String<MaxFilnameLength> filename;
174173 enum ThumbnailState state;
174+ struct Thumbnail thumbnail;
175175 int16_t parseErr;
176176 int32_t err;
177177 uint32_t size;
@@ -182,15 +182,15 @@ static struct ThumbnailContext {
182182 {
183183 filename.Clear ();
184184 state = ThumbnailState::Init;
185+ ThumbnailInit (thumbnail);
185186 parseErr = 0 ;
186187 err = 0 ;
187188 size = 0 ;
188189 offset = 0 ;
189190 next = 0 ;
190-
191191 };
192192
193- } thumbnailContext ;
193+ } thumbnailCurrent, thumbnailNew ;
194194
195195static const ColourScheme *colours = &colourSchemes[0 ];
196196
@@ -1004,13 +1004,15 @@ static bool GetBool(const char s[], bool &rslt)
10041004static void StartReceivedMessage ();
10051005static void EndReceivedMessage ();
10061006static void ProcessReceivedValue (StringRef id, const char data[], const size_t indices[]);
1007+ static void ProcessArrayElementEnd (const char id[], const size_t index);
10071008static void ProcessArrayEnd (const char id[], const size_t indices[]);
10081009static void ParserErrorEncountered (int currentState, const char *, int errors);
10091010
10101011static struct SerialIo ::SerialIoCbs serial_cbs = {
10111012 .StartReceivedMessage = StartReceivedMessage,
10121013 .EndReceivedMessage = EndReceivedMessage,
10131014 .ProcessReceivedValue = ProcessReceivedValue,
1015+ .ProcessArrayElementEnd = ProcessArrayElementEnd,
10141016 .ProcessArrayEnd = ProcessArrayEnd,
10151017 .ParserErrorEncountered = ParserErrorEncountered
10161018};
@@ -1022,10 +1024,10 @@ static void StartReceivedMessage()
10221024 FileManager::BeginNewMessage ();
10231025 currentAlert.Reset ();
10241026
1025- if (thumbnailContext.state == ThumbnailState::Init)
1027+ thumbnailNew.Init ();
1028+ if (thumbnailCurrent.state == ThumbnailState::Init)
10261029 {
1027- thumbnailContext.Init ();
1028- ThumbnailInit (thumbnail);
1030+ thumbnailCurrent.Init ();
10291031 memset (&thumbnailData, 0 , sizeof (thumbnailData));
10301032 }
10311033}
@@ -1061,57 +1063,57 @@ static void EndReceivedMessage()
10611063 lastAlertSeq = currentAlert.seq ;
10621064 }
10631065
1064- if (thumbnailContext .parseErr != 0 || thumbnailContext .err != 0 )
1066+ if (thumbnailCurrent .parseErr != 0 || thumbnailCurrent .err != 0 )
10651067 {
10661068 dbg (" thumbnail parseErr %d err %d.\n " ,
1067- thumbnailContext .parseErr ,
1068- thumbnailContext .err );
1069- thumbnailContext .state = ThumbnailState::Init;
1069+ thumbnailCurrent .parseErr ,
1070+ thumbnailCurrent .err );
1071+ thumbnailCurrent .state = ThumbnailState::Init;
10701072 }
1071- #if 0 // && DEBUG
1072- if (thumbnail.imageFormat != Thumbnail::ImageFormat::Invalid)
1073+ #if DEBUG
1074+ if (thumbnailCurrent. thumbnail .imageFormat != Thumbnail::ImageFormat::Invalid)
10731075 {
10741076 dbg (" filename %s offset %d size %d format %d width %d height %d\n " ,
1075- thumbnailContext .filename.c_str(),
1076- thumbnailContext .offset, thumbnailContext .size,
1077- thumbnail.imageFormat,
1078- thumbnail.width, thumbnail.height);
1077+ thumbnailCurrent .filename .c_str (),
1078+ thumbnailCurrent .offset , thumbnailCurrent .size ,
1079+ thumbnailCurrent. thumbnail .imageFormat ,
1080+ thumbnailCurrent. thumbnail .width , thumbnailCurrent. thumbnail .height );
10791081 }
10801082#endif
10811083 int ret;
10821084
1083- switch (thumbnailContext .state ) {
1085+ switch (thumbnailCurrent .state ) {
10841086 case ThumbnailState::Init:
10851087 case ThumbnailState::DataRequest:
10861088 case ThumbnailState::DataWait:
10871089 break ;
10881090 case ThumbnailState::Header:
1089- if (!ThumbnailIsValid (thumbnail))
1091+ if (!ThumbnailIsValid (thumbnailCurrent. thumbnail ))
10901092 {
10911093 dbg (" thumbnail meta invalid.\n " );
10921094 break ;
10931095 }
1094- thumbnailContext .state = ThumbnailState::DataRequest;
1096+ thumbnailCurrent .state = ThumbnailState::DataRequest;
10951097 break ;
10961098 case ThumbnailState::Data:
10971099 if (!ThumbnailDataIsValid (thumbnailData))
10981100 {
10991101 dbg (" thumbnail meta or data invalid.\n " );
1100- thumbnailContext .state = ThumbnailState::Init;
1102+ thumbnailCurrent .state = ThumbnailState::Init;
11011103 break ;
11021104 }
1103- if ((ret = ThumbnailDecodeChunk (thumbnail, thumbnailData, UI::UpdateFileThumbnailChunk)) < 0 )
1105+ if ((ret = ThumbnailDecodeChunk (thumbnailCurrent. thumbnail , thumbnailData, UI::UpdateFileThumbnailChunk)) < 0 )
11041106 {
11051107 dbg (" failed to decode thumbnail chunk %d.\n " , ret);
1106- thumbnailContext .state = ThumbnailState::Init;
1108+ thumbnailCurrent .state = ThumbnailState::Init;
11071109 break ;
11081110 }
1109- if (thumbnailContext .next == 0 )
1111+ if (thumbnailCurrent .next == 0 )
11101112 {
1111- thumbnailContext .state = ThumbnailState::Init;
1113+ thumbnailCurrent .state = ThumbnailState::Init;
11121114 } else
11131115 {
1114- thumbnailContext .state = ThumbnailState::DataRequest;
1116+ thumbnailCurrent .state = ThumbnailState::DataRequest;
11151117 }
11161118 break ;
11171119 }
@@ -1976,7 +1978,7 @@ static void ProcessReceivedValue(StringRef id, const char data[], const size_t i
19761978 }
19771979 break ;
19781980 case rcvM36Filename:
1979- thumbnailContext .filename .copy (data);
1981+ thumbnailNew .filename .copy (data);
19801982 break ;
19811983
19821984 case rcvM36GeneratedBy:
@@ -2029,76 +2031,76 @@ static void ProcessReceivedValue(StringRef id, const char data[], const size_t i
20292031 break ;
20302032
20312033 case rcvM36ThumbnailsFormat:
2032- thumbnail.imageFormat = Thumbnail::ImageFormat::Invalid;
2034+ thumbnailNew. thumbnail .imageFormat = Thumbnail::ImageFormat::Invalid;
20332035 if (strcmp (data, " qoi" ) == 0 )
20342036 {
2035- thumbnail.imageFormat = Thumbnail::ImageFormat::Qoi;
2037+ thumbnailNew. thumbnail .imageFormat = Thumbnail::ImageFormat::Qoi;
20362038
2037- thumbnailContext .state = ThumbnailState::Header;
2039+ thumbnailNew .state = ThumbnailState::Header;
20382040 }
20392041 break ;
20402042 case rcvM36ThumbnailsHeight:
20412043 uint32_t height;
20422044 if (GetUnsignedInteger (data, height))
20432045 {
2044- thumbnail.height = height;
2046+ thumbnailNew. thumbnail .height = height;
20452047 }
20462048 break ;
20472049 case rcvM36ThumbnailsOffset:
20482050 uint32_t offset;
20492051 if (GetUnsignedInteger (data, offset))
20502052 {
2051- thumbnailContext .next = offset;
2053+ thumbnailNew .next = offset;
20522054 dbg (" receive initial offset %d.\n " , offset);
20532055 }
20542056 break ;
20552057 case rcvM36ThumbnailsSize:
20562058 uint32_t size;
20572059 if (GetUnsignedInteger (data, size))
20582060 {
2059- thumbnailContext .size = size;
2061+ thumbnailNew .size = size;
20602062 }
20612063 break ;
20622064 case rcvM36ThumbnailsWidth:
20632065 uint32_t width;
20642066 if (GetUnsignedInteger (data, width))
20652067 {
2066- thumbnail.width = width;
2068+ thumbnailNew. thumbnail .width = width;
20672069 }
20682070 break ;
20692071
20702072 case rcvM361ThumbnailData:
20712073 thumbnailData.size = std::min (strlen (data), sizeof (thumbnailData.buffer ));
20722074 memcpy (thumbnailData.buffer , data, thumbnailData.size );
2073- thumbnailContext .state = ThumbnailState::Data;
2075+ thumbnailCurrent .state = ThumbnailState::Data;
20742076 break ;
20752077 case rcvM361ThumbnailErr:
2076- if (!GetInteger (data, thumbnailContext .err ))
2078+ if (!GetInteger (data, thumbnailCurrent .err ))
20772079 {
2078- thumbnailContext .parseErr = -1 ;
2080+ thumbnailCurrent .parseErr = -1 ;
20792081 }
20802082 break ;
20812083 case rcvM361ThumbnailFilename:
2082- if (!thumbnailContext .filename .Equals (data))
2084+ if (!thumbnailCurrent .filename .Equals (data))
20832085 {
2084- thumbnailContext .parseErr = -2 ;
2086+ thumbnailCurrent .parseErr = -2 ;
20852087 }
20862088 break ;
20872089 case rcvM361ThumbnailNext:
2088- if (!GetUnsignedInteger (data, thumbnailContext .next ))
2090+ if (!GetUnsignedInteger (data, thumbnailCurrent .next ))
20892091 {
2090- thumbnailContext .parseErr = -3 ;
2092+ thumbnailCurrent .parseErr = -3 ;
20912093 break ;
20922094 }
2093- dbg (" receive next offset %d.\n " , thumbnailContext .next );
2095+ dbg (" receive next offset %d.\n " , thumbnailCurrent .next );
20942096 break ;
20952097 case rcvM361ThumbnailOffset:
2096- if (!GetUnsignedInteger (data, thumbnailContext .offset ))
2098+ if (!GetUnsignedInteger (data, thumbnailNew .offset ))
20972099 {
2098- thumbnailContext .parseErr = -4 ;
2100+ thumbnailCurrent .parseErr = -4 ;
20992101 break ;
21002102 }
2101- dbg (" receive current offset %d.\n " , thumbnailContext .offset );
2103+ dbg (" receive current offset %d.\n " , thumbnailCurrent .offset );
21022104 break ;
21032105
21042106 case rcvControlCommand:
@@ -2132,6 +2134,26 @@ static void ProcessReceivedValue(StringRef id, const char data[], const size_t i
21322134 }
21332135}
21342136
2137+ static void ProcessArrayElementEnd (const char id[], const size_t index)
2138+ {
2139+ // dbg("id %s index %lu\r\n", id, index);
2140+
2141+ // check if new thumbnail fits better
2142+ if (strcmp (id, " thumbnails^" ) == 0 &&
2143+ ThumbnailIsValid (thumbnailNew.thumbnail ) &&
2144+ thumbnailCurrent.thumbnail .height < thumbnailNew.thumbnail .height &&
2145+ thumbnailNew.thumbnail .height <= fpThumbnail->GetHeight () &&
2146+ thumbnailCurrent.thumbnail .width < thumbnailNew.thumbnail .width &&
2147+ thumbnailNew.thumbnail .width <= fpThumbnail->GetWidth ())
2148+ {
2149+ dbg (" setting new thumbnail %d/%d\r\n " , fpThumbnail->GetWidth (), fpThumbnail->GetWidth ());
2150+ thumbnailCurrent = thumbnailNew;
2151+ thumbnailNew.Init ();
2152+ }
2153+
2154+ return ;
2155+ }
2156+
21352157// Public function called when the serial I/O module finishes receiving an array of values
21362158static void ProcessArrayEnd (const char id[], const size_t indices[])
21372159{
@@ -2598,11 +2620,11 @@ int main(void)
25982620#if DEBUG
25992621 static enum ThumbnailState stateOld = ThumbnailState::Init;
26002622
2601- if (stateOld != thumbnailContext .state )
2623+ if (stateOld != thumbnailCurrent .state )
26022624 {
26032625 dbg (" thumbnail state %d -> %d.\n " ,
2604- stateOld, thumbnailContext .state );
2605- stateOld = thumbnailContext .state ;
2626+ stateOld, thumbnailCurrent .state );
2627+ stateOld = thumbnailCurrent .state ;
26062628 }
26072629#endif
26082630
@@ -2617,15 +2639,15 @@ int main(void)
26172639 else if (lastResponseTime >= lastPollTime &&
26182640 (now > lastPollTime + printerPollInterval ||
26192641 !initialized ||
2620- thumbnailContext .state == ThumbnailState::DataRequest))
2642+ thumbnailCurrent .state == ThumbnailState::DataRequest))
26212643 {
2622- if (thumbnailContext .state == ThumbnailState::DataRequest)
2644+ if (thumbnailCurrent .state == ThumbnailState::DataRequest)
26232645 {
26242646 SerialIo::Sendf (" M36.1 P\" %s\" S%d\n " ,
2625- thumbnailContext .filename .c_str (),
2626- thumbnailContext .next );
2647+ thumbnailCurrent .filename .c_str (),
2648+ thumbnailCurrent .next );
26272649 lastPollTime = SystemTick::GetTickCount ();
2628- thumbnailContext .state = ThumbnailState::DataWait;
2650+ thumbnailCurrent .state = ThumbnailState::DataWait;
26292651 }
26302652 else
26312653 {
0 commit comments