There look to be a few different approaches, mostly variants on the same general theme. I'll attempt to summarise.
Resampling
In terms of resampling methods, resampling is recommended (-r <method> in gdalwarp), as the original image is aligned to longitude (true north) whereas the processed images are aligned to UTM grid, and are thus rotated. Cubic resampling seems to give the best results. Bilinear results in more blurring. Lanczos is almost identical to cubic. Near (default) is objectively sharper than cubic, but leaves noticeable artifacts due to the rotation.
Approach 1 - JPEG compression
While the original question asked for reduction in colors, and the base image is essentially paletted, (lossy) JPEG compression actually does a decent job of both file size reduction (74MB->12MB) and quality. It also has the advantage of being achievable in one step.
gdalwarp -r cubic -dstalpha -co compress=JPEG -co tiled=YES -cutline "9030-4S SPRINGWOOD.geojson" -crop_to_cutline "9030-4S SPRINGWOOD.pdf" "9030-4S SPRINGWOOD.tif"
Approach 2 - rgb2pct.py & gdalwarp
Due to the transparency requirement, paletting is a 3-step process
- First pass with gdalwarp strips the collar off (to avoid processing colors in the collar) and applies resampling
- Then we reduce the colors to 254 (or smaller if desired) using rgb2pct
- Finally, a second pass with gdalwarp sets the NoData value to 255
The file size reduction is from 74MB->9MB. The color fidelity is worse than the JPEG version, but larger blocks of color are "cleaner" due to having fewer artifacts.
gdalwarp -r cubic -co compress=LZW -cutline "9030-4S SPRINGWOOD.geojson" -crop_to_cutline "9030-4S SPRINGWOOD.pdf" "9030-4S SPRINGWOOD_1.tif"
rgb2pct -n 254 "9030-4S SPRINGWOOD_1.tif" "9030-4S SPRINGWOOD_2.tif"
gdalwarp -co tiled=YES -co compress=LZW -dstnodata 255 -cutline "9030-4S SPRINGWOOD.geojson" -crop_to_cutline "9030-4S SPRINGWOOD_2.tif" "9030-4S SPRINGWOOD.tif"
Results for both approaches are fairly good at 100% zoom.
Other approaches
I also looked at a 2-step process just using rgb2pct.py & gdalwarp in that order. This fails due to resampling/rotating a paletted image - which gdalwarp warns about! Just don't...
In terms of improving quality, at the cost of size, there is also the option of upsizing in the first step. With a pixel size of 2 (-tr 2 2), which is about 2.1x, the resulting images are 31MB for approach 1 (JPG) and 34MB for approach 2 (paletting). The comparative comments about color fidelity/artifacts stand.
Interestingly, using WEBP compression (-co compress=WEBP) in approach 1 gave a 4.5MB image at default resolution, and 11MB at a pixel size of 2. Quality appears fairly to both the JPEG and palette approach, at less than 50% size of either. The only downside is that WEBP compression is not as widely supported - if you need to take the files out of GDAL (eg Photoshop can't handle it). If you can live with that, this might be as good an option as any:
gdalwarp -r cubic -dstalpha -co compress=WEBP -co tiled=YES -cutline "9030-4S SPRINGWOOD.geojson" -crop_to_cutline "9030-4S SPRINGWOOD.pdf" "9030-4S SPRINGWOOD.tif"
The compression level can be specified (75% is default). Lossless WEBP can also be specified (18MB at default resolution).