writer.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package flate
  2. import (
  3. "io"
  4. "github.com/andybalholm/brotli/matchfinder"
  5. )
  6. // NewWriter returns a new matchfinder.Writer that compresses data at the given level,
  7. // in flate encoding. Levels 1–9 are available; levels outside this range will
  8. // be replaced with the closest level available.
  9. func NewWriter(w io.Writer, level int) *matchfinder.Writer {
  10. return newWriter(w, level, NewEncoder())
  11. }
  12. // NewGZIPWriter returns a new matchfinder.Writer that compresses data at the given
  13. // level, in gzip encoding. Levels 1–9 are available; levels outside this range
  14. // will be replaced by the closest level available.
  15. func NewGZIPWriter(w io.Writer, level int) *matchfinder.Writer {
  16. return newWriter(w, level, NewGZIPEncoder())
  17. }
  18. func newWriter(w io.Writer, level int, e matchfinder.Encoder) *matchfinder.Writer {
  19. var mf matchfinder.MatchFinder
  20. if level < 2 {
  21. mf = &matchfinder.ZFast{MaxDistance: 1 << 15}
  22. } else if level == 2 {
  23. mf = &matchfinder.ZDFast{MaxDistance: 1 << 15}
  24. } else if level == 3 {
  25. mf = &matchfinder.ZM{MaxDistance: 1 << 15}
  26. } else if level == 4 {
  27. mf = &matchfinder.Trio{MaxDistance: 1 << 15}
  28. } else if level < 8 {
  29. chainLen := 32
  30. switch level {
  31. case 5:
  32. chainLen = 8
  33. case 6:
  34. chainLen = 16
  35. }
  36. mf = &matchfinder.M4{
  37. MaxDistance: 1 << 15,
  38. ChainLength: chainLen,
  39. HashLen: 5,
  40. DistanceBitCost: 66,
  41. }
  42. } else {
  43. chainLen := 32
  44. hashLen := 5
  45. if level == 8 {
  46. chainLen = 4
  47. }
  48. mf = &matchfinder.Pathfinder{
  49. MaxDistance: 1 << 15,
  50. ChainLength: chainLen,
  51. HashLen: hashLen,
  52. }
  53. }
  54. return &matchfinder.Writer{
  55. Dest: w,
  56. MatchFinder: mf,
  57. Encoder: e,
  58. BlockSize: 1 << 16,
  59. }
  60. }